Compare commits

...

2762 Commits

Author SHA1 Message Date
J-Jamet
d560c3e8de Merge branch 'release/2.10.1' 2021-05-10 07:24:42 +02:00
J-Jamet
4f8e8e6669 Upgrade version code for deployment 2021-05-10 06:05:22 +02:00
J-Jamet
7cdc2e0915 Fix custom data item #986 2021-05-10 06:03:12 +02:00
J-Jamet
74b236b317 Fix class cast exception #986 2021-05-09 22:29:46 +02:00
J-Jamet
89ffeaf03b Fix crash with parcelable cast 2021-05-08 12:52:56 +02:00
J-Jamet
8b779a0fca Upgrade version 2021-05-07 17:45:12 +02:00
J-Jamet
4b71dc8445 Merge tag '2.10.0' into develop
2.10.0
2021-05-07 17:36:12 +02:00
J-Jamet
780875d5f2 Merge branch 'release/2.10.0' 2021-05-07 17:36:06 +02:00
J-Jamet
7356d4b0e2 Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-05-07 17:08:31 +02:00
J-Jamet
654dea6b7e Manage new database format 4.1 #956 2021-05-07 17:06:41 +02:00
J-Jamet
1204374637 Merge branch 'feature/Database_4.1' into develop 2021-05-07 17:03:12 +02:00
J-Jamet
880fde2148 Change version to 2.10.0 2021-05-07 17:02:57 +02:00
J-Jamet
d776d76100 Fix null context with advanced unlocking 2021-05-07 17:01:54 +02:00
J-Jamet
2a7af826a8 Update CHANGELOG 2021-05-07 10:41:24 +02:00
J-Jamet
9d2fd53073 Fix lock 2021-05-07 08:31:05 +02:00
J-Jamet
edc5985a7e Fix show button consistency #980 2021-05-05 11:01:53 +02:00
C. Rüdinger
96fc79103b Translated using Weblate (German)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-05-04 00:18:35 +02:00
VfBFan
76879f3a73 Translated using Weblate (German)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-05-04 00:18:34 +02:00
J-Jamet
328629fe88 Fix writing previous parent group in 4.0 2021-05-03 15:41:39 +02:00
ssantos
9754535055 Translated using Weblate (Portuguese)
Currently translated at 85.9% (454 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt/
2021-05-02 22:32:18 +02:00
J. Lavoie
26f701d890 Translated using Weblate (Italian)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-05-02 22:32:17 +02:00
VfBFan
f3df8024e6 Translated using Weblate (German)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-05-02 22:32:17 +02:00
J-Jamet
bc9fdfc7a4 Fix header custom data condition 2021-05-01 18:24:11 +02:00
J-Jamet
e1e37989e4 Fix custom icon condition 2021-05-01 18:06:47 +02:00
J-Jamet
dc67cb1807 Set previous parent group during a move or a deletion 2021-05-01 17:48:48 +02:00
J-Jamet
2e8a2457bc Show custom icon name #976 2021-05-01 14:36:11 +02:00
J-Jamet
6d4398c6fd Remove custom data last modification time recognition in Entry and Group 2021-05-01 13:03:44 +02:00
J-Jamet
9f67ad872d Remove contains parent group as condition to 4.1 migration 2021-05-01 12:58:28 +02:00
J-Jamet
aba396f274 Fix parcelable UUID 2021-04-30 21:57:59 +02:00
J-Jamet
4315f34398 Add previous parent group as condition to migrate to 4.1 2021-04-30 21:46:01 +02:00
J-Jamet
47b456e1ee Custom data refactoring 2021-04-30 21:24:37 +02:00
J-Jamet
529810b2dc Fix tags and implements previous parent group 2021-04-30 21:03:29 +02:00
J-Jamet
6f67b8e788 Fix tags string length representation 2021-04-30 20:10:49 +02:00
J-Jamet
a9c9d12444 Better write XML nodes implementation 2021-04-30 20:03:59 +02:00
J-Jamet
f8428cec61 Better date XML implementation and DeletedObject as parcelable 2021-04-30 19:58:21 +02:00
J-Jamet
ac46bce807 Fix custom data writing 2021-04-30 19:39:57 +02:00
J-Jamet
23e899042d Add custom data objects 2021-04-30 19:23:56 +02:00
J-Jamet
80c4a3c06d Fix custom icon parser 2021-04-30 17:19:39 +02:00
Hosted Weblate
d2a31601ba Merge branch 'origin/develop' into Weblate. 2021-04-30 17:04:40 +02:00
J-Jamet
7ddb4f3486 Fix saving custom icons 2021-04-30 14:57:48 +02:00
J-Jamet
e56da87e0e Add last modification to custom icons 2021-04-30 14:11:48 +02:00
J-Jamet
2e4ebecf67 Add name to custom icons #956 2021-04-30 12:49:36 +02:00
J-Jamet
1b4ccaed91 Manage quality check parameter #956 2021-04-30 12:08:21 +02:00
J-Jamet
1e2d41c7fb Merge branch 'develop' into feature/Database_4.1 2021-04-30 11:41:38 +02:00
J-Jamet
1b2ead054a Upgrade to version 3.0.0 2021-04-30 11:37:32 +02:00
J-Jamet
468c1b95b7 Fix CHANGELOG version 2021-04-30 11:29:58 +02:00
J-Jamet
60d8eff71f Merge tag '2.9.20' into develop
2.9.20
2021-04-30 11:28:16 +02:00
J-Jamet
8baae8b801 Merge branch 'release/2.9.20' 2021-04-30 11:28:03 +02:00
J-Jamet
9f16f26347 skip unchanged fastlane elements to deploy 2021-04-29 22:23:51 +02:00
J-Jamet
69b4cacab4 Upgrade version code to deploy beta 2021-04-29 22:23:13 +02:00
J-Jamet
b74b5040b1 Better timeout setting integration #974 2021-04-29 21:57:25 +02:00
J-Jamet
a28decc854 Fix timeout with 0s #974 2021-04-29 21:45:39 +02:00
J-Jamet
cb59cef1b8 Remove unused dependency 2021-04-29 12:37:19 +02:00
J-Jamet
d9b600466c Rollback ignore accents #945 2021-04-29 12:09:53 +02:00
J-Jamet
4edf2f8cd1 Upgrade CHANGELOG 2021-04-29 11:04:33 +02:00
J-Jamet
c60dfdf0d7 Fix search during a node action #972 2021-04-29 10:58:16 +02:00
J-Jamet
006afc6841 Fix search with non-latin chars #971 2021-04-29 10:44:12 +02:00
J-Jamet
f70879581d Change version to fix bugs 2021-04-29 10:35:34 +02:00
J-Jamet
7a2d2b0376 Add database version 4.1 2021-04-28 16:26:11 +02:00
J-Jamet
b5368fa239 First commit to allow tags in groups 2021-04-28 13:16:09 +02:00
J-Jamet
db1d71af9f Upgrade version 2021-04-28 12:04:22 +02:00
J-Jamet
6b03ef35a6 Merge tag '2.9.19' into develop
2.9.19
2021-04-28 10:01:22 +02:00
J-Jamet
2afd02d86f Merge branch 'release/2.9.19' 2021-04-28 10:01:14 +02:00
Oymate
b32c00f455 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 5.3% (28 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bn_BD/
2021-04-27 15:32:17 +02:00
Milo Ivir
fbe9fb41ed Translated using Weblate (Croatian)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-04-27 15:32:17 +02:00
gnu-ewm
cc0a7f7d76 Translated using Weblate (Polish)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-04-27 15:32:17 +02:00
Y. Sakamoto
db33fc60b9 Translated using Weblate (Japanese)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-04-27 15:32:16 +02:00
VfBFan
6feaee4f86 Translated using Weblate (German)
Currently translated at 99.8% (527 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-27 15:32:16 +02:00
C. Rüdinger
1a27a31a32 Translated using Weblate (German)
Currently translated at 99.8% (527 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-27 15:32:15 +02:00
zeritti
5b611e71d5 Translated using Weblate (Czech)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-04-27 15:32:15 +02:00
J-Jamet
6de88bfe11 Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-04-27 10:40:30 +02:00
J-Jamet
6d7236249f Fix field reference in search preview #964 2021-04-27 10:36:36 +02:00
J-Jamet
69fbaba8a6 Fix field reference engine 2021-04-26 21:46:45 +02:00
J-Jamet
6d88737505 Better field reference engine implementation 2021-04-26 16:28:56 +02:00
C. Rüdinger
9869cfc736 Translated using Weblate (German)
Currently translated at 96.9% (512 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-26 13:40:04 +02:00
VfBFan
8505326a68 Translated using Weblate (German)
Currently translated at 97.1% (513 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-26 13:32:54 +02:00
C. Rüdinger
3a4af88384 Translated using Weblate (German)
Currently translated at 97.1% (513 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-26 13:32:53 +02:00
solokot
5b2e7d0f70 Translated using Weblate (Russian)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-04-25 22:57:45 +02:00
J-Jamet
ddeea6bee3 Remove field reference in search 2021-04-25 21:28:23 +02:00
J-Jamet
0cfe3a7634 Check flatten 2021-04-25 16:52:37 +02:00
J-Jamet
727463e4d1 Better field reference engine implementation 2021-04-25 16:48:37 +02:00
J-Jamet
d42abfdc56 Remove unused search code 2021-04-25 15:08:36 +02:00
J-Jamet
e01ea1df4c Fix OTP token generation #967 2021-04-23 21:43:38 +02:00
J-Jamet
078bfac5f5 Upgrade CHANGELOG 2021-04-23 15:33:57 +02:00
J-Jamet
111b07b9e6 Better temp advanced unlocking implementation 2021-04-23 15:30:00 +02:00
J-Jamet
dfbc89addc Fix database notification #965 2021-04-23 14:24:23 +02:00
J-Jamet
bf44da9a14 Update version and CHANGELOG 2021-04-23 14:24:23 +02:00
J-Jamet
d75d13965b Faster accent replacement method implementation #964 2021-04-23 14:24:23 +02:00
Oğuz Ersen
8aedebdc94 Translated using Weblate (Turkish)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-04-22 14:32:18 +02:00
Eric
9388c4bb0d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-04-22 14:32:17 +02:00
Ihor Hordiichuk
77d4f601af Translated using Weblate (Ukrainian)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-04-22 14:32:16 +02:00
solokot
7fae590848 Translated using Weblate (Russian)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-04-22 14:32:16 +02:00
Stephan Paternotte
bc41558a26 Translated using Weblate (Dutch)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2021-04-22 14:32:16 +02:00
Oliver Cervera
f6651face4 Translated using Weblate (Italian)
Currently translated at 99.8% (527 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-04-22 14:32:16 +02:00
Kunzisoft
345f00f7f2 Translated using Weblate (French)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-04-22 14:32:15 +02:00
Retrial
e876d02118 Translated using Weblate (Greek)
Currently translated at 100.0% (528 of 528 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-04-22 14:32:15 +02:00
J-Jamet
5b7018f71b Merge tag '2.9.18' into develop
2.9.18
2021-04-20 20:11:11 +02:00
J-Jamet
f45b3fc50a Merge branch 'release/2.9.18' 2021-04-20 20:11:05 +02:00
J-Jamet
01196be30d Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-04-20 11:57:48 +02:00
J-Jamet
0a2999bffb Change Pro description 2021-04-20 11:46:55 +02:00
J-Jamet
8f097096e7 Update CHANGELOG 2021-04-20 11:36:52 +02:00
J-Jamet
cd97fc046a Fix theme in Libre version 2021-04-20 11:35:14 +02:00
Hosted Weblate
eeb10f31a6 Merge branch 'origin/develop' into Weblate. 2021-04-20 11:34:10 +02:00
J-Jamet
9df5e116e8 Change to version 2.9.18 to deploy bugs fixes 2021-04-20 11:01:26 +02:00
J-Jamet
1228a03d39 searchInEntry as instance method 2021-04-19 18:34:44 +02:00
J-Jamet
a5e1b3096e Merge branch 'feature/Search_Fields' into develop #962 2021-04-19 18:28:17 +02:00
J-Jamet
b41ae67128 Update CHANGELOG 2021-04-19 18:28:07 +02:00
Sebastian
ddfbe20125 Translated using Weblate (Danish)
Currently translated at 98.1% (517 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2021-04-19 18:27:10 +02:00
J-Jamet
0bfe9291dd Move UUID util 2021-04-19 18:26:40 +02:00
J-Jamet
622b2e1edc Fix search in field reference 2021-04-19 18:24:30 +02:00
J-Jamet
4a40719534 Search refactoring 2021-04-19 17:54:16 +02:00
J-Jamet
384993d363 Remove diacritical marks in search string #945 2021-04-19 15:24:06 +02:00
J-Jamet
01b7d28154 Update CHANGELOG 2021-04-19 13:28:48 +02:00
J-Jamet
d7c4f5577f Merge branch 'feature/Move_Group' into develop #658 2021-04-19 13:27:02 +02:00
J-Jamet
a69d23ca64 Update CHANGELOG 2021-04-19 13:26:41 +02:00
J-Jamet
e2f8b7a6e3 Fix move group message 2021-04-19 13:16:30 +02:00
J-Jamet
171a0b012f Fix remove recycle bin 2021-04-19 12:59:02 +02:00
J-Jamet
5c04b15433 Check group name to prevent manual backup group creation 2021-04-19 11:45:53 +02:00
J-Jamet
6397feffff Better search backup group implementation 2021-04-19 11:11:07 +02:00
J-Jamet
e73b9b7f1c Move group and fix backup in KDB 2021-04-18 23:52:59 +02:00
WaldiS
0d82e40c67 Translated using Weblate (Polish)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-04-17 23:27:06 +02:00
Stephan Paternotte
b75d6d02fa Translated using Weblate (Dutch)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2021-04-17 23:27:06 +02:00
J. Lavoie
76d4542716 Translated using Weblate (French)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-04-17 23:27:05 +02:00
J. Lavoie
87955de849 Translated using Weblate (German)
Currently translated at 95.8% (505 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-17 23:27:04 +02:00
J-Jamet
6df60cf5da Upgrade biometric lib to 1.1.0 2021-04-17 12:19:14 +02:00
Oliver Cervera
3c23a314f0 Translated using Weblate (Italian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-04-16 10:27:10 +02:00
Oğuz Ersen
8fda6b04a4 Translated using Weblate (Turkish)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-04-15 01:57:14 +02:00
Eric
9fa98e6b76 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-04-15 01:57:14 +02:00
Ihor Hordiichuk
deb685f39b Translated using Weblate (Ukrainian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-04-15 01:57:13 +02:00
Kunzisoft
d7851d3a18 Translated using Weblate (French)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-04-15 01:57:13 +02:00
Retrial
44946fc54a Translated using Weblate (Greek)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-04-15 01:57:12 +02:00
Hosted Weblate
a033d10adc Merge branch 'origin/develop' into Weblate. 2021-04-14 10:49:40 +02:00
André Marcelo Alvarenga
5a3e599fe0 Translated using Weblate (Portuguese (Brazil))
Currently translated at 81.2% (428 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2021-04-14 10:49:39 +02:00
Oliver Cervera
a9f645f389 Translated using Weblate (Italian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-04-14 10:49:39 +02:00
J-Jamet
d662f0903a Workaround to autofill recognition #960 2021-04-13 12:48:33 +02:00
J-Jamet
beaa947eb7 Upgrade version 2021-04-13 11:41:03 +02:00
random r
48006b64d6 Translated using Weblate (Italian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-04-13 11:34:57 +02:00
J-Jamet
8f195ba66f Merge tag '2.9.17' into develop
2.9.17
2021-04-13 09:11:12 +02:00
J-Jamet
123288e745 Merge branch 'release/2.9.17' 2021-04-13 09:11:05 +02:00
Milo Ivir
5866e95d49 Translated using Weblate (Croatian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-04-10 22:27:10 +02:00
WaldiS
e79f395424 Translated using Weblate (Polish)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-04-10 22:27:09 +02:00
HARADA Hiroyuki
999ca87fec Translated using Weblate (Japanese)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-04-10 22:27:09 +02:00
Oliver Cervera
1217266d88 Translated using Weblate (Italian)
Currently translated at 98.1% (517 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-04-10 22:27:08 +02:00
Sebastian
bb262198be Translated using Weblate (Danish)
Currently translated at 93.1% (491 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2021-04-10 22:27:08 +02:00
J-Jamet
11aae77caf Update CHANGELOG 2021-04-10 20:56:25 +02:00
J-Jamet
8212cede6e Merge branch 'feature/Duration_Preference' into develop #579 2021-04-10 20:53:35 +02:00
J-Jamet
a3c51884f4 Fix timeout strings 2021-04-10 20:53:24 +02:00
J-Jamet
b8890aca7f Better notification timer implementation 2021-04-10 20:30:48 +02:00
J-Jamet
014b0cce14 Add duration preference with number picker 2021-04-10 19:29:19 +02:00
Oğuz Ersen
6d860c5cb7 Translated using Weblate (Turkish)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-04-08 20:55:17 +02:00
Eric
d8be832858 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-04-08 20:55:17 +02:00
Ihor Hordiichuk
afcb9fcf41 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-04-08 20:55:16 +02:00
solokot
3c7ae0aaf0 Translated using Weblate (Russian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-04-08 20:55:15 +02:00
Retrial
6b7f93dbfe Translated using Weblate (Greek)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-04-08 20:55:15 +02:00
J-Jamet
c40b255022 Check properties 2021-04-08 16:40:01 +02:00
J-Jamet
1742d265f3 Better stylish implementation 2021-04-08 16:26:14 +02:00
Nikita Epifanov
3240e0bcae Translated using Weblate (Russian)
Currently translated at 100.0% (527 of 527 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-04-08 13:59:42 +02:00
J-Jamet
ff185f6505 Upgrade version and CHANGELOG 2021-04-08 12:58:39 +02:00
J-Jamet
346b517c9d Force twofish padding compatibility #955 2021-04-08 12:55:23 +02:00
Hosted Weblate
80f00aba0a Merge branch 'origin/develop' into Weblate. 2021-04-08 12:07:37 +02:00
J-Jamet
949905f6e2 Merge branch 'feature/Import_Export_App_Properties' into develop 2021-04-08 12:06:52 +02:00
J-Jamet
b9e26fecfd Export and import properties 2021-04-08 11:45:23 +02:00
solokot
232682f4a8 Translated using Weblate (Russian)
Currently translated at 100.0% (516 of 516 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-04-08 08:27:03 +02:00
C. Rüdinger
de3b690d60 Translated using Weblate (German)
Currently translated at 97.0% (501 of 516 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-04-08 08:27:03 +02:00
J-Jamet
de69a78a98 First commit to import and export app properties 2021-04-07 16:13:40 +02:00
J-Jamet
1c341c34a3 Merge tag '2.9.16' into develop
2.9.16
2021-04-07 09:53:13 +02:00
J-Jamet
33beb57e9d Merge branch 'release/2.9.16' 2021-04-07 09:53:07 +02:00
J-Jamet
66eeadca0b Upgrade version code 2021-04-06 17:39:27 +02:00
J-Jamet
a10d1c98a8 Fix KDB parcelable 2021-04-06 17:32:40 +02:00
J-Jamet
59ead4986f Move Parent Parcelable 2021-04-06 15:05:11 +02:00
J-Jamet
09f6c18189 Small changes 2021-04-06 15:02:24 +02:00
Timur Seber
a5cd6d5ac0 Translated using Weblate (Tatar)
Currently translated at 8.5% (44 of 516 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tt/
2021-04-06 06:26:46 +02:00
J-Jamet
0f3ad7c8b1 Fix select custom icon 2021-04-05 19:06:54 +02:00
J-Jamet
0487dea7fc Fix null cache directory 2021-04-05 11:32:07 +02:00
Timur Seber
a6803bf0e3 Added translation using Weblate (Tatar) 2021-04-05 05:18:42 +02:00
J-Jamet
8cac1ee284 Merge branch 'feature/ExternalFileHelper' into develop 2021-04-05 00:06:03 +02:00
J-Jamet
196620e1bd Remove unused methods 2021-04-05 00:04:25 +02:00
J-Jamet
43d6c76873 Refactor open document click listener 2021-04-04 23:44:25 +02:00
J-Jamet
b864c39a0d Fix add database workflow in some devices 2021-04-04 23:13:24 +02:00
J-Jamet
818b975111 Change default type verification to create document 2021-04-04 09:56:09 +02:00
J-Jamet
d5fbc8393f Change file creation methods 2021-04-03 19:40:55 +02:00
Oliver Cervera
df9a71a63d Translated using Weblate (Italian)
Currently translated at 100.0% (516 of 516 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-04-02 12:26:46 +02:00
J-Jamet
7b5e9d2344 Better parcelable entry CREATOR implementation #948 2021-04-02 09:37:18 +02:00
J-Jamet
7fc2d95886 Fix document file retrievment 2021-04-01 10:52:00 +02:00
J-Jamet
78d3b369bb Move Parcelable inheritance 2021-03-31 19:39:07 +02:00
J-Jamet
bb3620680b Upgrade version 2021-03-31 17:58:49 +02:00
J-Jamet
d4a45655ca Merge tag '2.9.15' into develop
2.9.15
2021-03-29 22:01:52 +02:00
J-Jamet
c9c739fd52 Merge branch 'release/2.9.15' 2021-03-29 22:01:44 +02:00
J-Jamet
2b359cc592 Remove unused code 2021-03-29 21:00:10 +02:00
J-Jamet
151b7a323d Upgrade version code 2021-03-29 13:58:30 +02:00
J-Jamet
1063dc2b63 Add TODO SparseArray 2021-03-29 13:57:30 +02:00
J-Jamet
f9f59a6eb1 Replace serializable UUID by Parcelable UUID 2021-03-29 13:49:49 +02:00
J-Jamet
73156cc337 Fix clipboard null exception 2021-03-29 13:09:22 +02:00
J-Jamet
7d53607f49 Capture exception when launching cipher action 2021-03-29 13:07:55 +02:00
J-Jamet
7539945465 Capture exception when error when launching database action 2021-03-29 13:01:31 +02:00
J-Jamet
51df8e7bb1 Try to fix rare bug 2021-03-29 12:52:12 +02:00
J-Jamet
17029ce67c Fix bad padding exception 2021-03-29 12:42:53 +02:00
J-Jamet
8cedc313cf Upgrade version code 2021-03-27 10:54:26 +01:00
J-Jamet
5afe3acac1 Remove unused string 2021-03-27 10:23:38 +01:00
J-Jamet
9887b58b71 Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-03-27 10:18:55 +01:00
J-Jamet
ec8363ba6a Merge branch 'develop' into release/2.9.15 2021-03-27 10:13:53 +01:00
J-Jamet
fcfb71f13b Fix disable Memory Usage setting with AES #941 2021-03-27 10:12:29 +01:00
J-Jamet
3a12e431ff Update CHANGELOG 2021-03-27 05:49:29 +01:00
J-Jamet
bc4ed8e123 Update CHANGELOG 2021-03-27 05:44:09 +01:00
J-Jamet
445e9540a5 Merge branch 'feature/Dynamic_Memory_And_Encrypt_Module' into develop 2021-03-26 20:06:12 +01:00
Joan Jaume Oliver
bbc2a2a9dd Translated using Weblate (Spanish)
Currently translated at 98.6% (515 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2021-03-26 19:29:42 +01:00
Joan Jaume Oliver
5117bc78b6 Translated using Weblate (Catalan)
Currently translated at 48.2% (252 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ca/
2021-03-26 19:29:41 +01:00
J-Jamet
10bf149a07 Rename final-key to aes and remove unused string resource 2021-03-26 19:27:19 +01:00
J-Jamet
0a976bd012 Rollback AES & Argon2 as native C lib 2021-03-26 19:09:30 +01:00
J-Jamet
df31c43e59 Rename crypto module 2021-03-26 16:53:09 +01:00
J-Jamet
c5d30b9b23 Native AES call refactoring 2021-03-26 16:10:55 +01:00
J-Jamet
2e18beff27 Native AES call refactoring 2021-03-26 16:06:28 +01:00
J-Jamet
25e0cec2cc Fix CPU usage with RecyclerView (Weird that the recyclerview uses so much CPU continuously, probably an Android view bug) 2021-03-26 13:51:51 +01:00
J-Jamet
16cc4c5c97 Better activity_password layout implementation 2021-03-26 13:45:08 +01:00
J-Jamet
e5cfb6b7eb Rollback AES thread implementation 2021-03-25 14:59:39 +01:00
J-Jamet
a882ba07e9 Fix create database education 2021-03-25 12:42:40 +01:00
J-Jamet
801f3f99aa Fix app timeout and decrease keyboard timeout #934 2021-03-25 12:36:56 +01:00
J-Jamet
2338b9b57d Fix SHA-512 2021-03-25 12:23:31 +01:00
J-Jamet
8ba396c693 Remove pro guard files 2021-03-25 12:16:04 +01:00
J-Jamet
1164022765 Upgrade gradle and kotlin 2021-03-25 11:29:24 +01:00
J-Jamet
b0c5519da5 Upgrade build tool version to 30.0.3 in icon packs 2021-03-25 11:27:25 +01:00
J-Jamet
f5073238d8 Better KDBX version implementation (new code) 2021-03-25 11:07:51 +01:00
J-Jamet
3ffa89bfaf Revert "Better KDBX version implementation"
This reverts commit 9fae343668.
2021-03-25 10:57:19 +01:00
Reza Almanda
26d8b2fa22 Translated using Weblate (Indonesian)
Currently translated at 74.3% (388 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2021-03-25 01:29:42 +01:00
J-Jamet
6b17502694 Better hash implementation 2021-03-24 22:17:15 +01:00
J-Jamet
a69d57a4f4 Move classes in right places 2021-03-24 21:29:58 +01:00
J-Jamet
430bc6150f Remove manual cipher input stream 2021-03-24 21:09:44 +01:00
J-Jamet
b888615e0d Fix small variable name 2021-03-24 21:04:12 +01:00
J-Jamet
9fae343668 Better KDBX version implementation 2021-03-24 21:00:41 +01:00
J-Jamet
db467889b0 Encapsulate SHA-256 2021-03-24 20:30:13 +01:00
J-Jamet
153b8d1f37 Better getHmacKey64 method 2021-03-24 20:05:40 +01:00
J-Jamet
87858762d4 Remove NullOutputStream 2021-03-24 19:50:56 +01:00
J-Jamet
50d3282a65 Refactor HMAC methods 2021-03-24 19:15:45 +01:00
J-Jamet
aee0500b38 Merge branch 'develop' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-24 18:25:28 +01:00
J-Jamet
f2ef6eb94e Decrease default clipboard time #934 2021-03-24 18:25:10 +01:00
J-Jamet
151a5a7e73 Select Twofish with KDB database 2021-03-24 18:08:11 +01:00
J-Jamet
6a088c58de Fix Twofish algorithm 2021-03-24 17:50:08 +01:00
J-Jamet
23e7bf9f89 Update test 2021-03-24 16:13:28 +01:00
J-Jamet
59f24206ad Merge branch 'feature/Dynamic_Memory' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-24 16:02:23 +01:00
J-Jamet
e45ef019c0 Small encapsulation 2021-03-24 14:57:41 +01:00
J-Jamet
2830d3c8fa Small encapsulation 2021-03-24 14:21:19 +01:00
J-Jamet
088816dfab Change Unsigned Long Implementation 2021-03-24 14:05:45 +01:00
J-Jamet
453a29b81c Rename .java to .kt 2021-03-24 14:05:44 +01:00
J-Jamet
e5cb160aa4 Remove Little Endian output stream 2021-03-24 12:22:34 +01:00
J-Jamet
844588a0d4 Remove Little Endian input stream 2021-03-24 11:55:41 +01:00
J-Jamet
cfcfd47705 Fix test 2021-03-24 11:53:36 +01:00
J-Jamet
f416c0ec7d Merge branch 'feature/Dynamic_Memory' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-24 11:32:17 +01:00
J-Jamet
78f707c07c Simpler method 2021-03-24 11:29:15 +01:00
J-Jamet
d28a59a2fe Throw exception if bad header 2021-03-24 11:20:30 +01:00
J-Jamet
edf3525a3f Remove unecessary TODO 2021-03-24 11:17:52 +01:00
random r
2b7fe35305 Translated using Weblate (Italian)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-03-23 21:30:04 +01:00
Vít Šindlář
d5819ea4d0 Translated using Weblate (Czech)
Currently translated at 99.6% (520 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-03-23 21:30:04 +01:00
J-Jamet
1099126def Merge branch 'feature/Dynamic_Memory' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-23 21:24:54 +01:00
J-Jamet
4ba3a797e3 Simpler dataExists 2021-03-23 21:24:30 +01:00
J-Jamet
51b9bb88e5 Merge branch 'feature/Dynamic_Memory' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-23 21:06:04 +01:00
J-Jamet
fa376148bd Move CustomIconPool in the right package 2021-03-23 21:05:48 +01:00
J-Jamet
452b9677da Merge branch 'feature/Dynamic_Memory' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-23 21:00:40 +01:00
J-Jamet
02a779f9a2 Fix binary save 2021-03-23 21:00:23 +01:00
J-Jamet
ea60645247 Merge branch 'feature/Encrypt_Module' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-23 20:25:49 +01:00
J-Jamet
b444a13285 Fix small warnings 2021-03-23 20:24:53 +01:00
J-Jamet
0c6b2a13eb Merge branch 'feature/Encrypt_Module' into feature/Dynamic_Memory_And_Encrypt_Module 2021-03-23 20:23:19 +01:00
J-Jamet
e10bdc1169 Fix clear 2021-03-23 20:02:39 +01:00
J-Jamet
7512cffca3 Code refactoring 2021-03-23 20:00:56 +01:00
J-Jamet
203440e9b8 Better cache management 2021-03-23 19:44:14 +01:00
J-Jamet
145030e854 Refactoring Binary cache 2021-03-23 17:44:07 +01:00
J-Jamet
2b81dfb100 Refactor KeyBinaryByte 2021-03-23 14:57:56 +01:00
J-Jamet
c96ace5281 Add binary byte as an encrypted element of the entire app 2021-03-23 14:45:26 +01:00
J-Jamet
520c6b60be First commit to allocate dynamic memory 2021-03-23 13:07:49 +01:00
J-Jamet
492382d552 Upgrade max binary bytes 2021-03-23 10:57:45 +01:00
J-Jamet
7ca55dd531 Fix themes 2021-03-23 10:38:06 +01:00
J-Jamet
ce4ba73fc4 Replace version by 2.9.15 2021-03-23 09:59:20 +01:00
J-Jamet
5622d92cbb Better native AES KDF method 2021-03-22 22:13:16 +01:00
J-Jamet
8de1c5fd36 Remove unused variables 2021-03-22 21:26:50 +01:00
J-Jamet
6c84fea8dc Update AES and SHA libs 2021-03-22 20:55:27 +01:00
J-Jamet
0b94070086 Simpler AES KDF implementation 2021-03-22 20:36:44 +01:00
J-Jamet
2f209182f5 Replace Argon2 lib 2021-03-22 15:41:57 +01:00
J-Jamet
d7bc572f3e Rename .java to .kt 2021-03-22 14:47:50 +01:00
J-Jamet
4985b49194 Refactor AES tests 2021-03-22 14:46:32 +01:00
J-Jamet
a792df2021 Create timers to calculate Database opening 2021-03-22 12:56:20 +01:00
J-Jamet
a42ec74723 Small refactoring 2021-03-22 11:04:17 +01:00
J-Jamet
de3dbe3b36 Better exception 2021-03-22 10:37:06 +01:00
J-Jamet
874fdb7da0 Refactor KDB cipher and better tests 2021-03-22 10:33:32 +01:00
J-Jamet
3bf0de3888 Refactor ciphers 2021-03-21 16:02:56 +01:00
J-Jamet
d4020c5e0f Better inner random stream implementation 2021-03-21 11:02:52 +01:00
J-Jamet
6175fc00ad Rename .java to .kt 2021-03-21 11:02:52 +01:00
J-Jamet
76e996f429 Remove unused stream 2021-03-21 10:22:05 +01:00
J-Jamet
fd222b73ce Fix unit tests 2021-03-21 10:20:24 +01:00
J-Jamet
a8cc0b1edf Change ObjectNameResource dependencies 2021-03-21 10:06:26 +01:00
J-Jamet
ea2f3545a6 Create encrypt module 2021-03-20 17:35:08 +01:00
Hosted Weblate
0cf136712a Merge branch 'origin/develop' into Weblate. 2021-03-20 14:07:16 +01:00
Milo Ivir
34a453873a Translated using Weblate (Croatian)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-03-20 14:07:16 +01:00
Kunzisoft
0acac3b096 Translated using Weblate (French)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-03-20 14:07:04 +01:00
J-Jamet
37141410e0 Upgrade to version 3.0.0 2021-03-20 12:03:56 +01:00
J-Jamet
69b0e276e3 Merge tag '2.9.14' into develop
2.9.14
2021-03-20 11:42:44 +01:00
J-Jamet
5872376f50 Merge branch 'release/2.9.14' 2021-03-20 11:42:33 +01:00
J-Jamet
075f72d9f6 Update version code 2021-03-18 15:48:58 +01:00
J-Jamet
4441ec1b14 Add small comments 2021-03-18 15:07:38 +01:00
J-Jamet
0735cc1a54 Condition to choose BinaryByte instead of BinaryFile 2021-03-18 14:58:56 +01:00
J-Jamet
dea2ad6904 Compress methods for byte array 2021-03-18 14:25:29 +01:00
J-Jamet
0f0b6b4a8a Better method to put binary 2021-03-18 13:37:33 +01:00
J-Jamet
174e562dcb Add BinaryByte and BinaryFile 2021-03-18 13:20:35 +01:00
J-Jamet
f080750545 Rename BinaryFile by BinaryData 2021-03-18 11:42:28 +01:00
J-Jamet
621415fe51 Replace BinaryFile length method 2021-03-18 11:40:01 +01:00
J-Jamet
428c2818a5 Upgrade version code 2021-03-17 22:17:37 +01:00
J-Jamet
5aa1c70999 Better binary hash implementation 2021-03-17 22:17:14 +01:00
J-Jamet
3508f47842 Externalize binary in custom icon 2021-03-17 15:31:12 +01:00
J-Jamet
62d4993e6d Better loaded cipher key implementation to prevent bad database file is key is not accessible 2021-03-17 13:56:18 +01:00
Oymate
ede6070e43 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 4.2% (22 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bn_BD/
2021-03-17 08:18:07 +01:00
jan madsen
a61b1d4337 Translated using Weblate (Danish)
Currently translated at 93.8% (490 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2021-03-17 08:18:06 +01:00
J-Jamet
631d946dcf Upgrade version code 2021-03-15 20:23:27 +01:00
J-Jamet
8945334f37 Fix reloading issue 2021-03-15 20:09:31 +01:00
J-Jamet
af2df11a56 Check binary length #924 2021-03-15 18:47:36 +01:00
J-Jamet
6dc0c42b1e Fix database save with bad binary #924 2021-03-15 18:44:53 +01:00
J-Jamet
0328293746 Upgrade version code to 61 2021-03-15 17:31:52 +01:00
J-Jamet
ad406947cf Check data in custom icon 2021-03-15 17:30:44 +01:00
J-Jamet
6bb4c1171f Better database stream exception caught 2021-03-15 17:02:13 +01:00
WaldiS
0f8c71a9df Translated using Weblate (Polish)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-03-14 13:02:53 +01:00
J-Jamet
faa39190fc Icon list optimization 2021-03-13 14:05:44 +01:00
J-Jamet
7c0b925c96 Rename BinaryStreamManager to BinaryDatabaseManager 2021-03-13 13:46:32 +01:00
J-Jamet
1b8c453fd0 Allow IconImage to have null custom icon 2021-03-13 13:06:40 +01:00
J-Jamet
8cc8f595bd upgrade version code 2021-03-13 12:26:10 +01:00
gnu-ewm
cb0b6e010d Translated using Weblate (Polish)
Currently translated at 99.8% (521 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-03-12 21:02:54 +01:00
Hisikawa Mizuki
23dc7be1ab Translated using Weblate (Japanese)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-03-12 21:02:54 +01:00
Oliver Cervera
4b14ad07d2 Translated using Weblate (Italian)
Currently translated at 99.8% (521 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-03-12 21:02:54 +01:00
J-Jamet
9a5a8ae23a Downgrade material lib to 1.1.0 2021-03-12 14:00:10 +01:00
J-Jamet
02b27e235c Upgrade version code to upload a new beta version 2021-03-12 13:59:00 +01:00
Oğuz Ersen
8a4bf7896f Translated using Weblate (Turkish)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-03-11 17:14:10 +01:00
Allan Nordhøy
208ea29643 Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.6% (400 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2021-03-11 17:14:09 +01:00
Eric
7c52ec731a Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-03-11 17:14:09 +01:00
Ihor Hordiichuk
c6ee38e435 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-03-11 17:14:08 +01:00
solokot
65253cc5b9 Translated using Weblate (Russian)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-03-11 17:14:08 +01:00
Stephan Paternotte
d1a1a23cbc Translated using Weblate (Dutch)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2021-03-11 17:14:08 +01:00
HARADA Hiroyuki
e8bb3a5ba7 Translated using Weblate (Japanese)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-03-11 17:14:07 +01:00
Retrial
22b8f82770 Translated using Weblate (Greek)
Currently translated at 100.0% (522 of 522 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-03-11 17:14:07 +01:00
J-Jamet
5874c5b9cb Resize image stream dynamically to show image preview #919 2021-03-11 16:02:15 +01:00
J-Jamet
fad09b2cd5 Better themes files organization 2021-03-11 11:01:16 +01:00
J-Jamet
cfb08afd7d Fix dateTime themes 2021-03-11 10:45:03 +01:00
J-Jamet
16d939c601 Fix dateTime dialog purple theme 2021-03-10 22:37:54 +01:00
J-Jamet
af072648c1 Fix reload database dialog when database created and when file modification is not 0 2021-03-10 21:24:00 +01:00
J-Jamet
45d2609494 Revert "Remove unused Base64 stream in temp file"
This reverts commit 4ecb8d4483.
2021-03-10 21:05:33 +01:00
J-Jamet
f5ea65f18c Change default icon width 2021-03-10 19:48:59 +01:00
J-Jamet
e9fc6bed23 Load icons as coroutine 2021-03-10 19:24:00 +01:00
J-Jamet
ccc8e4664d Update gradle 2021-03-10 17:43:11 +01:00
J-Jamet
651ef04137 Fix recognize iconId -1 2021-03-10 14:51:30 +01:00
Hosted Weblate
063aba333c Merge branch 'origin/develop' into Weblate. 2021-03-10 13:58:23 +01:00
J-Jamet
a3a517ff89 Fix reloading 2021-03-10 13:46:15 +01:00
Milo Ivir
40da29b681 Translated using Weblate (Croatian)
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-03-09 19:03:13 +01:00
Oğuz Ersen
684d81c895 Translated using Weblate (Turkish)
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-03-09 19:03:13 +01:00
Eric
c6ddd3b238 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-03-09 19:03:12 +01:00
Ihor Hordiichuk
3186413bee Translated using Weblate (Ukrainian)
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-03-09 19:03:12 +01:00
solokot
aae1c4cf1c Translated using Weblate (Russian)
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-03-09 19:03:11 +01:00
WaldiS
e64f264f12 Translated using Weblate (Polish)
Currently translated at 99.8% (519 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-03-09 19:03:11 +01:00
Retrial
08cf747f52 Translated using Weblate (Greek)
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-03-09 19:03:11 +01:00
J-Jamet
383437a3c7 Fix search layout 2021-03-08 20:22:35 +01:00
J-Jamet
c7cba3f50b Fix notes in group 2021-03-08 20:07:16 +01:00
J-Jamet
7feb499d50 Update CHANGELOG 2021-03-08 19:11:15 +01:00
J-Jamet
2e6c25b651 Merge branch 'feature/Add_Group_Root' into develop 2021-03-08 19:09:58 +01:00
J-Jamet
192903e8d7 Add group to root 2021-03-08 19:09:21 +01:00
J-Jamet
6f72ade4d4 Change add node button view 2021-03-08 18:49:54 +01:00
J-Jamet
7e3fc0fa59 Fix 'kotlin-android-extensions' Gradle plugin deprecated 2021-03-08 18:22:43 +01:00
J-Jamet
4ea896b57c Fix small warning 2021-03-08 18:06:56 +01:00
J-Jamet
073ccb9b52 Revert androidx.fragment:fragment-ktx:1.2.5 2021-03-08 18:03:20 +01:00
J-Jamet
f32c944d31 Remove unused import 2021-03-08 17:50:06 +01:00
J-Jamet
acd1e3bdfc Refactoring virtual group 2021-03-08 17:49:10 +01:00
J-Jamet
774cbdf0fe Fix group search 2021-03-08 17:28:55 +01:00
J-Jamet
f5fd527590 Fix status bar color 2021-03-08 17:01:08 +01:00
J-Jamet
7ac9a7e94a Fix add button in a search 2021-03-08 16:26:43 +01:00
J-Jamet
5735f7a945 Better custom icons duplication implementation 2021-03-08 14:43:50 +01:00
J-Jamet
f8f423b5c1 Better XML writing for custom icons 2021-03-08 13:35:57 +01:00
J-Jamet
81ba7f0721 Prevent duplication during database saving 2021-03-08 13:29:02 +01:00
J-Jamet
e6be8c23fb Rollback toolbar home icon 2021-03-08 13:05:53 +01:00
J-Jamet
9cc1764a18 Consume icon added 2021-03-08 13:02:48 +01:00
J-Jamet
6a77adc313 Fix error after orientation change 2021-03-08 12:58:01 +01:00
J-Jamet
e532572d5a Prevent adding duplicate icon 2021-03-08 12:51:30 +01:00
zeritti
dcae49c5f8 Translated using Weblate (Czech)
Currently translated at 100.0% (520 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-03-08 10:56:58 +01:00
Oliver Cervera
7321c01e8c Translated using Weblate (Italian)
Currently translated at 98.6% (513 of 520 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-03-08 08:16:00 +01:00
J-Jamet
a85b9998c3 Fix purple color 2021-03-07 19:10:56 +01:00
J-Jamet
30d2ce43d1 Update CHANGELOG 2021-03-07 19:00:41 +01:00
J-Jamet
d46edfc9b7 Fix flickering 2021-03-07 18:49:19 +01:00
J-Jamet
79d11138e6 Change home button icon 2021-03-07 18:28:55 +01:00
J-Jamet
f5cd019b6c Fix orientation change during icon selection 2021-03-07 17:58:31 +01:00
J-Jamet
42c4de56fd Encapsulate setResult 2021-03-07 17:33:46 +01:00
J-Jamet
44b3c28a2a Fix icon removed no longer accessible 2021-03-07 17:24:37 +01:00
J-Jamet
e5184a1568 Fix icon selection and icon removed no longer accessible 2021-03-07 17:15:48 +01:00
J-Jamet
76d60ded4c Fix color icon selection 2021-03-07 17:05:36 +01:00
J-Jamet
d2e7e925f7 Remove custom icons 2021-03-07 16:56:51 +01:00
J-Jamet
6357a30acb Upgrade material lib to 1.3.0 2021-03-06 14:57:44 +01:00
J-Jamet
4b1fdd0e38 Upgrade fragment lib 2021-03-06 14:49:30 +01:00
J-Jamet
227fc060b9 Fix restricted API and upgrade Autofill lib 2021-03-06 14:45:34 +01:00
J-Jamet
32e5aba906 Better color integration 2021-03-06 14:41:31 +01:00
J-Jamet
55013bb220 Change background dark color 2021-03-06 13:43:25 +01:00
J-Jamet
5544b20d7f Auto convert old themes 2021-03-06 13:28:10 +01:00
J-Jamet
d6c7f9c68b Fix button hidden in dialog #903 2021-03-06 12:53:44 +01:00
J-Jamet
8b5004e500 Change package import in dialog 2021-03-06 12:53:11 +01:00
J-Jamet
d6cf11b87d Fix file manager button 2021-03-06 12:35:07 +01:00
J-Jamet
d4c3a3be6b Center validate button in toolbar 2021-03-06 12:10:47 +01:00
J-Jamet
e724b188ef Remove unused code 2021-03-06 11:10:45 +01:00
J-Jamet
ebf92b1103 Remove unused code 2021-03-06 11:08:03 +01:00
J-Jamet
42e2a49af6 Better draw factory implementation 2021-03-06 10:48:05 +01:00
J-Jamet
be7cd3275a Better draw factory implementation 2021-03-06 10:22:14 +01:00
J-Jamet
966df11beb Fix subtitle toolbar color 2021-03-06 09:31:16 +01:00
J-Jamet
fad852f00d Fix icon standard color 2021-03-05 21:01:48 +01:00
Hosted Weblate
9c3e6eb823 Merge branch 'origin/develop' into Weblate. 2021-03-05 20:54:33 +01:00
J-Jamet
8b88f72efc OTP wiki link 2021-03-05 20:52:50 +01:00
J-Jamet
e0aab6cfbf Default custom tab when custom icon is already selected 2021-03-05 20:36:23 +01:00
J-Jamet
29a2e60e05 Fix fragment style 2021-03-05 20:06:30 +01:00
J-Jamet
12df74b3a7 Fix fragment style 2021-03-05 19:55:51 +01:00
Retrial
22d943c9e2 Translated using Weblate (Greek)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-03-05 19:50:50 +01:00
J-Jamet
5839f51f44 Fix otp key uppercase label #909 2021-03-05 15:14:52 +01:00
J-Jamet
4ecb8d4483 Remove unused Base64 stream in temp file 2021-03-05 14:52:56 +01:00
J-Jamet
a08035551a Move fragment in right package 2021-03-05 14:51:03 +01:00
J-Jamet
c2460d7262 Better code encapsulation 2021-03-05 14:46:23 +01:00
J-Jamet
4776eac07e Prevent custom icon usage with KDB database 2021-03-05 14:32:01 +01:00
J-Jamet
4952d107dd Upgrade NDK to v21 LTS 2021-03-05 13:17:03 +01:00
J-Jamet
b5d6ee9dee Fix education hints color 2021-03-05 13:13:07 +01:00
J-Jamet
e7a30c6024 Merge branch 'feature/Custom_Icons' into develop 2021-03-04 20:06:03 +01:00
J-Jamet
6578e52ec5 Fix error view in edit entry 2021-03-04 20:04:44 +01:00
J-Jamet
97508beb5c Icon error as warning 2021-03-04 19:50:00 +01:00
J-Jamet
e063b0d6fc Remove unused code 2021-03-04 19:48:13 +01:00
J-Jamet
bb65dc0e81 Change icon interface name 2021-03-04 19:41:43 +01:00
J-Jamet
09e00ec119 Better icon type implementation 2021-03-04 19:33:16 +01:00
J-Jamet
985f8fad3b Keep icon history 2021-03-04 19:00:17 +01:00
J-Jamet
a9accc8c42 Replace deprecated Password toggle 2021-03-04 18:34:15 +01:00
J-Jamet
41316d2bd3 Prevent add empty icon 2021-03-03 19:43:46 +01:00
J-Jamet
2c172eb8d3 Fix multiple addition 2021-03-03 19:30:33 +01:00
J-Jamet
d49827f9f8 Remove unused method 2021-03-03 17:38:45 +01:00
J-Jamet
b2aafda2b1 Auto select custom tab after upload an icon 2021-03-03 15:16:56 +01:00
J-Jamet
b4c50e0262 Async icon loading 2021-03-03 14:34:08 +01:00
J-Jamet
fbe51c12c1 Icon drawable as WeakReference 2021-03-03 12:32:06 +01:00
J-Jamet
991959416b Replace string section 2021-03-03 12:24:46 +01:00
J-Jamet
41f0e61f60 Scroll to the end when an icon is added 2021-03-02 16:55:41 +01:00
J-Jamet
eab8cd101f Prevent uploading icon in error 2021-03-02 16:50:35 +01:00
J-Jamet
97765d798c Remove apache commons collection 2021-03-02 16:23:13 +01:00
J-Jamet
a7f76248ac Better icon list implementation 2021-03-02 16:11:39 +01:00
J-Jamet
8de670fcf2 Fix uncaught exception 2021-03-02 14:48:15 +01:00
J-Jamet
744823cce4 Fix unique id for each binary file 2021-03-02 14:43:48 +01:00
J-Jamet
d95a3e00aa Resize icon file to upload 2021-03-02 13:59:15 +01:00
Deleted User
ccc190f7b0 Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.2% (386 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2021-03-02 07:03:29 +01:00
J-Jamet
3e6cd98cb9 Add big image file error 2021-03-01 17:54:10 +01:00
J-Jamet
0e3b8fdbb6 Upload custom attachment with thread 2021-03-01 16:39:46 +01:00
J-Jamet
5aa3f79616 Upload custom attachment and fix warning 2021-03-01 15:50:11 +01:00
vachan-maker
42427d0690 Translated using Weblate (Malayalam)
Currently translated at 74.8% (384 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2021-03-01 10:50:33 +01:00
J-Jamet
1a7b32e6d1 Select icon file 2021-03-01 10:48:38 +01:00
naofum
83555bfdc5 Translated using Weblate (Japanese)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-02-28 06:50:53 +01:00
J-Jamet
03990c1dd9 Add lock action 2021-02-25 19:46:51 +01:00
J-Jamet
b361be5cb0 Fix listener by using view model 2021-02-25 19:36:42 +01:00
J-Jamet
d02f6d1e67 Merge branch 'develop' into feature/Custom_Icons 2021-02-25 19:05:50 +01:00
J-Jamet
1e56c34e2f Fix ImageButton style 2021-02-25 19:05:31 +01:00
J-Jamet
2a2f8dcecd Migrate to ViewPager2 and as Activity 2021-02-25 18:54:42 +01:00
J-Jamet
b609ed3ad4 Fix number of icons 2021-02-25 15:44:23 +01:00
J-Jamet
80521f8ec2 Change list to recyclerview 2021-02-25 15:13:34 +01:00
J-Jamet
3a5df6a893 Add IconCustomFragment 2021-02-25 13:23:42 +01:00
Reza Almanda
0e60c4f910 Translated using Weblate (Indonesian)
Currently translated at 63.3% (325 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2021-02-24 23:50:38 +01:00
abidin toumi
f5f2d3c883 Translated using Weblate (Arabic)
Currently translated at 67.6% (347 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2021-02-24 23:50:36 +01:00
Kornelijus Tvarijanavičius
3c830bfaf2 Translated using Weblate (Lithuanian)
Currently translated at 22.4% (115 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lt/
2021-02-24 23:50:36 +01:00
random r
98caf9b5bf Translated using Weblate (Italian)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-02-24 23:50:35 +01:00
J-Jamet
cfbb8fab1b Merge branch 'develop' into feature/Custom_Icons 2021-02-24 21:18:08 +01:00
J-Jamet
3069e5e566 Change bioemtric unlock description #900 2021-02-24 21:13:32 +01:00
J-Jamet
ac050a09e8 Remove unused interface 2021-02-24 20:59:07 +01:00
J-Jamet
78406ccdbf Merge branch 'develop' into feature/Custom_Icons 2021-02-24 20:51:08 +01:00
J-Jamet
2efea1bb00 Merge branch 'feature/Refactor_Icons' into develop #96 2021-02-24 20:29:41 +01:00
J-Jamet
0157a160f0 Fix new entry icon inheritance 2021-02-24 20:27:19 +01:00
J-Jamet
eb4084a6a4 Factorize icon class 2021-02-24 20:19:25 +01:00
J-Jamet
63f5e5416f Refactor IconPool 2021-02-24 18:40:43 +01:00
J-Jamet
38e0433e8f Fix iconId #901 2021-02-22 21:25:14 +01:00
J-Jamet
fc5ffc5f62 Fix binary deduplication #715 2021-02-22 18:56:21 +01:00
J-Jamet
460e3558a9 First commit to create custom attachments 2021-02-22 17:17:31 +01:00
Vít Šindlář
b06f223124 Translated using Weblate (Czech)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-02-21 04:48:37 +01:00
Suyono Hermanto
aabfb2adfd Translated using Weblate (Indonesian)
Currently translated at 44.6% (229 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2021-02-20 17:50:38 +01:00
Kornelijus Tvarijanavičius
f9c47c9035 Translated using Weblate (Lithuanian)
Currently translated at 18.7% (96 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lt/
2021-02-20 17:50:38 +01:00
zeritti
e9485ebf56 Translated using Weblate (Czech)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-02-20 17:50:37 +01:00
J-Jamet
fcd7fd2889 Merge branch 'feature/Dark_Mode' into develop #714 2021-02-20 11:16:57 +01:00
J-Jamet
279f4a347a Update CHANGELOG 2021-02-20 11:16:46 +01:00
J-Jamet
b29fe23403 Fix clear style binaries color 2021-02-19 12:57:17 +01:00
J-Jamet
1972a551e9 Rename styles 2021-02-19 12:48:20 +01:00
J-Jamet
7e2ffd2ec4 Change Night word by Dark 2021-02-19 12:34:32 +01:00
J-Jamet
06793ae13e Fix database list elevation 2021-02-19 12:24:07 +01:00
J-Jamet
26e961d356 Fix color selection 2021-02-19 12:20:41 +01:00
J-Jamet
da956d3bd5 Change white colors 2021-02-19 12:01:36 +01:00
J-Jamet
318a72a123 Fix toolbar popup background 2021-02-19 11:46:42 +01:00
J-Jamet
5c4b4864d2 Setting to select theme brightness 2021-02-18 20:07:03 +01:00
J-Jamet
4ab31fe21a Small color change 2021-02-18 19:04:03 +01:00
J-Jamet
c22a213635 Fix title shadow 2021-02-18 18:39:28 +01:00
J-Jamet
aa166a0104 Fix windowLightStatusBar in v21 2021-02-18 18:34:38 +01:00
J-Jamet
2a36626731 Change blue 2021-02-18 18:22:43 +01:00
J-Jamet
2f2360fd48 Fix fab menu text color 2021-02-18 18:19:07 +01:00
J-Jamet
e466643229 Fix overflow color button 2021-02-18 18:09:47 +01:00
J-Jamet
a9044c3dc4 Fix white and black themes 2021-02-18 18:01:15 +01:00
J-Jamet
2d28cc21a0 Lock button with white color 2021-02-18 14:30:52 +01:00
J-Jamet
ebb0e7e118 Fix white & clear themes 2021-02-18 14:30:28 +01:00
J-Jamet
8205454858 Fix red & blue themes 2021-02-18 14:05:10 +01:00
ButterflyOfFire
e909112ab8 Translated using Weblate (Arabic)
Currently translated at 67.4% (346 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2021-02-18 13:50:31 +01:00
Stephan Paternotte
469923855a Translated using Weblate (Dutch)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2021-02-18 13:50:30 +01:00
Caetano Demián Moreno
f2aca08886 Translated using Weblate (Spanish)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2021-02-18 13:50:30 +01:00
J-Jamet
9900f8fecb Fix black theme 2021-02-18 13:48:33 +01:00
J-Jamet
73224887b9 Refactor toolbar popup theme 2021-02-18 13:41:29 +01:00
J-Jamet
e31574015b Refactor toolbar special appearance 2021-02-18 12:48:39 +01:00
J-Jamet
ef26251469 Refactor toolbar styles 2021-02-18 12:35:32 +01:00
J-Jamet
798bce2759 Fix custom bar home button color 2021-02-18 11:40:15 +01:00
J-Jamet
88fee5f6de Tint menu icon 2021-02-18 11:32:31 +01:00
J-Jamet
937695a1e5 First commit to implement Dark mode 2021-02-18 10:50:29 +01:00
J-Jamet
a43b580d67 Elevation in password view 2021-02-17 16:21:58 +01:00
J-Jamet
b8d0bff22b Remove unused style code 2021-02-17 15:00:24 +01:00
J-Jamet
c180d38394 Remove unused style code 2021-02-17 12:54:14 +01:00
J-Jamet
10f7d955ff Small style refactoring 2021-02-17 12:39:34 +01:00
J-Jamet
143651099a Auto open biometric prompt by default 2021-02-17 11:27:14 +01:00
J-Jamet
63bb12269f Update to version 2.9.14 2021-02-17 11:22:24 +01:00
J-Jamet
00ee80184e Merge tag '2.9.13' into develop
2.9.13
2021-02-15 12:47:54 +01:00
J-Jamet
60ba058515 Merge branch 'release/2.9.13' 2021-02-15 12:47:48 +01:00
Milo Ivir
1cf8131b6c Translated using Weblate (Croatian)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-02-13 17:50:46 +01:00
WaldiS
1b38bd59ef Translated using Weblate (Polish)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-02-13 17:50:46 +01:00
Oliver Cervera
2e409c3246 Translated using Weblate (Italian)
Currently translated at 99.2% (509 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-02-13 17:50:46 +01:00
J-Jamet
63fbca8029 Fix warning 2021-02-12 11:17:28 +01:00
J-Jamet
b37966f79c Remove empty translation 2021-02-12 11:03:06 +01:00
J-Jamet
bac5b0de5b Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-02-12 10:57:57 +01:00
J-Jamet
5dac161553 Small UI change 2021-02-12 10:53:48 +01:00
J-Jamet
528c167a88 Change delta reload time to 10 seconds to prevent dialog spamming #875 2021-02-12 10:37:43 +01:00
J-Jamet
cfe01aa996 Fix reloading database 2021-02-12 10:34:41 +01:00
J-Jamet
0f53c975cc Add popup theme to toolbar action 2021-02-11 19:24:43 +01:00
J-Jamet
b7b99c77c8 Add group edition scroll and notes multiline 2021-02-11 19:18:56 +01:00
J-Jamet
1eea5412a5 Add group expiration and fix bugs in group info 2021-02-11 19:13:30 +01:00
Oğuz Ersen
4240465930 Translated using Weblate (Turkish)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-02-11 17:57:54 +01:00
Eric
3dfbf7d2ad Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-02-11 17:57:48 +01:00
Ihor Hordiichuk
440490a4bb Translated using Weblate (Ukrainian)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-02-11 17:57:47 +01:00
solokot
746382811b Translated using Weblate (Russian)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-02-11 17:57:46 +01:00
Kunzisoft
967a54dd50 Translated using Weblate (French)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-02-11 17:57:45 +01:00
Retrial
289d9a2531 Translated using Weblate (Greek)
Currently translated at 100.0% (513 of 513 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-02-11 17:57:44 +01:00
J-Jamet
c56b4964fe Add notes in group creation 2021-02-11 17:09:26 +01:00
J-Jamet
79dbb942f9 Add notes in groups #734 2021-02-11 16:05:58 +01:00
Hosted Weblate
a5bb5635d3 Merge branch 'origin/develop' into Weblate. 2021-02-11 12:32:26 +01:00
J-Jamet
3efe43c0fe Fix toolbar popup menu color 2021-02-11 12:10:11 +01:00
J-Jamet
5fb5299d34 Fix dialog color 2021-02-11 11:22:28 +01:00
J-Jamet
b988882251 Fix themes and add Purple Dark #889 2021-02-10 20:00:56 +01:00
J-Jamet
85e82e3fb9 Update CHANGELOG 2021-02-10 17:58:34 +01:00
J-Jamet
35cfe261d2 Change Regex to allow infinite OTP padding #585 2021-02-10 17:56:22 +01:00
J-Jamet
fe4faf9ebc Update CHANGELOG 2021-02-10 17:35:41 +01:00
J-Jamet
751392d656 Add cancellation to binary uploading 2021-02-10 17:28:00 +01:00
J-Jamet
2e5ce5e94f Merge branch 'feature/Image_Viewer' into develop #473 2021-02-10 11:49:41 +01:00
J-Jamet
535eeb2594 Prevent saving attachment if currently uploading 2021-02-10 11:47:20 +01:00
J-Jamet
8f5e0e93ee Fix view flickering 2021-02-09 21:33:00 +01:00
J-Jamet
6f17c5dcac Fix binary with KDB Database 2021-02-09 21:27:57 +01:00
J-Jamet
4e7c7ba8ce Fix output KDB 2021-02-09 20:20:46 +01:00
J-Jamet
6bd5b2345c Small refactoring code 2021-02-09 18:23:48 +01:00
Michalis
63832ef8fd Translated using Weblate (Greek)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-02-09 17:50:48 +01:00
J-Jamet
3719bf3593 Remove unused code 2021-02-09 17:27:46 +01:00
J-Jamet
7bca41ca72 Standardize readAllBytes methods 2021-02-09 14:21:47 +01:00
J-Jamet
3f6a9c3af5 Rollback readBytes method and default buffer to fix argon2 database 2021-02-09 14:15:18 +01:00
J-Jamet
309380bdd5 Perform binary preview animation 2021-02-08 19:40:29 +01:00
J-Jamet
f135bdb905 Fix click listener 2021-02-08 18:35:41 +01:00
J-Jamet
2b926fd157 Fix bad preview during upload 2021-02-08 18:28:22 +01:00
J-Jamet
e911eea69c Fix closing stream for preview 2021-02-08 18:25:29 +01:00
J-Jamet
9d182b8299 Change preview layout 2021-02-08 18:12:25 +01:00
J-Jamet
61366e000f Change image binary preview 2021-02-08 17:31:42 +01:00
J-Jamet
21cf49f4f8 Better preview state management 2021-02-08 16:30:19 +01:00
J-Jamet
30f0de83d3 Better viewer in list 2021-02-08 15:09:30 +01:00
J-Jamet
42278a4b66 Add image viewer toolbar 2021-02-08 14:17:47 +01:00
J-Jamet
8752f92cea Add thread to load images 2021-02-08 13:42:04 +01:00
J-Jamet
064c468e62 Merge branch 'feature/Encrypt_Temp_Binaries' into feature/Image_Viewer 2021-02-08 10:58:31 +01:00
Michalis
ef78fb749c Translated using Weblate (Greek)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-02-07 22:47:27 +01:00
J-Jamet
a5d1db392b Try to improve image thumbnail 2021-02-07 19:24:20 +01:00
J-Jamet
6234fc2ca3 Attachment viewer 2021-02-07 19:11:59 +01:00
J-Jamet
c9cf90cdc9 Add Copyright 2021-02-07 18:22:10 +01:00
J-Jamet
5b033975b6 Add Loope license directly in Loupe class 2021-02-07 18:14:49 +01:00
J-Jamet
5663a153f7 Merge branch 'develop' into feature/Image_Viewer 2021-02-07 17:58:48 +01:00
J-Jamet
4b73c45e65 Fix unzip issue 2021-02-07 15:52:20 +01:00
J-Jamet
ac248d8b73 Merge branch 'develop' into feature/Encrypt_Temp_Binaries 2021-02-07 15:24:28 +01:00
J-Jamet
726b0d0fa3 Merge branch 'feature/Refactor_Main_Credential' into develop 2021-02-07 15:23:42 +01:00
J-Jamet
2d40164549 Remove TODO 2021-02-07 14:52:43 +01:00
J-Jamet
5203152f78 Better main credential factorization 2021-02-07 14:33:36 +01:00
J-Jamet
b064bb74cd Better main credential factorization 2021-02-07 14:26:57 +01:00
J-Jamet
843d8e8e77 Refactor Main Credential object 2021-02-07 14:06:44 +01:00
J-Jamet
c5f95b243d Merge branch 'develop' into feature/Encrypt_Temp_Binaries 2021-02-07 13:02:16 +01:00
J-Jamet
06f1f4c8ad Fix new database version 2021-02-07 13:02:01 +01:00
J-Jamet
9847f834c2 Check length during binary unit tests 2021-02-07 10:51:56 +01:00
J-Jamet
b744d58e6c Better upload method 2021-02-07 10:51:39 +01:00
J-Jamet
c95358b344 Fix binary padding 2021-02-06 23:15:49 +01:00
J-Jamet
2f15d6c9f2 Show buffer copy 2021-02-06 20:57:28 +01:00
J-Jamet
d13aa047d5 Fix length and better streams implementation 2021-02-06 20:24:07 +01:00
J-Jamet
7590d18c67 Better copy methods 2021-02-06 17:23:03 +01:00
Michalis
a689116c97 Translated using Weblate (Greek)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-02-06 00:42:03 +01:00
J-Jamet
3bf7459f05 Fix binary stream and change cipher to be faster 2021-02-05 15:39:34 +01:00
J-Jamet
c70faaedd1 Rename BinaryAttachment to BinaryAttachmentTest 2021-02-05 13:44:30 +01:00
J-Jamet
cb2417fbe4 Better unit test for attachment 2021-02-05 13:43:36 +01:00
J-Jamet
65dd996f2e Merge branch 'feature/Unit_Test_Binary' into feature/Encrypt_Temp_Binaries 2021-02-05 13:14:26 +01:00
J-Jamet
01790a6f31 Add binary unit test 2021-02-05 13:14:05 +01:00
Jakub Fabijan
8b84bb893d Translated using Weblate (Esperanto)
Currently translated at 28.7% (147 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/eo/
2021-02-01 22:40:31 +01:00
Óscar Fernández Díaz
8cb99847c5 Translated using Weblate (Spanish)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2021-02-01 22:40:28 +01:00
zeritti
b3e01277d4 Translated using Weblate (Czech)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-02-01 22:40:27 +01:00
Jakub Fabijan
b10d407659 Added translation using Weblate (Esperanto) 2021-02-01 01:34:06 +01:00
WaldiS
b7c5a5d238 Translated using Weblate (Polish)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-01-29 15:32:14 +01:00
J-Jamet
90d1ce63e8 Encrypt and decrypt temp files 2021-01-28 14:23:44 +01:00
Allan Nordhøy
9e30b4e5f7 Translated using Weblate (Norwegian Bokmål)
Currently translated at 69.7% (357 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2021-01-28 05:32:14 +01:00
J-Jamet
e541a8c629 Merge branch 'develop' into feature/Encrypt_Temp_Binaries 2021-01-26 18:36:39 +01:00
J-Jamet
0afe25c922 Scroll and better UI in entry edition screen #876 2021-01-26 18:22:00 +01:00
J-Jamet
bca133430f Transform exceptions to be sure #877 2021-01-26 14:41:57 +01:00
J-Jamet
9c925518a7 Add toast if reload error #877 2021-01-26 14:25:56 +01:00
J-Jamet
18e79b99e7 Move notifications package to services 2021-01-26 12:34:12 +01:00
J-Jamet
4e02846df9 Update CHANGELOG 2021-01-26 12:15:48 +01:00
J-Jamet
2268b78bba Allow Emoji #796 2021-01-26 12:14:24 +01:00
J-Jamet
ea8acd0677 Upgrade version and CHANGELOG 2021-01-26 09:16:41 +01:00
J-Jamet
9e931dd03f Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2021-01-26 09:12:34 +01:00
J-Jamet
19e3aabca4 Try to fix TOTP plugin #878 2021-01-26 09:11:29 +01:00
Milo Ivir
ae697d82d5 Translated using Weblate (Croatian)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-01-25 19:32:14 +01:00
Oğuz Ersen
33382273c3 Translated using Weblate (Turkish)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-01-24 04:24:11 +01:00
Eric
7d8466d77a Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-01-24 04:24:10 +01:00
Ihor Hordiichuk
5ca08a00d2 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-01-24 04:24:10 +01:00
solokot
df3942697e Translated using Weblate (Russian)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-01-24 04:24:10 +01:00
Oliver Cervera
5700ca5bcf Translated using Weblate (Italian)
Currently translated at 99.2% (508 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-01-24 04:24:09 +01:00
Kunzisoft
54b2419d64 Translated using Weblate (French)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-01-24 04:24:09 +01:00
Retrial
d8b1c94b78 Translated using Weblate (Greek)
Currently translated at 100.0% (512 of 512 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-01-24 04:24:09 +01:00
J-Jamet
2d1ffc23b9 Merge tag '2.9.12' into develop
2.9.12
2021-01-23 13:44:39 +01:00
J-Jamet
e6b33d60c3 Merge branch 'release/2.9.12' 2021-01-23 13:44:33 +01:00
J-Jamet
3fd06890d7 Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-01-23 13:22:56 +01:00
J-Jamet
4af4ad7663 Fix show UUID key 2021-01-23 13:18:03 +01:00
J-Jamet
6ca8501e28 Keep current screen after theme change 2021-01-23 13:13:01 +01:00
J-Jamet
432b385f60 Fix orientation change in settings #872 2021-01-23 12:56:47 +01:00
Hosted Weblate
6cebdefa4a Merge branch 'origin/develop' into Weblate. 2021-01-23 12:48:39 +01:00
J-Jamet
bc665eb83d Fix orientation change in settings #872 2021-01-23 12:16:18 +01:00
J-Jamet
cb187300fe Deactivate GiB #851 2021-01-23 11:21:38 +01:00
J-Jamet
da761614bd Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2021-01-22 18:03:36 +01:00
J-Jamet
f34e007ecd Add kibibyte and gibibyte #851 2021-01-22 16:07:50 +01:00
J-Jamet
3b6ad080b4 Update CHANGELOG 2021-01-22 15:46:30 +01:00
J-Jamet
9919e90ba5 Change memory unit to MiB 2021-01-22 15:37:50 +01:00
WaldiS
f4af44925b Translated using Weblate (Polish)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-01-21 21:45:29 +01:00
J-Jamet
4bb366b568 Capture exception in IO action task 2021-01-21 14:38:34 +01:00
J-Jamet
7e7ab4ce19 Catch exception when check database info 2021-01-21 14:32:11 +01:00
J-Jamet
4d833d25ce Add IME_FLAG_NO_PERSONALIZED_LEARNING options #642 2021-01-21 14:16:13 +01:00
J-Jamet
a9c508ecd9 Fix back appearance setting #865 2021-01-21 13:36:50 +01:00
J-Jamet
ef4dbb8fdb Fix auto open biometric prompt #862 2021-01-21 12:46:43 +01:00
J-Jamet
9eb66face5 Fix reload exception 2021-01-20 12:46:08 +01:00
J-Jamet
3fd13f3e3b Try to fix decodeHex method conflict in some devices 2021-01-20 11:42:09 +01:00
Kornelijus Tvarijanavičius
319c9cad4b Translated using Weblate (Lithuanian)
Currently translated at 15.1% (77 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lt/
2021-01-20 11:32:13 +01:00
nautilusx
c12297c98d Translated using Weblate (German)
Currently translated at 98.8% (501 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2021-01-20 11:32:13 +01:00
J-Jamet
7c38361844 Fix OTP token type #863 2021-01-18 16:48:57 +01:00
J-Jamet
559554a975 Upgrade to 2.9.12 2021-01-18 16:47:48 +01:00
Darin Avdeyeva
7e2ffa2124 Translated using Weblate (Russian)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-01-17 19:40:00 +01:00
Milo Ivir
66dbac4bb2 Translated using Weblate (Croatian)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-01-17 15:28:44 +01:00
Carlos Pinto
8b6a843a85 Translated using Weblate (Portuguese (Portugal))
Currently translated at 90.7% (460 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2021-01-17 15:28:43 +01:00
HARADA Hiroyuki
976cff2751 Translated using Weblate (Japanese)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-01-17 15:28:43 +01:00
zeritti
f7c30fa8eb Translated using Weblate (Czech)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2021-01-17 15:28:42 +01:00
J-Jamet
7757c8218b Merge tag '2.9.11' into develop
2.9.11
2021-01-16 19:09:33 +01:00
J-Jamet
2928b7daa3 Merge branch 'release/2.9.11' 2021-01-16 19:09:22 +01:00
J-Jamet
3a55dea276 Merge branch 'develop' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2021-01-16 18:54:47 +01:00
J-Jamet
2a25213d66 Update CHANGELOG 2021-01-16 18:49:11 +01:00
J-Jamet
035ffd8135 Fix hexadecimal keyfile #861 2021-01-16 18:46:17 +01:00
J-Jamet
b040487f1f Use decodeHex method 2021-01-15 18:16:46 +01:00
J-Jamet
6fc821aecf Fix keyx file version 2 #844 2021-01-15 17:00:29 +01:00
J-Jamet
cdceb1fb6f Fix keyx file version 2 #844 2021-01-15 16:57:29 +01:00
J-Jamet
07d185913d Upgrade to 2.9.11 2021-01-15 16:35:25 +01:00
Eric
f2a245a9c8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2021-01-15 14:19:14 +01:00
Oliver Cervera
33338f4759 Translated using Weblate (Italian)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2021-01-15 14:19:13 +01:00
J-Jamet
f7a4370b29 Merge tag '2.9.10' into develop
2.9.10
2021-01-15 01:53:07 +01:00
J-Jamet
77b7afedda Merge branch 'release/2.9.10' 2021-01-15 01:52:59 +01:00
J-Jamet
caa13039e5 Update CHANGELOG 2021-01-15 01:52:32 +01:00
J-Jamet
02845d93ed Change order keyfile recognition 2021-01-15 01:44:40 +01:00
J-Jamet
9ef4695cc7 Change order keyfile recognition 2021-01-15 01:00:13 +01:00
Oğuz Ersen
d619e089c0 Translated using Weblate (Turkish)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2021-01-14 23:11:57 +01:00
Ihor Hordiichuk
3c50348a79 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2021-01-14 23:11:56 +01:00
solokot
167ea3b82b Translated using Weblate (Russian)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2021-01-14 23:11:56 +01:00
WaldiS
9eda3e62f7 Translated using Weblate (Polish)
Currently translated at 99.0% (502 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-01-14 23:11:56 +01:00
Kunzisoft
99c4319b51 Translated using Weblate (French)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2021-01-14 23:11:55 +01:00
Retrial
790b25db65 Translated using Weblate (Greek)
Currently translated at 100.0% (507 of 507 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2021-01-14 23:11:55 +01:00
J-Jamet
97d4972f9a Try to fix crash with autofill #852 2021-01-14 21:42:40 +01:00
J-Jamet
8e6853756f Upgrade to version 2.9.10 2021-01-14 14:58:07 +01:00
J-Jamet
6d3aae187b Merge tag '2.9.9' into develop
2.9.9
2021-01-14 14:46:53 +01:00
J-Jamet
b8c7acf7ce Merge branch 'release/2.9.9' 2021-01-14 14:46:46 +01:00
J-Jamet
17a356ae76 Replace strong tag 2021-01-14 13:50:41 +01:00
J-Jamet
bd847e632d Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2021-01-14 13:46:56 +01:00
J-Jamet
2bfb9b048d Better entry visualisation 2021-01-14 13:23:35 +01:00
J-Jamet
dc40b50b65 Parse new TOTP fields from KeePass 2.47 #850 2021-01-14 11:48:44 +01:00
J-Jamet
3e2271e596 Update CHANGELOG 2021-01-13 16:48:36 +01:00
J-Jamet
4b4fd2a11d Fix OTP generation for long secret key #848 2021-01-13 16:46:19 +01:00
J-Jamet
23468290df Fix small visual element 2021-01-12 19:43:16 +01:00
J-Jamet
a276f6aa06 Remove keyfile icon 2021-01-12 19:11:23 +01:00
J-Jamet
f2a58361a1 Update CHANGELOG 2021-01-12 18:09:40 +01:00
J-Jamet
271023b528 Fix Toggling custom field protection #849 2021-01-12 18:08:05 +01:00
J-Jamet
e1771ca249 Upgrade CHANGELOG 2021-01-12 15:11:09 +01:00
J-Jamet
ca4f4bd151 Add priority to OTP button in notification #845 2021-01-12 15:08:59 +01:00
J-Jamet
d81454d618 FEATURE_SECURE_PROCESSING Error to Warning log 2021-01-12 13:13:08 +01:00
J-Jamet
fb43c1c624 Special search in title fields #830 2021-01-12 09:28:05 +01:00
J-Jamet
9e060f878d Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2021-01-12 09:24:09 +01:00
Milo Ivir
bd9c21ee8a Translated using Weblate (Croatian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2021-01-12 00:32:09 +01:00
J-Jamet
3e6d40e8da Better autofill suggestion toast 2021-01-11 21:33:25 +01:00
J-Jamet
79683cb3fc Encapsulate autofillInlineSuggestionsEnabled preference 2021-01-11 21:17:34 +01:00
J-Jamet
52a2090a31 Upgrade CHANGELOG 2021-01-11 20:53:52 +01:00
J-Jamet
3dfe4ace7b Fix binary keyfiles of 64 bytes #835 2021-01-11 20:42:14 +01:00
J-Jamet
bd0d17b134 Remove unused log 2021-01-11 17:58:22 +01:00
J-Jamet
6b0ccc1780 Update CHANGELOG 2021-01-11 15:02:18 +01:00
J-Jamet
d75ac4b825 Remove unused log 2021-01-11 14:55:37 +01:00
J-Jamet
b60d610d02 Remove loadXmlKeyFile method in KDB database 2021-01-11 14:30:53 +01:00
J-Jamet
f7a5c5d0ea Fix hash in keyfile XML version 1 2021-01-11 14:17:43 +01:00
J-Jamet
28f79aec11 Check keyfile XML hash 2021-01-11 14:11:30 +01:00
J-Jamet
778d963fbf Encapsulate String util and fix Key File recognition #844 2021-01-11 11:31:22 +01:00
J-Jamet
a765bc84e7 Upgrade buildToolsVersion to 30.0.3 2021-01-11 11:29:31 +01:00
J-Jamet
804ecc1baa Merge branch 'feature/Autofill_Inline' into develop #827 2021-01-09 16:01:04 +01:00
J-Jamet
d331c3dc03 Fix title in autofill activity 2021-01-09 16:00:44 +01:00
J-Jamet
7010d2f86a Refresh preferences during connection 2021-01-09 15:50:50 +01:00
J-Jamet
b1d6117eb2 Fix autofill longpress 2021-01-09 15:44:47 +01:00
J-Jamet
f3b814388d Add toast to inform the user of inline suggestions in the keyboard 2021-01-09 15:02:29 +01:00
J-Jamet
b62996a57c Setting to allow or not inline suggestions 2021-01-09 14:29:59 +01:00
J-Jamet
a49e056f02 Autofill component to select entry with inline response 2021-01-09 14:02:01 +01:00
J-Jamet
a6dece16bf Merge branch 'develop' into feature/Autofill_Inline 2021-01-09 12:33:26 +01:00
J-Jamet
8e3ddd64d2 Better exception catching #794 2021-01-09 12:17:43 +01:00
J-Jamet
45a847fa3e Remove unused code 2021-01-09 11:26:19 +01:00
J-Jamet
6b6f03b143 Remove small warning 2021-01-09 11:20:41 +01:00
J-Jamet
5446efca4a Output header refactor 2021-01-09 11:09:31 +01:00
J-Jamet
8d04a7f90b Merge branch 'develop' into feature/Autofill_Inline 2021-01-08 16:36:34 +01:00
J-Jamet
626495c19e Upgrade CHANGELOG 2021-01-07 23:35:06 +01:00
J-Jamet
e5a198f524 Remove unused variable 2021-01-07 23:22:30 +01:00
J-Jamet
161524843f Merge branch 'feature/Detect_File_Changes' into develop #794 2021-01-07 22:50:05 +01:00
J-Jamet
5550e7dea3 Remove unused duplicateUUID exception during reloading 2021-01-07 22:44:46 +01:00
J-Jamet
64f66c290c Prevent reloading from special mode 2021-01-07 22:34:11 +01:00
J-Jamet
e8925b3c0b Fix exception 2021-01-07 22:12:02 +01:00
J-Jamet
cf67ce04a8 Better animation and reload setting screen 2021-01-07 22:03:17 +01:00
J-Jamet
84ee4ca2c7 Change dialog 2021-01-07 21:07:32 +01:00
J-Jamet
27eb095720 Add database reloading #794 2021-01-07 16:25:05 +01:00
J-Jamet
d273f21819 Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2021-01-05 15:50:34 +01:00
J-Jamet
455fd0cd6d Remove unused log 2021-01-05 13:20:12 +01:00
J-Jamet
c5a8650c81 Show a dialog when a database file info changes #794 2021-01-05 12:48:06 +01:00
J-Jamet
b5f9bbed5e Detect Database File Info Changes #794 2021-01-04 19:26:20 +01:00
J-Jamet
45da17adb8 Encrypt temp binaries 2021-01-04 16:56:57 +01:00
George
e789741090 Translated using Weblate (Bulgarian)
Currently translated at 2.2% (11 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bg/
2021-01-04 03:29:34 +01:00
George
5c6d93bc57 Added translation using Weblate (Bulgarian) 2021-01-03 02:39:46 +01:00
WaldiS
697b672038 Translated using Weblate (Polish)
Currently translated at 98.8% (494 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2021-01-02 22:49:58 +01:00
Y. Sakamoto
2d9e9c24a8 Translated using Weblate (Japanese)
Currently translated at 99.8% (499 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2021-01-02 22:49:58 +01:00
J-Jamet
5fb281c800 Upgrade to 2.9.9 2021-01-02 19:13:08 +01:00
J-Jamet
96896c1c42 Merge tag '2.9.8' into develop
2.9.8
2021-01-02 18:28:48 +01:00
J-Jamet
d7052bd9e6 Merge branch 'release/2.9.8' 2021-01-02 18:28:26 +01:00
J-Jamet
8b23932788 Fix IllegalStateException 2021-01-02 18:28:03 +01:00
J-Jamet
50912c6966 Update CHANGELOG 2021-01-02 18:25:45 +01:00
J-Jamet
53b51934b9 Upgrade kotlin version 2021-01-02 18:14:15 +01:00
J-Jamet
a8a3685965 Upgrade Room to 2.2.6 2021-01-02 13:50:38 +01:00
J-Jamet
149b67e28b Better exception StreamCipherFactory.getInstance management 2021-01-02 11:04:45 +01:00
J-Jamet
a83032bffa Fix binary in a single entry #828 2021-01-02 09:44:03 +01:00
Oğuz Ersen
a5d3a153bf Translated using Weblate (Turkish)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-31 13:30:01 +01:00
Eric
4210c155eb Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-31 13:30:01 +01:00
Ihor Hordiichuk
4bf110a9b1 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-31 13:30:00 +01:00
solokot
50f2684500 Translated using Weblate (Russian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-31 13:30:00 +01:00
J. Lavoie
e95424b8f9 Translated using Weblate (Italian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-31 13:30:00 +01:00
J. Lavoie
8462882707 Translated using Weblate (French)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-31 13:30:00 +01:00
Óscar Fernández Díaz
a5c8d25f64 Translated using Weblate (Spanish)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-31 13:29:59 +01:00
Retrial
689ce2f9b3 Translated using Weblate (Greek)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-12-31 13:29:59 +01:00
J. Lavoie
54246533ac Translated using Weblate (German)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-31 13:29:59 +01:00
zeritti
66e4b0fe47 Translated using Weblate (Czech)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-12-31 13:29:16 +01:00
J-Jamet
3e8ae3e2e3 Upgrade KeePassDX Pro description 2020-12-30 17:23:17 +01:00
J-Jamet
d856ef3772 Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-12-30 17:20:05 +01:00
x
5727880ac7 Translated using Weblate (Italian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-30 03:21:37 +01:00
Oliver Cervera
ec4302a780 Translated using Weblate (Italian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-30 03:20:48 +01:00
x
d4203598a1 Translated using Weblate (Italian)
Currently translated at 100.0% (500 of 500 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-30 03:20:46 +01:00
Hosted Weblate
a278c8c718 Merge branch 'origin/develop' into Weblate. 2020-12-28 21:11:52 +01:00
WaldiS
faf5f4b51a Translated using Weblate (Polish)
Currently translated at 98.7% (492 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-12-28 21:11:52 +01:00
J-Jamet
b2f503b326 Upgrade to 2.9.8 2020-12-28 21:11:20 +01:00
J-Jamet
beb5484bf6 Merge tag '2.9.7' into develop
2.9.7
2020-12-28 21:00:32 +01:00
J-Jamet
ec63d75349 Merge branch 'release/2.9.7' 2020-12-28 21:00:27 +01:00
J-Jamet
4c0e79b245 Update CHANGELOG 2020-12-28 20:46:14 +01:00
J-Jamet
50a77684c1 Replace strong tag 2020-12-28 20:35:20 +01:00
J-Jamet
8bb84b486d Fix small translation 2020-12-28 20:33:41 +01:00
J-Jamet
4b05f2536f Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2020-12-28 20:33:05 +01:00
J-Jamet
d6f968fe7e Write permission until Android 10 #823 2020-12-28 12:06:48 +01:00
J-Jamet
ed758edd44 Fix small warning 2020-12-28 11:57:29 +01:00
J-Jamet
94b7fce2e5 Merge branch 'tibequadorian-patch-1' into develop 2020-12-28 11:54:56 +01:00
J-Jamet
dbd9c6cbb7 Fix rebuiltList crash 2020-12-28 11:39:16 +01:00
J-Jamet
0f6376fb80 Fix illegalstate when managing views 2020-12-28 11:17:38 +01:00
J-Jamet
9522328238 Fix crash when creating new field 2020-12-28 11:05:20 +01:00
J-Jamet
e6ad716119 Fix crash 2020-12-28 10:45:27 +01:00
Éfrit
440006bb08 Translated using Weblate (French)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-26 23:29:31 +01:00
tibequadorian
ea289ef7cf fix typo 2020-12-26 05:42:57 +01:00
solokot
352b171484 Translated using Weblate (Russian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-25 17:10:11 +01:00
Óscar Fernández Díaz
969ab56bf8 Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-25 00:29:12 +01:00
J-Jamet
062a9852e5 Fix small warning 2020-12-24 15:20:13 +01:00
Óscar Fernández Díaz
dd77d7a5e6 Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 23:22:51 +01:00
SeerLite
f60e32522a Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 23:22:51 +01:00
Óscar Fernández Díaz
070a91f19c Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 23:20:44 +01:00
SeerLite
0790e80670 Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 23:20:44 +01:00
Óscar Fernández Díaz
20841e3d7b Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 23:13:36 +01:00
SeerLite
0caae233c3 Translated using Weblate (Spanish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 23:13:36 +01:00
Óscar Fernández Díaz
5497d8fafb Translated using Weblate (Spanish)
Currently translated at 99.5% (496 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:41:42 +01:00
SeerLite
f69b43249c Translated using Weblate (Spanish)
Currently translated at 99.5% (496 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:41:41 +01:00
Óscar Fernández Díaz
b606fd98f6 Translated using Weblate (Spanish)
Currently translated at 88.5% (441 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:20:52 +01:00
SeerLite
ba3b7b0f1f Translated using Weblate (Spanish)
Currently translated at 88.5% (441 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:20:52 +01:00
Óscar Fernández Díaz
058d82dc36 Translated using Weblate (Spanish)
Currently translated at 86.3% (430 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:17:07 +01:00
SeerLite
6f0b0ac4fa Translated using Weblate (Spanish)
Currently translated at 86.3% (430 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:17:06 +01:00
Óscar Fernández Díaz
35f87b0f94 Translated using Weblate (Spanish)
Currently translated at 85.5% (426 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:15:19 +01:00
SeerLite
0ead9ce9b4 Translated using Weblate (Spanish)
Currently translated at 85.5% (426 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-12-23 17:15:18 +01:00
vachan-maker
80479a6a7c Translated using Weblate (Malayalam)
Currently translated at 76.9% (383 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-12-22 00:37:38 +01:00
J-Jamet
a7cea8201e Try to fix biometric crash 2020-12-20 11:41:58 +01:00
solokot
081a7fa798 Translated using Weblate (Russian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-20 10:29:12 +01:00
WaldiS
85782c4f93 Translated using Weblate (Polish)
Currently translated at 97.9% (488 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-12-20 10:29:11 +01:00
uniprivscy
d7b7df26d7 Translated using Weblate (German)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-18 18:29:10 +01:00
J-Jamet
b6b1c8e31d Upgrade to version 2.9.7 2020-12-18 10:51:42 +01:00
J-Jamet
17156f7ca2 Merge tag '2.9.6' into develop
2.9.6
2020-12-18 10:15:51 +01:00
J-Jamet
0761d356b8 Merge branch 'release/2.9.6' 2020-12-18 10:15:41 +01:00
J-Jamet
6da747ce6f Fix keyfile bug #820 2020-12-18 10:06:38 +01:00
uniprivscy
87b1a1f527 Translated using Weblate (German)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-17 17:44:09 +01:00
Paul
72a8a55faf Translated using Weblate (German)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-17 17:44:09 +01:00
J-Jamet
9a6a709746 Inline presentation when sign in 2020-12-17 15:16:06 +01:00
J-Jamet
428b53cc56 Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-12-17 12:32:37 +01:00
J-Jamet
e688859e32 Fix exception when UI not fully loaded and click performed 2020-12-17 12:32:30 +01:00
Milo Ivir
98336da116 Translated using Weblate (Croatian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-12-17 09:56:23 +01:00
Oğuz Ersen
c037e443b0 Translated using Weblate (Turkish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-17 09:56:23 +01:00
Eric
d339a50e0a Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-17 09:56:23 +01:00
Ihor Hordiichuk
7d836f2633 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-17 09:56:22 +01:00
solokot
45d8470b4c Translated using Weblate (Russian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-17 09:56:22 +01:00
Oliver Cervera
1ca3bfe472 Translated using Weblate (Italian)
Currently translated at 99.7% (497 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-17 09:56:22 +01:00
Retrial
066da83d70 Translated using Weblate (Greek)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-12-17 09:56:22 +01:00
zeritti
44ab881751 Translated using Weblate (Czech)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-12-17 09:56:21 +01:00
J-Jamet
5ab3cf985a Merge branch 'develop' into feature/Autofill_Inline 2020-12-16 17:54:53 +01:00
J-Jamet
f271f2b181 Update to 2.9.6 2020-12-16 17:54:33 +01:00
J-Jamet
91d75be0ea Merge tag '2.9.5' into develop
2.9.5
2020-12-16 17:06:02 +01:00
J-Jamet
774dddca54 Merge branch 'release/2.9.5' 2020-12-16 17:05:47 +01:00
J-Jamet
e18b3436c9 Add inline autofill right icon 2020-12-16 15:37:23 +01:00
J-Jamet
fcb1b5ae6b First inline code 2020-12-16 15:25:04 +01:00
J-Jamet
de980d030a Merge branch 'develop' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-12-16 11:13:48 +01:00
J-Jamet
0e859646fe Fix timeout reset #817 2020-12-15 19:40:27 +01:00
christopher robert
059c7b7713 Translated using Weblate (German)
Currently translated at 98.3% (490 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-15 13:29:10 +01:00
J-Jamet
5fb7bf71c8 Prevent auto switch back to previous keyboard if otp field exists #814 2020-12-15 11:47:57 +01:00
J-Jamet
8b0133ff7f Update CHANGELOG 2020-12-14 19:25:34 +01:00
J-Jamet
8d834946b8 Fix view flickering 2020-12-14 19:12:45 +01:00
J-Jamet
2f646395d4 Merge branch 'feature/Device_Unlock' into develop 2020-12-14 18:31:28 +01:00
J-Jamet
f6e79ba37b Add advanced unlock education hint 2020-12-14 18:23:41 +01:00
J-Jamet
e633c7a861 Biometric unlock in priority and device unlock when biometric not available 2020-12-14 17:51:18 +01:00
J-Jamet
dc02a8d78c Rollback to fix bug after orientation change 2020-12-14 16:59:38 +01:00
J-Jamet
baa9b88512 Check if current database is the same after activity result 2020-12-14 16:56:15 +01:00
J-Jamet
c522e87da8 Fix multiple methods in settings 2020-12-14 16:41:14 +01:00
Paul
ef5ebf2c15 Translated using Weblate (German)
Currently translated at 98.3% (490 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-14 13:23:34 +01:00
christopher robert
4b147e770c Translated using Weblate (German)
Currently translated at 98.3% (490 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-14 13:23:34 +01:00
J-Jamet
157a5c0b05 Refactor view visibility method 2020-12-13 23:39:17 +01:00
J-Jamet
f2288b0c64 Fix biometric prompt during orientation change 2020-12-13 23:25:44 +01:00
J-Jamet
d8506450aa Fix biometric orientation change 2020-12-13 23:19:04 +01:00
J-Jamet
f9b085e73f Fix min setting version and condition in Android R 2020-12-13 22:44:30 +01:00
J-Jamet
388cf6a91b Fix device credential condition and keep connexion if ActivityForResult requested 2020-12-13 22:33:58 +01:00
Stephan Paternotte
9e6e77b363 Translated using Weblate (Dutch)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-12-13 18:48:46 +01:00
J-Jamet
ec33ca8173 Refactoring Advanced unlock fragment and manager 2020-12-13 17:09:41 +01:00
J-Jamet
6be0457947 Add fragment 2020-12-13 14:18:21 +01:00
WaldiS
f3b84aa845 Translated using Weblate (Polish)
Currently translated at 98.1% (489 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-12-12 17:29:08 +01:00
J-Jamet
bd0b5b0954 Fix exception message 2020-12-12 14:53:23 +01:00
J-Jamet
7dc93604ad Refactoring AdvancedUnlockManager.kt 2020-12-12 14:13:13 +01:00
J-Jamet
0ab22698a6 Refactoring classes 2020-12-11 15:15:52 +01:00
J-Jamet
c885ce7aaf Refactoring of advanced unlock 2020-12-11 13:36:51 +01:00
J-Jamet
92d1a7b901 Fix string 2020-12-11 11:11:48 +01:00
J-Jamet
6119054b45 Upgrade to version 2.9.5 2020-12-11 11:03:00 +01:00
Eric
e7aed72398 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-11 01:55:56 +01:00
solokot
cee7fa50f5 Translated using Weblate (Russian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-11 01:55:55 +01:00
Stephan Paternotte
39a38bb223 Translated using Weblate (Dutch)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-12-11 01:55:55 +01:00
Oliver Cervera
7159a993db Translated using Weblate (Italian)
Currently translated at 99.7% (497 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-11 01:55:54 +01:00
J-Jamet
23933e80e3 Merge tag '2.9.4' into develop
2.9.4
2020-12-10 22:27:38 +01:00
J-Jamet
abc971b5cc Merge branch 'release/2.9.4' 2020-12-10 22:27:30 +01:00
J-Jamet
7dedcc8a21 Argon2_id implementation #791 2020-12-10 22:15:08 +01:00
J-Jamet
10d46e5dee Remove default device credential in Android R to prevent update bug #812 2020-12-10 14:58:33 +01:00
J-Jamet
139f7eb36d Upgrade version to 2.9.4 2020-12-09 16:50:32 +01:00
J-Jamet
1ddfa894b6 Merge tag '2.9.3' into develop
2.9.3
2020-12-09 16:13:56 +01:00
J-Jamet
d1695ab8c2 Merge branch 'release/2.9.3' 2020-12-09 16:13:39 +01:00
Milo Ivir
f27979e729 Translated using Weblate (Croatian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-12-09 15:36:20 +01:00
Milo Ivir
6e61e8172a Translated using Weblate (Croatian)
Currently translated at 99.7% (497 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-12-09 14:37:24 +01:00
Oğuz Ersen
21890894ae Translated using Weblate (Turkish)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-09 14:37:24 +01:00
Ihor Hordiichuk
1feecd559d Translated using Weblate (Ukrainian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-09 14:37:24 +01:00
solokot
6ea4afe75b Translated using Weblate (Russian)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-09 14:37:21 +01:00
HARADA Hiroyuki
fd96f6367d Translated using Weblate (Japanese)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-12-09 14:37:21 +01:00
Kunzisoft
8ce183c4c9 Translated using Weblate (French)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-09 14:37:20 +01:00
Retrial
407a1db101 Translated using Weblate (Greek)
Currently translated at 100.0% (498 of 498 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-12-09 14:37:20 +01:00
J-Jamet
622d096e31 Merge branch 'develop' of https://hosted.weblate.org/git/keepass-dx/strings into translations 2020-12-08 13:01:48 +01:00
C. Rüdinger
bf27fb1f89 Translated using Weblate (German)
Currently translated at 94.9% (466 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-08 12:53:03 +01:00
Paul
860b9055c5 Translated using Weblate (German)
Currently translated at 94.9% (466 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-08 12:53:03 +01:00
J-Jamet
b3ae3a4148 Merge branch 'feature/Temp_Advanced_Unlock' into develop #102 #437 #566 2020-12-08 12:08:48 +01:00
J-Jamet
0abd7d5762 Update CHANGELOG 2020-12-08 12:08:28 +01:00
J-Jamet
0aac2bc55b Fix settings 2020-12-08 12:05:35 +01:00
J-Jamet
fa08dc5cfb Change notification icon 2020-12-08 11:17:39 +01:00
J-Jamet
8d18970b4c Fix advanced unlock notification 2020-12-07 20:34:23 +01:00
J-Jamet
173f5ce979 Add advanced unlock timeout 2020-12-07 20:21:39 +01:00
J-Jamet
2e7088310a Add listeners to refresh unlocking state 2020-12-07 19:07:10 +01:00
J-Jamet
c75d99030c Better service implementation 2020-12-07 18:22:04 +01:00
J-Jamet
e4ba1d9bae Better service implementation 2020-12-07 17:40:12 +01:00
J-Jamet
e2886c342a Add temp advanced service to store encrypted elements 2020-12-07 17:03:26 +01:00
J-Jamet
e600d8a56c Add temp advanced unlocking settings 2020-12-07 14:08:44 +01:00
J-Jamet
caeb305475 Fix deletion keystore key 2020-12-07 12:17:07 +01:00
Milo Ivir
3d3a9d9bad Translated using Weblate (Croatian)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-12-06 15:29:09 +01:00
Oğuz Ersen
5499ad5b94 Translated using Weblate (Turkish)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-06 15:29:08 +01:00
Eric
0e29cd0cee Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-06 15:29:08 +01:00
Ihor Hordiichuk
24fb1b1a8f Translated using Weblate (Ukrainian)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-06 15:29:07 +01:00
solokot
03fb4cbf0c Translated using Weblate (Russian)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-06 15:29:07 +01:00
WaldiS
e909280d5b Translated using Weblate (Polish)
Currently translated at 98.7% (485 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-12-06 15:29:07 +01:00
Kunzisoft
d41ddf60b4 Translated using Weblate (French)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-06 15:29:06 +01:00
Retrial
1e01a74986 Translated using Weblate (Greek)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-12-06 15:29:06 +01:00
zeritti
96a007aace Translated using Weblate (Czech)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-12-06 15:29:06 +01:00
J-Jamet
9f23bb6129 Device credential as default unlock method in Android R+ 2020-12-05 15:03:23 +01:00
J-Jamet
b7e8559773 Remove unused code 2020-12-05 14:42:45 +01:00
J-Jamet
5b247575c8 Fix small bugs #805 2020-12-05 12:09:07 +01:00
HARADA Hiroyuki
eb0e5b478f Translated using Weblate (Japanese)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-12-04 03:46:13 +01:00
HARADA Hiroyuki
08906ae1da Translated using Weblate (Japanese)
Currently translated at 100.0% (491 of 491 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-12-04 02:53:11 +01:00
Hosted Weblate
395a5efecd Merge branch 'origin/develop' into Weblate. 2020-12-03 23:58:52 +01:00
Milo Ivir
0452dd14f6 Translated using Weblate (Croatian)
Currently translated at 97.9% (476 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-12-03 23:58:52 +01:00
Oğuz Ersen
3906df314d Translated using Weblate (Turkish)
Currently translated at 100.0% (486 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-03 23:58:52 +01:00
Allan Nordhøy
ce49aa2ebd Translated using Weblate (Norwegian Bokmål)
Currently translated at 70.7% (344 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-12-03 23:58:51 +01:00
Eric
f2cb062b1e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (486 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-03 23:58:50 +01:00
Ihor Hordiichuk
f25819a940 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (486 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-03 23:58:50 +01:00
Kunzisoft
3075a9f9f4 Translated using Weblate (Japanese)
Currently translated at 96.0% (467 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-12-03 23:58:49 +01:00
Kunzisoft
52f1a672c8 Translated using Weblate (French)
Currently translated at 100.0% (486 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-03 23:58:49 +01:00
Retrial
45785fde1c Translated using Weblate (Greek)
Currently translated at 96.0% (467 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-12-03 23:58:49 +01:00
J-Jamet
6a7649e1d7 Tooltips for Magikeyboard #586 2020-12-03 23:56:42 +01:00
J-Jamet
8b3831eb2b Move OTP button to the first view level in Magikeyboard #587 2020-12-03 23:21:59 +01:00
J-Jamet
73e7f4669c Remove lifecycle observer import 2020-12-03 15:45:03 +01:00
J-Jamet
c9f7bbbd25 Remove default database parameter when the file is no longer accessible #803 2020-12-03 15:41:13 +01:00
solokot
ee67238133 Translated using Weblate (Russian)
Currently translated at 100.0% (486 of 486 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-03 08:23:35 +01:00
J-Jamet
b425da8d0f Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-12-02 13:45:08 +01:00
J-Jamet
754a7f70bc Remove unused translation 2020-12-02 13:22:18 +01:00
Oğuz Ersen
a857ffa987 Translated using Weblate (Turkish)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-02 13:12:41 +01:00
Kunzisoft
391ce2ebba Translated using Weblate (Galician)
Currently translated at 6.4% (31 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/gl/
2020-12-02 13:12:40 +01:00
Wilker Santana da Silva
086723adf4 Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 13:12:40 +01:00
Kunzisoft
e993279c35 Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 13:12:40 +01:00
Ihor Hordiichuk
aa64310875 Translated using Weblate (Ukrainian)
Currently translated at 99.3% (480 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-02 13:12:39 +01:00
Kunzisoft
795baf2c01 Translated using Weblate (Slovak)
Currently translated at 17.8% (86 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sk/
2020-12-02 13:12:39 +01:00
solokot
68ac453100 Translated using Weblate (Russian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-02 13:12:39 +01:00
Kunzisoft
79d1f512e5 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 14.9% (72 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nn/
2020-12-02 13:12:39 +01:00
Kunzisoft
e739211314 Translated using Weblate (Latvian)
Currently translated at 14.6% (71 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lv/
2020-12-02 13:12:38 +01:00
HARADA Hiroyuki
d3f6374bb4 Translated using Weblate (Japanese)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-12-02 13:12:38 +01:00
Kunzisoft
5add632cbc Translated using Weblate (Hebrew)
Currently translated at 13.8% (67 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/he/
2020-12-02 13:12:38 +01:00
Kunzisoft
d210d1bcce Translated using Weblate (French)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-02 13:12:38 +01:00
J-Jamet
6d6422cd63 Merge branch 'translations' into develop 2020-12-02 10:06:28 +01:00
J-Jamet
66e8b7702b Default backup API key to unused 2020-12-02 09:54:47 +01:00
J-Jamet
b75502ad87 Replace strong tag 2020-12-02 09:41:17 +01:00
J-Jamet
3fba96d11f Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-12-02 09:39:11 +01:00
J-Jamet
58d10672ea First implementation 2020-12-02 09:28:44 +01:00
Kunzisoft
3571905705 Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 09:15:20 +01:00
vachan-maker
acf0e2a1cb Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 09:15:19 +01:00
Wilker Santana da Silva
9e7dcb0d7c Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 09:15:19 +01:00
Kunzisoft
3c261e3cf7 Deleted translation using Weblate (Abkhazian) 2020-12-02 08:54:49 +01:00
x
b6f324f399 Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
Kunzisoft
f2459489fa Translated using Weblate (Turkish)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-02 08:38:03 +01:00
Kunzisoft
f8691cf285 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-02 08:38:03 +01:00
Ihor Hordiichuk
2e631d3c42 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-02 08:38:03 +01:00
Filippo De Bortoli
1044dca936 Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
x
56c3f495d5 Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
x
0f3036dd9c Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
Filippo De Bortoli
af445ef157 Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
Kunzisoft
25eb09f11c Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 08:38:03 +01:00
Oğuz Ersen
16f255aeca Translated using Weblate (Turkish)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-02 08:38:03 +01:00
Jennifer Kitts
d0b340837d Translated using Weblate (English)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-12-02 08:38:03 +01:00
Eric
893828ac44 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-02 08:38:03 +01:00
Ihor Hordiichuk
a3ca03636a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-02 08:38:03 +01:00
WaldiS
582ffe3f23 Translated using Weblate (Polish)
Currently translated at 99.5% (481 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-12-02 08:38:03 +01:00
Milo Ivir
3caad2cceb Translated using Weblate (Croatian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-12-02 08:38:03 +01:00
Jennifer Kitts
618dcf014d Added translation using Weblate (Abkhazian) 2020-12-02 08:38:03 +01:00
zeritti
d88e20bb56 Translated using Weblate (Czech)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-12-02 08:38:03 +01:00
Miguel
8a8b2b027e Translated using Weblate (Portuguese (Portugal))
Currently translated at 94.8% (458 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-12-02 08:38:03 +01:00
Bruno Guerreiro
41cb223099 Translated using Weblate (Portuguese (Portugal))
Currently translated at 94.8% (458 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-12-02 08:38:03 +01:00
J. Lavoie
b93ea5e662 Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
J. Lavoie
31c35939fd Translated using Weblate (French)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-12-02 08:38:03 +01:00
J. Lavoie
20a35f4221 Translated using Weblate (Finnish)
Currently translated at 60.0% (290 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fi/
2020-12-02 08:38:03 +01:00
C. Rüdinger
bc6aeb2e93 Translated using Weblate (German)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-02 08:38:03 +01:00
J. Lavoie
a561299809 Translated using Weblate (German)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-02 08:38:03 +01:00
Filippo De Bortoli
76efb938ab Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
Filippo De Bortoli
56abf73eaf Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
J. Lavoie
2bc068d65a Translated using Weblate (Italian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-12-02 08:38:03 +01:00
J. Lavoie
f191259f37 Translated using Weblate (German)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-02 08:38:03 +01:00
C. Rüdinger
1384c6661d Translated using Weblate (German)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-12-02 08:38:03 +01:00
Oğuz Ersen
c047621548 Translated using Weblate (Turkish)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-12-02 08:38:03 +01:00
Eric
017aaf2e54 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-12-02 08:38:03 +01:00
Ihor Hordiichuk
e4b2b930af Translated using Weblate (Ukrainian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-12-02 08:38:03 +01:00
solokot
2646c0f0ee Translated using Weblate (Russian)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-12-02 08:38:03 +01:00
HARADA Hiroyuki
4afadb779c Translated using Weblate (Japanese)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-12-02 08:38:03 +01:00
Retrial
ad6e4daa22 Translated using Weblate (Greek)
Currently translated at 100.0% (483 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-12-02 08:38:03 +01:00
jan madsen
d5cd07fe76 Translated using Weblate (Danish)
Currently translated at 98.7% (477 of 483 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-12-02 08:38:03 +01:00
abidin toumi
364065ed51 Translated using Weblate (Arabic)
Currently translated at 74.6% (360 of 482 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-12-02 08:38:03 +01:00
Stephan Paternotte
b4f05d4da7 Translated using Weblate (Dutch)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-12-02 08:38:03 +01:00
J-Jamet
3d12a0e8e9 Fix fingerprint none enrolled detection 2020-12-01 13:48:08 +01:00
J-Jamet
e29f3194f3 Upgrade to 2.9.3 and update CHANGELOG 2020-11-30 17:50:47 +01:00
J-Jamet
6bac86638b Change fingerprint pref icon by a bolt 2020-11-30 17:45:58 +01:00
J-Jamet
d6ee1cdf6e Merge branch 'feature/Device_Credential_Unlock' into develop #779 2020-11-30 17:24:59 +01:00
J-Jamet
e9d0efaf93 Fix advanced unlock setting events 2020-11-30 17:20:58 +01:00
J-Jamet
85467fa15b Change biometric to advanced unlock 2020-11-30 13:56:14 +01:00
J-Jamet
84bb47aa53 Better unlock settings 2020-11-23 20:47:50 +01:00
J-Jamet
75f245c7dc Add device credential unlock 2020-11-23 19:14:44 +01:00
J-Jamet
6c5be88432 Fix biometric error message when the keystore is not accessible 2020-11-23 16:52:36 +01:00
J-Jamet
590b22de69 Merge tag '2.9.2' into develop
2.9.2
2020-11-22 20:37:23 +01:00
J-Jamet
4770269f6f Merge branch 'release/2.9.2' 2020-11-22 20:37:14 +01:00
J-Jamet
823f591aa8 Fix small UI issue 2020-11-22 20:06:39 +01:00
J-Jamet
c88c489633 Maximal search elements to 10 #793 2020-11-22 19:06:35 +01:00
J-Jamet
8afb58a044 Fix translations 2020-11-22 18:32:48 +01:00
J-Jamet
428fa8a61b Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-11-22 18:15:31 +01:00
J-Jamet
3ba5e1ee79 Upgrade gradle and libs 2020-11-21 19:09:54 +01:00
J-Jamet
d46d0cb384 Better custom field name verification #718 2020-11-21 17:20:54 +01:00
J-Jamet
f841884557 Fix first custom field #718 2020-11-21 17:06:43 +01:00
J-Jamet
d381ab5316 Merge branch 'master' into develop 2020-11-21 14:20:13 +01:00
J-Jamet
a3e8e7ae77 Remove not required files 2020-11-21 14:19:40 +01:00
Jérémy JAMET
a405753827 Licensing organization 2020-11-21 14:11:23 +01:00
J-Jamet
8df74d2c4b Harmonization of KeePass names 2020-11-21 11:51:20 +01:00
J-Jamet
cbe0ffe52a 2 lines to show title in lists #534 #617 2020-11-20 20:09:47 +01:00
J-Jamet
a5631a0476 Fix read only #792 2020-11-20 18:36:44 +01:00
Michal Čihař
e4bd704a53 Deleted translation using Weblate (_EN (generated)) 2020-11-19 12:57:02 +01:00
J-Jamet
81a53440bc Change database edition color #719 2020-11-19 11:57:46 +01:00
J-Jamet
3466de1990 Update CHANGELOG 2020-11-19 11:38:08 +01:00
J-Jamet
253b053c2c Different channels for each type of notification #688 2020-11-19 11:31:03 +01:00
Aman Alam
928d012046 Translated using Weblate (Punjabi)
Currently translated at 74.4% (359 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2020-11-18 21:28:54 +01:00
Ihor Hordiichuk
19367406c6 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-11-18 21:28:52 +01:00
Balázs Meskó
f4e3717dd3 Translated using Weblate (Hungarian)
Currently translated at 93.3% (450 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2020-11-18 21:28:52 +01:00
Retrial
c01e1d91c5 Translated using Weblate (Greek)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-11-18 21:28:51 +01:00
J-Jamet
6983f9f0b6 Harmonization of field names #789 2020-11-18 20:23:05 +01:00
J-Jamet
c13cf1a86c Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-11-18 19:40:14 +01:00
J-Jamet
2a3dafe07f Prevent manual creation of existing field name #718 2020-11-18 19:39:53 +01:00
vachan-maker
0104d02442 Translated using Weblate (Malayalam)
Currently translated at 82.5% (398 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-11-16 07:28:51 +01:00
solokot
8cef4fde82 Translated using Weblate (Russian)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-11-13 15:17:29 +01:00
J-Jamet
3dc02516ea Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-11-13 10:03:45 +01:00
J-Jamet
3614529fda Add new browsers to Autofill compatibility list #769 2020-11-13 10:03:36 +01:00
Jennifer Kitts
80d4f06e56 Added translation using Weblate (_EN (generated)) 2020-11-13 06:22:19 +01:00
J-Jamet
9ff4f395b5 Merge branch 'feature/OTP_Links' into develop 2020-11-12 15:15:43 +01:00
J-Jamet
61b8fa116a Fix small chars issue 2020-11-12 15:14:14 +01:00
J-Jamet
22a3541b7b Auto populate Title and Username from OTP Auth 2020-11-12 15:08:27 +01:00
J-Jamet
c57515fed5 Fix small OTP Auth syntax #556 2020-11-12 14:59:39 +01:00
J-Jamet
eec6199413 Fix decoding OTP Auth #556 2020-11-12 14:39:33 +01:00
J-Jamet
fe48955b94 Check OTP Auth URI #556 2020-11-12 13:19:05 +01:00
J-Jamet
03047ae6dd Replace OTP when already exists #556 2020-11-12 12:30:25 +01:00
J-Jamet
856d4867b4 Manage OTP links #556 2020-11-10 15:00:42 +01:00
J-Jamet
b1b1aa0e13 Change behavior #783 2020-11-10 13:05:07 +01:00
WaldiS
ab68472698 Translated using Weblate (Polish)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-11-09 21:22:11 +01:00
J-Jamet
5ae4ee1411 Fix switch back to previous keyboard #782 2020-11-09 17:04:43 +01:00
Aman Alam
f1989bac21 Translated using Weblate (Punjabi)
Currently translated at 62.8% (303 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2020-11-09 14:19:18 +01:00
J-Jamet
1b20188b98 Fix links in pro description #771 2020-11-09 14:14:09 +01:00
J-Jamet
140a79d18c Fix same save shared info #783 2020-11-09 11:53:42 +01:00
J-Jamet
a9610ced0e Fix empty OTP field after selection #781 2020-11-09 11:07:23 +01:00
J-Jamet
17faee7719 Fix search in OTP #780 2020-11-09 10:30:58 +01:00
jan madsen
120ca1c02c Translated using Weblate (Danish)
Currently translated at 94.3% (455 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-11-07 20:52:16 +01:00
Srdjan Todorovic
ef2d1ebe4f Translated using Weblate (Serbian (latin))
Currently translated at 54.7% (264 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sr_Latn/
2020-11-06 22:21:23 +01:00
Milo Ivir
b9c931c97f Translated using Weblate (Croatian)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-11-06 22:21:18 +01:00
Milo Ivir
60dd963d7d Translated using Weblate (German)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-11-06 22:21:18 +01:00
J-Jamet
c414fac815 Change default AES Key rounds to 500000 2020-11-06 13:08:46 +01:00
Srdjan Todorovic
95041d6a0c Translated using Weblate (Serbian (latin))
Currently translated at 3.3% (16 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sr_Latn/
2020-11-04 19:27:07 +01:00
Oğuz Ersen
1fab9c3279 Translated using Weblate (Turkish)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-11-04 19:27:06 +01:00
Eric
3b8661249e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-11-04 19:27:05 +01:00
Ihor Hordiichuk
2fba831851 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-11-04 19:27:03 +01:00
solokot
fd4ac14ab3 Translated using Weblate (Russian)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-11-04 19:27:03 +01:00
HARADA Hiroyuki
1d9b9e9bfa Translated using Weblate (Japanese)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-11-04 19:27:02 +01:00
Kunzisoft
14b2277313 Translated using Weblate (French)
Currently translated at 100.0% (482 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-11-04 19:27:02 +01:00
nautilusx
0f57bf5235 Translated using Weblate (German)
Currently translated at 98.3% (474 of 482 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-11-04 19:26:59 +01:00
J-Jamet
4bb7fae1e3 Upgrade to version 2.9.2 2020-11-03 12:28:04 +01:00
J-Jamet
ec0b8ebc92 Merge tag '2.9.1' into develop
2.9.1
2020-11-03 12:17:23 +01:00
J-Jamet
1727633f5d Merge branch 'release/2.9.1' 2020-11-03 12:17:15 +01:00
J-Jamet
668a77cb5a Remove empty string resources 2020-11-03 12:00:31 +01:00
J-Jamet
e87ee5e091 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-11-03 11:57:10 +01:00
J-Jamet
b7acc0e6da Update CHANGELOG 2020-11-02 22:15:22 +01:00
J-Jamet
109f34680f Fix crash in Android 21/23 #774 2020-11-02 21:20:15 +01:00
J-Jamet
fd57ccc1a7 Copy password from generator #697 2020-11-02 17:31:35 +01:00
J-Jamet
e3dfae246a Fix change font size #770 2020-11-02 16:52:59 +01:00
Srdjan Todorovic
7186bbbe6c Added translation using Weblate (Serbian (latin)) 2020-11-02 15:06:36 +01:00
J-Jamet
c7b2ce37b1 Update CHANGELOG 2020-11-02 13:42:24 +01:00
J-Jamet
5b3a602911 Replace constraint layout by linear layout to fix crop #772 2020-11-02 13:38:54 +01:00
J-Jamet
6d51edd94d Upgrade CHANGELOG 2020-11-02 12:45:16 +01:00
J-Jamet
dcb68a6538 Fix full description links #771 2020-11-02 12:39:13 +01:00
J-Jamet
d549b86c81 Upgrade to version 2.9.1 2020-11-01 20:54:53 +01:00
J-Jamet
ac415f1384 Remove files after deploy pro 2020-11-01 20:52:25 +01:00
Hosted Weblate
80ed5800a0 Merge branch 'origin/master' into Weblate. 2020-11-01 20:38:50 +01:00
J-Jamet
291ed44621 Fix fastlane metadata 2020-11-01 20:30:50 +01:00
J-Jamet
a7e8915ea0 Merge tag '2.9' into develop
2.9
2020-11-01 19:44:36 +01:00
J-Jamet
a027c76af3 Merge branch 'release/2.9' 2020-11-01 19:44:28 +01:00
J-Jamet
ec375bd068 Fix subDomain when WebDomain is an IP #767 2020-11-01 15:24:16 +01:00
J-Jamet
f5a28c83f0 Check opening database in read only to saving data 2020-11-01 12:52:02 +01:00
J-Jamet
813240e233 Allow IP addresses instead of strict WebDomain #767 2020-11-01 11:43:16 +01:00
J-Jamet
051ac0e669 Fix discard entry edition in registration mode 2020-11-01 11:23:31 +01:00
J-Jamet
5c798c4569 Fix search domain in open database 2020-11-01 11:11:03 +01:00
Jennifer Kitts
cc2146e397 Added translation using Weblate (English (Developer)) 2020-11-01 02:32:59 +01:00
J-Jamet
8356514bf8 Replace <strong> tags 2020-10-31 18:31:05 +01:00
J-Jamet
464bc10860 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations
# Conflicts:
#	app/src/main/res/values-el/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-fr/strings.xml
2020-10-31 18:21:36 +01:00
J-Jamet
5436c8bed1 Save scheme in WebDomain 2020-10-31 17:55:58 +01:00
J-Jamet
1b163b161b To ask data lost only one time 2020-10-31 17:22:28 +01:00
J-Jamet
f0ee5fd946 Fix read only for registration 2020-10-31 14:48:33 +01:00
J-Jamet
066a9f871c Set entry result in EntryEditActivity only if requested by the caller 2020-10-30 15:15:38 +01:00
J-Jamet
e23841f5bb Fix lock database after autofill 2020-10-30 15:10:35 +01:00
J-Jamet
571e66fae5 Fix registration callback, to upgrade with #765 2020-10-30 12:45:21 +01:00
J-Jamet
402aa280e0 Upgrade ContraintLayout lib and fix custom edit field 2020-10-30 11:47:42 +01:00
J-Jamet
65de5df319 Change UI to prevent unwanted manual file deletion 2020-10-30 11:34:53 +01:00
J-Jamet
63168afc85 Small UI fix when file modification hidden 2020-10-29 13:48:20 +01:00
J-Jamet
1c61f54df6 Fix expand file info view 2020-10-29 13:33:49 +01:00
J-Jamet
50b5ad1799 Fix setting color 2020-10-29 11:43:08 +01:00
J-Jamet
6457c02a35 Upgrade core lib 2020-10-29 09:20:55 +01:00
J-Jamet
7b242c9733 Links to open external applications 2020-10-28 18:20:53 +01:00
J-Jamet
e0ab6137e7 Fix search info field value in WebDomain[x] 2020-10-28 16:39:51 +01:00
J-Jamet
49b23a33e7 Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop
# Conflicts:
#	app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt
#	app/src/main/java/com/kunzisoft/keepass/biometric/AdvancedUnlockedManager.kt
2020-10-28 15:18:11 +01:00
J-Jamet
c5e9d14199 Fix special modes and add search/save modes 2020-10-27 16:01:40 +01:00
J-Jamet
f7e8662bdf Fix search info 2020-10-26 18:49:37 +01:00
J-Jamet
7d356d1e34 Fix magikeyboard selection 2020-10-26 18:26:14 +01:00
J-Jamet
f9bb70f395 Fix autofill response 2020-10-26 16:06:43 +01:00
Aman ALam
4335809468 Translated using Weblate (Punjabi)
Currently translated at 61.9% (285 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2020-10-25 18:26:51 +01:00
Vibo Lavida
2a1b1d28bd Translated using Weblate (Spanish)
Currently translated at 83.4% (384 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-10-25 18:26:50 +01:00
J-Jamet
38d69428d8 Merge branch 'hokonch-i18n-ja' into develop 2020-10-25 18:01:20 +01:00
J-Jamet
0c22a8135d Merge branch 'i18n-ja' of git://github.com/hokonch/KeePassDX into hokonch-i18n-ja 2020-10-25 18:00:57 +01:00
J-Jamet
2b50665f9e Merge branch 'teemue-patch-1' into develop 2020-10-25 17:51:49 +01:00
J-Jamet
59607efa62 Fix backup search #759 2020-10-25 17:48:16 +01:00
J-Jamet
cd5cfbe009 Fix logo in password UI 2020-10-25 16:17:43 +01:00
J-Jamet
84e6d96ce0 Fix logo in password UI 2020-10-25 15:58:06 +01:00
hokonch
8f00b53fab Reorder and update strings (ja) 2020-10-25 12:59:56 +09:00
hokonch
e2164a1a9c Add fastlane screenshots (ja) 2020-10-25 12:59:56 +09:00
hokonch
6e5dcaf08d Add fastlane descriptions (ja) 2020-10-25 12:59:35 +09:00
J-Jamet
18a2aae66a Rollback password UI and add logotype 2020-10-23 23:10:50 +02:00
J-Jamet
4c0aab15fa Fix biometric state and string 2020-10-23 17:44:24 +02:00
J-Jamet
75a7d4188b Fix biometric education hint 2020-10-23 16:59:51 +02:00
J-Jamet
ff0da57aeb Fix crash in KitKat 2020-10-23 16:37:57 +02:00
J-Jamet
d716cba46b Fix password view in landscape 2020-10-23 16:00:39 +02:00
J-Jamet
5d41e44141 Change password layout to fix biometric view flickering 2020-10-23 14:54:07 +02:00
J-Jamet
281936ecd0 Fix biometric view flickering 2020-10-23 13:13:12 +02:00
J-Jamet
da23321c0d Add mozilla license and upgrade CHNAGELOG 2020-10-23 10:01:12 +02:00
J-Jamet
110e2b7580 Fix subdomain search #728 2020-10-22 21:16:44 +02:00
SeerLite
546d4353e2 Translated using Weblate (Spanish)
Currently translated at 76.9% (354 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-10-22 16:26:54 +02:00
Vibo Lavida
15b5d36cd6 Translated using Weblate (Spanish)
Currently translated at 76.9% (354 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-10-22 16:26:54 +02:00
J-Jamet
6a935a49ea Setting to hide UUID #757 2020-10-21 21:28:52 +02:00
J-Jamet
f7f515481f Fix biometric flickering 2020-10-19 17:26:13 +02:00
J-Jamet
3aab37c0c0 Refactor biometric variables 2020-10-19 17:20:29 +02:00
J-Jamet
123e626df6 Fix onValidateSpecialMode() 2020-10-19 16:53:44 +02:00
J-Jamet
758985675d Encapsulate activities launch methods 2020-10-19 16:51:23 +02:00
J-Jamet
631ebc657b Fix special mode in app background 2020-10-19 16:01:11 +02:00
J-Jamet
d0ca714482 Setting to switch keyboard when database is locked #625 2020-10-19 15:04:12 +02:00
J-Jamet
1fe3787186 Fix keyboard selection 2020-10-19 14:24:12 +02:00
J-Jamet
c8a952616f Setting to close database after Autofill selection #755 2020-10-19 14:10:16 +02:00
J-Jamet
efcbecc218 Fix load database when launch autofill or share in background #738 2020-10-19 12:45:34 +02:00
J-Jamet
487bafa5cf Fix biometric prompt auto opened #738 2020-10-19 12:26:07 +02:00
teemue
93aed33e2a Update fi translation
Typo fixes
2020-10-18 17:28:05 +03:00
J-Jamet
a7765cb635 Fix warning at emptying recycle bin #742 2020-10-18 13:24:47 +02:00
J-Jamet
e6a5be6c66 Save new credentials with Autofill #524 2020-10-18 12:58:22 +02:00
Devin Williams
5443532266 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 15.8% (73 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nn/
2020-10-17 22:26:42 +02:00
J-Jamet
990aca2e1a Merge branch 'feature/Autofill_Save' into develop #524 2020-10-17 16:18:40 +02:00
J-Jamet
49297adf97 Fix read only mode and back pressed 2020-10-17 15:35:01 +02:00
J-Jamet
b4d26fd35a Manually save search in selection mode 2020-10-16 15:40:01 +02:00
J-Jamet
b31f580760 Save web scheme to save URL 2020-10-16 12:39:30 +02:00
José Elias Júnior
7dc33f1956 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2020-10-15 01:49:34 +02:00
Éfrit
e3470dd68b Translated using Weblate (French)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-10-15 01:49:33 +02:00
J-Jamet
410c653654 Fix save last access time 2020-10-13 15:04:59 +02:00
J-Jamet
bef3cf4c93 Fix save search info 2020-10-13 15:04:12 +02:00
J-Jamet
d8961d2acb Save search info settings 2020-10-13 14:20:12 +02:00
J-Jamet
17873ef7aa Merge branch 'develop' into feature/Autofill_Save 2020-10-13 12:55:05 +02:00
random r
1d6e7eabc1 Translated using Weblate (Italian)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-10-13 12:26:41 +02:00
J-Jamet
ba956abb1c Fix populate custom field in KDB database 2020-10-12 22:33:57 +02:00
J-Jamet
7a2c2df89e Change app caller in special mode, remove home button from regular toolbar in special mode 2020-10-12 21:59:12 +02:00
J-Jamet
bd44e659a8 Add verification to save data 2020-10-12 15:47:28 +02:00
J-Jamet
8a1a27f5a1 Fix callback result 2020-10-12 15:40:40 +02:00
J-Jamet
7825071f61 Fix keyboard selection result 2020-10-12 15:04:17 +02:00
J-Jamet
7047bcbb1e Register username and password in entry 2020-10-12 14:24:52 +02:00
J-Jamet
193ef74e63 Register WebDomain or ApplicationId 2020-10-12 12:50:14 +02:00
Jennifer Kitts
8a193d4dcd Added translation using Weblate (English (United States)) 2020-10-10 17:22:00 +02:00
marklin0913da248e4cdada422a
35cc662b26 Translated using Weblate (Chinese (Traditional))
Currently translated at 65.4% (301 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2020-10-10 16:26:41 +02:00
J-Jamet
9173bcc742 Fix biometric authentication when weak security is not present 2020-10-08 23:17:36 +02:00
J-Jamet
267f4273ee Try to add new biometric states from the doc #724 2020-10-08 23:10:28 +02:00
J-Jamet
f1e675d662 Upgrade biometric lib to 1.1.0-beta01 #724 2020-10-08 22:28:20 +02:00
J-Jamet
c228534218 Merge branch 'hbiel-feature/api-upgrade-icon-packs' into develop 2020-10-08 22:13:44 +02:00
J-Jamet
181fa5f32a Create registration mode 2020-10-08 21:58:32 +02:00
hbiel
7d5c37ec33 upgrade icon packs to API 30 2020-10-08 21:16:10 +02:00
J-Jamet
2eb9736d23 Merge branch 'develop' into feature/Autofill_Save 2020-10-08 18:16:21 +02:00
Allan Nordhøy
9f89ad2a08 Translated using Weblate (Indonesian)
Currently translated at 50.4% (232 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2020-10-08 07:26:12 +02:00
J-Jamet
490db3a026 Add a lock to fix autofill in Firefox #725 2020-10-07 16:23:54 +02:00
J-Jamet
2428f073bc Update CHANGELOG 2020-10-07 13:46:43 +02:00
J-Jamet
e1231585ce Merge branch 'develop' into feature/Autofill_Save 2020-10-07 13:39:36 +02:00
J-Jamet
839adaf559 Merge branch 'feature/BIOMETRIC_SECURITY' into develop 2020-10-07 13:38:51 +02:00
J-Jamet
839e004c08 Merge branch 'develop' into feature/Autofill_Save 2020-10-07 13:38:04 +02:00
J-Jamet
ecf98828ff Merge branch 'jdambron-add-missing-French-translation' into develop 2020-10-07 13:35:37 +02:00
J-Jamet
4dbc3c2353 Merge branch 'develop' of git://github.com/wishawa/KeePassDX into wishawa-develop 2020-10-07 13:33:24 +02:00
J-Jamet
c953a337fe Setting to disable save autofill data 2020-10-05 20:39:33 +02:00
J-Jamet
6f026e6043 Merge branch 'develop' into feature/Autofill_Save 2020-10-05 19:31:11 +02:00
J-Jamet
a775e29aef Fix webDomain with Autofill compatibility mode #551 2020-10-05 19:29:19 +02:00
J-Jamet
cb7b37fca4 Fix crash in autofill save workflow 2020-10-05 18:12:30 +02:00
arwansel
cc79a67a9f Translated using Weblate (Indonesian)
Currently translated at 50.4% (232 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2020-10-05 12:35:31 +02:00
Lucas Nunes
72e7e3a3c4 Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.3% (457 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2020-10-05 12:35:29 +02:00
ssantos
4ffbeebd85 Translated using Weblate (Portuguese)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt/
2020-10-02 23:35:38 +02:00
abidin toumi
2e4b4e4736 Translated using Weblate (Arabic)
Currently translated at 77.3% (356 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-10-02 23:35:37 +02:00
Retrial
a0acb0b658 Translated using Weblate (Greek)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-10-02 23:34:57 +02:00
cloudy-dev
feeaea4d64 Translated using Weblate (German)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-10-02 23:34:56 +02:00
Wisha Wa
0b7eb96e48 Use textNoSuggestions type for username input instead. 2020-10-02 06:48:43 +00:00
jdambron
f0c4b628bf Add missing French translations 2020-10-02 08:28:12 +02:00
J-Jamet
c66fc102ee First commit for save 2020-10-01 18:55:29 +02:00
J-Jamet
9947a23343 Try to fix add/update database history #732 2020-10-01 12:47:52 +02:00
J-Jamet
abc204b313 Replace Toast by Log.e 2020-09-30 22:47:20 +02:00
J-Jamet
425a0812bd Try to fix variable BIOMETRIC_STRONG recognition #724 2020-09-30 19:55:43 +02:00
J-Jamet
030d466b11 Try to fix variable BIOMETRIC_STRONG recognition #724 2020-09-30 15:58:12 +02:00
J-Jamet
27e9cd04a9 Fix password activity education exception 2020-09-29 22:32:18 +02:00
J-Jamet
e42aea9444 Fix biometric button animation after key deletion 2020-09-29 17:34:10 +02:00
J-Jamet
3e1ee720f1 Fix biometric button animation after key deletion 2020-09-29 17:13:18 +02:00
J-Jamet
cb9f12482e Fix biometric clear button menu 2020-09-29 16:47:02 +02:00
J-Jamet
bcf273a435 Fix button state after clearing key 2020-09-29 16:35:56 +02:00
J-Jamet
6230ada2cc Upgrade biometric lib to 1.1.0-alpha02
Use BIOMETRIC_STRONG option
Fix biometricPrompt opening after clearing key
2020-09-29 16:21:32 +02:00
J-Jamet
db4de65683 Refactor canAuthenticate 2020-09-29 15:12:32 +02:00
J-Jamet
931f7f07ca Update CHANGELOG 2020-09-29 13:37:40 +02:00
J-Jamet
0f764c9400 Fix text size 2020-09-29 13:30:21 +02:00
J-Jamet
89c98ab257 Add variable 'm' suffix 2020-09-29 13:13:19 +02:00
J-Jamet
a49255c471 Fix crash with API 30 #723 2020-09-29 13:10:24 +02:00
J-Jamet
39d5a4908f Upgrade to version 2.9 2020-09-29 12:46:39 +02:00
J-Jamet
fbaeaddff7 Upgrade to API 30 2020-09-29 12:44:51 +02:00
abidin toumi
bc97db982e Translated using Weblate (Arabic)
Currently translated at 69.3% (319 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-09-29 11:40:10 +02:00
abidin toumi
9a2f260bc5 Translated using Weblate (Arabic)
Currently translated at 66.0% (304 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-09-28 11:41:00 +02:00
vachan-maker
954f1e3c7f Translated using Weblate (Malayalam)
Currently translated at 83.2% (383 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-09-27 11:01:07 +02:00
abidin toumi
0626f8d678 Translated using Weblate (Arabic)
Currently translated at 61.9% (285 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-09-27 11:01:06 +02:00
WaldiS
aa8c9676fe Translated using Weblate (Polish)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-09-27 11:01:06 +02:00
Kornelijus Tvarijanavičius
bb2ab768a8 Translated using Weblate (Lithuanian)
Currently translated at 16.7% (77 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lt/
2020-09-27 11:01:05 +02:00
J-Jamet
8192c68f38 Merge tag '2.8.7' into develop
2.8.7
2020-09-26 10:31:54 +02:00
J-Jamet
454561c2a1 Merge branch 'release/2.8.7' 2020-09-26 10:31:47 +02:00
J-Jamet
deabcc9605 Update CHANGELOG and version to 2.8.7 2020-09-26 10:22:00 +02:00
J-Jamet
c3bdb9dd16 Downgrade to API 29 #722 2020-09-26 10:17:19 +02:00
J-Jamet
86d77c908f Merge tag '2.8.6' into develop
2.8.6
2020-09-25 22:18:25 +02:00
J-Jamet
c5cbba5971 Merge branch 'release/2.8.6' 2020-09-25 22:18:16 +02:00
J-Jamet
aea5493180 Small change when write inner random stream id 2020-09-25 21:40:58 +02:00
J-Jamet
431832e50e Downgrade constaintLayout to fix extra field 2020-09-25 21:00:04 +02:00
J-Jamet
daf239c93c Fix autolink #720 2020-09-25 20:41:24 +02:00
J-Jamet
2c669deae5 Add writeByte method in LittleEndianDataOutputStream 2020-09-25 19:34:02 +02:00
J-Jamet
81969de76e Write UInt size 2020-09-25 19:23:05 +02:00
J-Jamet
5a29e7a83e Replace strong tag 2020-09-25 18:57:45 +02:00
J-Jamet
9ed5aef40f Fix strings 2020-09-25 18:56:32 +02:00
J-Jamet
9e025b4329 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-09-25 18:47:51 +02:00
J-Jamet
543da4fe24 Fix write custom data #651 2020-09-25 18:31:30 +02:00
J-Jamet
e82e50a57a Refactor VariantDictionary serializer 2020-09-25 18:16:23 +02:00
Martin
288d62d666 Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-25 17:40:58 +02:00
zeritti
8ed224eeab Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-25 17:40:58 +02:00
J-Jamet
22bafff943 Update CHANGELOG 2020-09-25 16:30:11 +02:00
J-Jamet
02403cf566 Fix dialog background #717 2020-09-25 16:28:48 +02:00
J-Jamet
eabbc6f037 Refactor binary write in header 2020-09-24 19:01:21 +02:00
J-Jamet
27e60edaf4 Fix check create button visibility 2020-09-24 18:43:43 +02:00
J-Jamet
f7d0b64dea Small changes 2020-09-24 18:07:58 +02:00
J-Jamet
b874484101 Refactor binary protection 2020-09-24 17:51:05 +02:00
Martin
0ee72db2e9 Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-24 17:00:09 +02:00
zeritti
4f07bac9ec Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-24 17:00:09 +02:00
Martin
80abaf70f2 Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-24 16:59:24 +02:00
zeritti
d6acbc2fb1 Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-24 16:59:24 +02:00
J-Jamet
caf93c019a Add Looper in Handler 2020-09-24 14:28:12 +02:00
J-Jamet
7044efa7c3 Upgrade compilation version 2020-09-24 12:17:55 +02:00
J-Jamet
5b4d8f971f Fix string 2020-09-24 12:12:27 +02:00
J-Jamet
75e8feb9b8 Change yes -> ok, no -> cancel 2020-09-24 12:10:44 +02:00
J-Jamet
5d59419a06 Fix autofill domain with Android 11 #702 2020-09-24 11:48:42 +02:00
J-Jamet
ff2e47bf70 Change version to 2.8.6 2020-09-24 09:25:31 +02:00
ssantos
4721ed7c15 Translated using Weblate (Portuguese)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt/
2020-09-23 18:41:05 +02:00
Zidan Pragata
d9da328088 Translated using Weblate (Indonesian)
Currently translated at 44.3% (204 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2020-09-23 18:40:58 +02:00
Milo Ivir
2ee506ac06 Translated using Weblate (Croatian)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-09-23 18:40:58 +02:00
ssantos
16c4e4dc5b Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-09-23 18:40:57 +02:00
J-Jamet
28b8fb1b97 Update CHANGELOG 2020-09-23 17:16:30 +02:00
J-Jamet
c8bae9fba6 Fix binaries unique Ids #713 2020-09-23 17:15:45 +02:00
J-Jamet
920764ad33 Fix binaries unique Ids #713 2020-09-23 17:07:15 +02:00
J-Jamet
a45d114527 Add toString() for BinaryPool 2020-09-23 16:47:10 +02:00
J-Jamet
62cca09045 Change length binary method 2020-09-23 16:46:31 +02:00
J-Jamet
ea126b90e2 Revert "Revert "Early return in readHeaderField" #713"
This reverts commit 777a20182e.
2020-09-23 13:13:22 +02:00
J-Jamet
777a20182e Revert "Early return in readHeaderField" #713
This reverts commit f2150e3d85.
2020-09-23 12:21:06 +02:00
J-Jamet
df62a9d32b Binary dir as no backup 2020-09-23 11:35:20 +02:00
ssantos
47e211bf3c Added translation using Weblate (Portuguese) 2020-09-22 17:31:10 +02:00
ian Vatega
650ca3844e Added translation using Weblate (Esperanto) 2020-09-22 12:56:17 +02:00
J-Jamet
8de49fa027 Fix renaming custom field #709 2020-09-21 11:31:14 +02:00
J-Jamet
35b7633f4d Fix autofill recognition #712 and update version to 2.9 2020-09-21 10:56:09 +02:00
Oğuz Ersen
2c96a80280 Translated using Weblate (Turkish)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-09-20 12:39:55 +02:00
Eric
c7000c8ac6 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-09-20 12:39:55 +02:00
ihor_ck
1dca2b4387 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-09-20 12:39:54 +02:00
solokot
ccbe9ad21e Translated using Weblate (Russian)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-09-20 12:39:54 +02:00
Stephan Paternotte
1fe6f11ef4 Translated using Weblate (Dutch)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-09-20 12:39:54 +02:00
HARADA Hiroyuki
9d4ab60fc4 Translated using Weblate (Japanese)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-20 12:39:53 +02:00
zeritti
ea8c5ad6e1 Translated using Weblate (Czech)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-09-20 12:39:53 +02:00
Nikita Epifanov
63a0f5f91c Translated using Weblate (Russian)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-09-18 22:01:50 +02:00
J-Jamet
e8bacbdb6f Merge tag '2.8.5' into develop
2.8.5
2020-09-18 16:13:36 +02:00
J-Jamet
bcc8226ccc Merge branch 'release/2.8.5' 2020-09-18 16:13:25 +02:00
J-Jamet
ddec91a0c5 Upgrade to 2.8.5 2020-09-18 16:13:01 +02:00
J-Jamet
2c262bb29d Fix Base64 #708 2020-09-18 16:09:43 +02:00
HARADA Hiroyuki
ae0afb7b53 Translated using Weblate (Japanese)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-18 15:38:56 +02:00
HARADA Hiroyuki
84e7fe5b60 Translated using Weblate (Japanese)
Currently translated at 100.0% (460 of 460 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-18 15:08:01 +02:00
J-Jamet
ccb32b045a Merge tag '2.8.4' into develop
2.8.4
2020-09-18 14:05:31 +02:00
J-Jamet
b2e29ac4bd Merge branch 'release/2.8.4' 2020-09-18 14:05:24 +02:00
J-Jamet
7df6309a68 Update CHANGELOG 2020-09-18 13:57:05 +02:00
J-Jamet
a203ad9f64 Replace strong tag 2020-09-18 13:48:56 +02:00
J-Jamet
44d6e09337 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into develop 2020-09-18 13:44:27 +02:00
J-Jamet
7c59ec019a Add credentials information and fix small error issue in keyfile 2020-09-18 13:35:32 +02:00
J-Jamet
b457f64ec8 Fix passwordEncodingDialogFragment leak 2020-09-18 13:12:25 +02:00
J-Jamet
e152e59a61 Fix dialog leak 2020-09-18 12:55:04 +02:00
J-Jamet
2c620ad69a Add dialog for empty keyfile #679 2020-09-18 12:24:43 +02:00
J-Jamet
c08b405fc2 Remove unused dialog 2020-09-18 12:09:22 +02:00
J-Jamet
585e39c591 Open database with empty key file #679 2020-09-18 11:35:57 +02:00
J-Jamet
60e857dba9 Fix title in setting after orientation change 2020-09-17 19:33:06 +02:00
J-Jamet
9a4aa2b08f Clear listeners during fragment onDetach() 2020-09-17 19:24:39 +02:00
J-Jamet
2900b08b70 Fix OTP title and username #707 2020-09-17 19:10:26 +02:00
J-Jamet
b0936563a2 Fix upload attachment multiple times 2020-09-17 18:09:37 +02:00
J-Jamet
3d327b245a Update CHANGELOG 2020-09-17 17:39:58 +02:00
J-Jamet
9a14de3448 Add corrupted attachment icon #691 2020-09-17 17:38:29 +02:00
HARADA Hiroyuki
59f83545cf Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-17 16:24:03 +02:00
J-Jamet
d9da1ef085 Fix opening database with bad attachment #691 2020-09-17 15:59:48 +02:00
Vachan
279a27f740 Translated using Weblate (Malayalam)
Currently translated at 80.5% (364 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-09-17 09:53:01 +02:00
HARADA Hiroyuki
6ba822ee48 Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-16 19:27:58 +02:00
J-Jamet
e4445949c8 Update CHANGELOG 2020-09-16 11:39:48 +02:00
J-Jamet
8178ff583d Merge branch 'feature/Fragment_Edit_Entry' into develop #686 2020-09-16 11:36:32 +02:00
J-Jamet
0e0e19a802 Delete extra field animation 2020-09-16 11:34:01 +02:00
J-Jamet
1e2e7d841f Fix OTP generation 2020-09-15 23:22:49 +02:00
J-Jamet
263c2f00eb Fix OTP generation 2020-09-15 22:48:35 +02:00
J-Jamet
39c0b57652 Fix expire date 2020-09-15 22:42:24 +02:00
J-Jamet
677baf549c Remove unused classes 2020-09-15 22:42:08 +02:00
J-Jamet
848478c28b Remove unused code 2020-09-15 22:02:35 +02:00
J-Jamet
98ad33a589 Fix concurrent modification 2020-09-15 21:59:16 +02:00
J-Jamet
3f33733f40 Fix expiry time 2020-09-15 21:50:55 +02:00
J-Jamet
cdc4ae4fb3 Fix date instant 2020-09-15 21:35:47 +02:00
J-Jamet
3edfa8a6ce Fix entry edit education 2020-09-15 21:25:07 +02:00
J-Jamet
6e99b667af Refactor edit fragment code 2020-09-15 20:16:40 +02:00
J-Jamet
23c8735568 Try to fix leak 2020-09-15 20:12:44 +02:00
J-Jamet
f39065044f Remove unused code 2020-09-15 19:50:37 +02:00
J-Jamet
7d2ae47b0f Fix last focus 2020-09-15 19:49:20 +02:00
J-Jamet
7247de6908 Refactor fragment edit entry, using EntryInfo 2020-09-15 19:04:20 +02:00
Zidan Pragata
4c2aef8504 Translated using Weblate (Javanese)
Currently translated at 5.9% (27 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/jv/
2020-09-15 17:36:14 +02:00
Zidan Pragata
ac8717cf1f Translated using Weblate (Indonesian)
Currently translated at 40.2% (182 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2020-09-15 17:36:13 +02:00
Stephan Paternotte
7761928064 Translated using Weblate (Dutch)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-09-15 17:36:13 +02:00
HARADA Hiroyuki
198047406b Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-15 17:36:12 +02:00
J-Jamet
1d57309db9 EntryEditContentsFragment as EntryEditFragment 2020-09-15 16:56:51 +02:00
J-Jamet
07af9f36b2 Move temp entry in fragment 2020-09-15 16:50:04 +02:00
J-Jamet
d157fea9be Add fragment in edit entry 2020-09-15 14:04:48 +02:00
Zidan Pragata
7692caf622 Added translation using Weblate (Javanese) 2020-09-14 13:50:26 +02:00
J-Jamet
dc65a8823f Update CHANGELOG 2020-09-14 13:01:01 +02:00
J-Jamet
2210932fdf Fix app crash when unlocking database V1 without backup folder #692 2020-09-14 12:56:38 +02:00
J-Jamet
0cb1bf4b7f Show error when upload error 2020-09-14 12:28:02 +02:00
J-Jamet
44d175dd40 Remove unlinked data as database preference #684 2020-09-14 12:13:26 +02:00
J-Jamet
097feb6437 Move unlinked attachment callback in fragment 2020-09-14 11:17:33 +02:00
J-Jamet
250c7e5f20 Change string 2020-09-13 16:29:35 +02:00
J-Jamet
83740f77bb Fix attachment service listeners 2020-09-13 16:18:46 +02:00
J-Jamet
8267e13d22 Fix uploading attachment with same name 2020-09-13 15:47:05 +02:00
HARADA Hiroyuki
a7e9396f35 Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-13 15:36:11 +02:00
J-Jamet
0f6c8601d2 Remove temp attachment if not used 2020-09-13 13:38:33 +02:00
J-Jamet
66e68092d5 Fix incomplete attachment deletion #684 2020-09-13 13:11:08 +02:00
J-Jamet
09616a594c Fix commit attachment layout 2020-09-13 10:36:51 +02:00
J-Jamet
7ae58ea7ea Change consumme by consume 2020-09-13 10:25:01 +02:00
Oğuz Ersen
9f1f85a3c4 Translated using Weblate (Turkish)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-09-11 23:44:02 +02:00
Vachan
9992cdfce0 Translated using Weblate (Malayalam)
Currently translated at 71.9% (325 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-09-11 12:36:11 +02:00
Milo Ivir
f5fa08ce94 Translated using Weblate (Croatian)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-09-11 12:36:10 +02:00
Andrew
67f70f7f85 Translated using Weblate (Russian)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-09-11 12:36:10 +02:00
Éfrit
840bd56a3d Translated using Weblate (French)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-09-11 12:36:10 +02:00
HARADA Hiroyuki
c1e2d31cfd Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-09 18:05:42 +02:00
HARADA Hiroyuki
c35322d44e Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-06 19:24:01 +02:00
Dhruvan Ganesh
9867e46c3f Translated using Weblate (Tamil)
Currently translated at 2.8% (13 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ta/
2020-09-06 14:36:08 +02:00
WaldiS
946a120038 Translated using Weblate (Polish)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-09-06 14:36:08 +02:00
Dhruvan Ganesh
2cd1a17aa2 Added translation using Weblate (Tamil) 2020-09-05 13:58:58 +02:00
J-Jamet
6e29fe2932 Fix education hint freeze #685 2020-09-04 10:55:16 +02:00
J-Jamet
e6c6bf6613 Rename version to 2.8.4 2020-09-04 09:57:23 +02:00
Eric
72c53169df Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-09-03 14:57:25 +02:00
ihor_ck
b78cce7b4f Translated using Weblate (Ukrainian)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-09-03 14:57:25 +02:00
solokot
c40499ec31 Translated using Weblate (Russian)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-09-03 14:57:25 +02:00
HARADA Hiroyuki
ee158e517e Translated using Weblate (Japanese)
Currently translated at 100.0% (452 of 452 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-09-03 14:57:24 +02:00
J-Jamet
70aebcf9aa Upgrade to 2.9 2020-09-02 13:46:02 +02:00
J-Jamet
b15870d441 Merge tag '2.8.3' into develop
2.8.3
2020-09-02 12:29:43 +02:00
J-Jamet
fe7074736a Merge branch 'release/2.8.3' 2020-09-02 12:29:36 +02:00
J-Jamet
69c523ffad Image button at 48dp 2020-09-02 12:21:18 +02:00
J-Jamet
6aeefdf43d Merge branch 'translations' into develop 2020-09-01 20:27:41 +02:00
J-Jamet
5f4c8be3d3 Replace strong tags 2020-09-01 20:27:19 +02:00
J-Jamet
3092e4c557 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations
# Conflicts:
#	app/src/main/res/values-cs/strings.xml
#	app/src/main/res/values-da/strings.xml
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-hr/strings.xml
#	app/src/main/res/values-ja/strings.xml
#	app/src/main/res/values-pl/strings.xml
#	app/src/main/res/values-ru/strings.xml
#	app/src/main/res/values-tr/strings.xml
#	app/src/main/res/values-uk/strings.xml
#	app/src/main/res/values-zh-rCN/strings.xml
#	app/src/main/res/values-zh-rTW/strings.xml
2020-09-01 20:19:46 +02:00
J-Jamet
ea119068da Remove full file path setting 2020-09-01 19:19:15 +02:00
J-Jamet
14371ecf94 Educational hint for attachment 2020-09-01 19:12:25 +02:00
James Alison
45b0fcfe15 Translated using Weblate (Persian)
Currently translated at 57.3% (257 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fa/
2020-09-01 18:49:37 +02:00
behnam ghafari
00aa5f5586 Translated using Weblate (Persian)
Currently translated at 57.3% (257 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fa/
2020-09-01 18:49:37 +02:00
J-Jamet
79fd53fd4c Edit custom fields #675 2020-09-01 18:45:52 +02:00
J-Jamet
357ee3daf0 Fix styles color in Kitkat 2020-09-01 13:22:41 +02:00
J-Jamet
c2f7897f10 Information icon as home button 2020-09-01 12:43:29 +02:00
J-Jamet
75455c0c48 Change file modification info #667 2020-09-01 12:14:37 +02:00
J-Jamet
a394bb9f8e Remove modification date when not available 2020-09-01 12:00:08 +02:00
J-Jamet
2f5a846493 Change bottom bar color 2020-09-01 00:30:18 +02:00
J-Jamet
90376b361d Fix populate OTP 2020-09-01 00:30:03 +02:00
J-Jamet
229cf6bf5f Change purple background cardview 2020-09-01 00:19:00 +02:00
J-Jamet
bc46737353 Fix tab selection 2020-08-31 23:29:00 +02:00
J-Jamet
1db2243a2e Upgrade CHANGELOG 2020-08-31 22:16:28 +02:00
J-Jamet
7cf836b3cb Refactor backup methods for KDB database 2020-08-31 22:14:04 +02:00
J-Jamet
f7bbd295d6 Fix backup group 2020-08-31 21:45:39 +02:00
behnam ghafari
62dbd95b48 Added translation using Weblate (Persian) 2020-08-31 20:01:41 +02:00
HARADA Hiroyuki
df07e9c719 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-31 19:46:13 +02:00
J-Jamet
9aaf72726e Fix deletion for database V1 #394 2020-08-31 17:18:37 +02:00
J-Jamet
5289927619 Removes max lines in notes #676 2020-08-31 16:54:26 +02:00
J-Jamet
fa8c686f75 Revert EditTextVisibility #660 2020-08-31 16:35:02 +02:00
J-Jamet
df5f28b7c4 Smooth scroll when adding element and fix #660 2020-08-31 16:05:22 +02:00
HARADA Hiroyuki
280d8368fa Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-31 15:22:27 +02:00
HARADA Hiroyuki
80dbff1f21 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-31 15:11:27 +02:00
J-Jamet
7ee68a8481 Change item attachment focus 2020-08-31 13:35:38 +02:00
J-Jamet
ac8dd42c45 Change small code 2020-08-31 13:35:18 +02:00
J-Jamet
eed2148b2a Remove unused import 2020-08-28 21:49:15 +02:00
J-Jamet
dc5345b6d3 Fix database alias #670 2020-08-28 21:49:00 +02:00
J-Jamet
221af0b5bb Fix attachment history with the same name 2020-08-28 13:48:07 +02:00
J-Jamet
a10ccc1eb0 Second pass to fix attachment deleted in history 2020-08-28 13:12:54 +02:00
J-Jamet
b72d858480 First pass to fix attachment deleted in history 2020-08-28 11:08:30 +02:00
J-Jamet
60412cc90b Update CHANGELOG 2020-08-28 10:43:54 +02:00
J-Jamet
512ac87dc9 Fix attachment icon color 2020-08-28 10:38:48 +02:00
J-Jamet
d97020d1c5 Merge branch 'wiomoc-patch-1' into develop 2020-08-28 10:22:12 +02:00
Zidan Pragata
f82cb617ba Translated using Weblate (Indonesian)
Currently translated at 39.2% (176 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2020-08-28 09:00:49 +02:00
Small Ku
f79281a1a0 Translated using Weblate (Chinese (Traditional))
Currently translated at 55.5% (249 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2020-08-28 09:00:45 +02:00
HARADA Hiroyuki
7be1dbb78b Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-28 09:00:44 +02:00
C. Rüdinger
f875787799 Translated using Weblate (German)
Currently translated at 99.7% (447 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-08-28 09:00:44 +02:00
jan madsen
f82c208556 Translated using Weblate (Danish)
Currently translated at 94.8% (425 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-08-28 09:00:43 +02:00
Christoph Walcher
f2150e3d85 Early return in readHeaderField
In the old version the outer loop won't terminate if `EndOfHeader` is a zero sized field.
2020-08-28 03:09:23 +02:00
J-Jamet
ecc198e8a0 Fix toolbar appearance #669 2020-08-27 20:39:03 +02:00
J-Jamet
949bc58a80 Merge branch 'feature/File_Attachment' into develop #189 2020-08-27 19:14:51 +02:00
J-Jamet
7d79fff16f Disable compression by entry attachment in DatabaseV4 2020-08-27 19:04:58 +02:00
J-Jamet
3aeb678292 Fix binaries indexes in DatabaseV4 2020-08-27 18:45:56 +02:00
Zidan Pragata
160ac41bed Added translation using Weblate (Indonesian) 2020-08-27 16:41:50 +02:00
J-Jamet
9dfbcbe89c Not compress by default for database v4 2020-08-27 14:21:36 +02:00
J-Jamet
30da529348 Fix corruption in header 2020-08-27 13:57:34 +02:00
J-Jamet
dd8d114711 Change save binaries compression for database 3.1 & 4 2020-08-27 13:49:48 +02:00
J-Jamet
2191a4a848 Allow swipe notification when download completed 2020-08-27 10:27:45 +02:00
J-Jamet
8b9ea8d988 Fix remove oldest attachments 2020-08-27 10:16:37 +02:00
J-Jamet
46dda8567d Remove warnings and better gzip view implementation 2020-08-26 23:43:49 +02:00
J-Jamet
6953da4d9a Change containsAttachment method 2020-08-26 23:35:16 +02:00
J-Jamet
e987d6647e Fix header binary compression 2020-08-26 23:25:13 +02:00
J-Jamet
359d85727e Remove oldest attachments files when deleted from entries 2020-08-26 21:25:51 +02:00
J-Jamet
a994bf9dd8 Change string to Gzip 2020-08-26 20:35:45 +02:00
J-Jamet
14c4e095f6 Remove attachment path view 2020-08-26 20:33:13 +02:00
J-Jamet
59dce0e56f Restore unknown compression 2020-08-26 20:27:13 +02:00
J-Jamet
1f54a893a7 Move classes 2020-08-26 19:28:26 +02:00
J-Jamet
9489f1ee3d Rename removeUnlinkedAttachments 2020-08-26 19:25:30 +02:00
J-Jamet
dc3d720e8d Binary files as time 2020-08-26 19:20:37 +02:00
J-Jamet
efe30b598b Write only attachments in header
Remove unlinked attachments
Simpler compression
2020-08-26 18:51:25 +02:00
J-Jamet
42515bfb2d Encapsulate consume attachment action 2020-08-26 11:44:56 +02:00
J-Jamet
acb3657d95 Better compression - decompression implementation 2020-08-26 11:43:35 +02:00
J-Jamet
e7159c9d36 Try to fix decompression 2020-08-26 10:39:56 +02:00
J-Jamet
f3fdca368b Fix compression after download and upload attachment 2020-08-25 20:07:41 +02:00
J-Jamet
4ea3e08a45 Refactor EntryAttachment to Attachment 2020-08-25 19:28:41 +02:00
J-Jamet
1eebc72b21 Encapsulate binary methods 2020-08-25 19:20:58 +02:00
J-Jamet
9a91be7e36 Add attachment icon in entry list 2020-08-25 18:13:44 +02:00
J-Jamet
48476f9b88 Add attachments 2020-08-25 17:51:01 +02:00
J-Jamet
68c991eb9b Ask to replace file 2020-08-25 17:48:17 +02:00
J-Jamet
b51c77b01b Ask for big files 2020-08-25 17:19:58 +02:00
J-Jamet
57105db554 Allow only one attachment for Database KDB 2020-08-25 12:52:41 +02:00
J-Jamet
4bd3bdaddf Fix concurrent exception and upload the same file 2020-08-25 12:39:17 +02:00
J-Jamet
9cf59b8d73 Refactoring code 2020-08-25 12:27:43 +02:00
J-Jamet
a793b0bb42 Remove not compatible elements below KitKat 2020-08-25 12:00:17 +02:00
J-Jamet
4d9e2e1471 Upload progression 2020-08-25 11:37:11 +02:00
J-Jamet
1719887e55 Fix lock button after download or upload 2020-08-24 22:52:12 +02:00
J-Jamet
2be00aca9d Merge branch 'develop' into feature/File_Attachment 2020-08-24 22:33:05 +02:00
J-Jamet
6fd05c5ad7 Rotate arrow drawable 2020-08-24 22:32:40 +02:00
J-Jamet
65e404374f Change upload icon 2020-08-24 22:32:05 +02:00
J-Jamet
0b78731bb3 Strings for upload notification 2020-08-24 22:20:58 +02:00
J-Jamet
65d318ed88 Fix many upload issues 2020-08-24 21:54:21 +02:00
Milo Ivir
1bfcea55a9 Translated using Weblate (Croatian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-08-24 16:06:20 +02:00
Eric
6780eb004d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-08-24 16:06:20 +02:00
ihor_ck
0e12b2d021 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-08-24 16:06:20 +02:00
Andrew
1b356f87ec Translated using Weblate (Russian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-08-24 16:06:20 +02:00
solokot
bf24d0bae1 Translated using Weblate (Russian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-08-24 16:06:19 +02:00
WaldiS
97c831d4bb Translated using Weblate (Polish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-08-24 16:06:19 +02:00
HARADA Hiroyuki
e3e48ffa6d Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-24 16:06:19 +02:00
zeritti
b678416122 Translated using Weblate (Czech)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-08-24 16:06:19 +02:00
J-Jamet
df722925fa Upload attachments #189 2020-08-24 13:03:59 +02:00
J-Jamet
4cbc0d9806 Merge branch 'develop' into feature/File_Attachment 2020-08-23 12:49:44 +02:00
J-Jamet
b0f3711b4e Remove previous allow lock code 2020-08-23 12:49:12 +02:00
J-Jamet
14ec6579b2 Merge branch 'develop' into feature/File_Attachment 2020-08-23 12:41:56 +02:00
J-Jamet
30bf039473 Fix last item visibility 2020-08-23 12:26:10 +02:00
Oğuz Ersen
33bea317b0 Translated using Weblate (Turkish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-08-22 05:31:03 +02:00
Andrew
c6814dc05e Translated using Weblate (Russian)
Currently translated at 97.9% (439 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-08-22 05:31:03 +02:00
HARADA Hiroyuki
16808069ec Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-22 05:31:02 +02:00
J-Jamet
e813974e29 Fix file info issue 2020-08-21 20:17:05 +02:00
J-Jamet
7e0010b536 Images buttons width 36dp 2020-08-21 20:02:32 +02:00
J-Jamet
93171adcb3 Smaller download icon 2020-08-21 19:48:16 +02:00
J-Jamet
9501cc76a4 Notes and URL as EntryField 2020-08-21 19:43:54 +02:00
J-Jamet
5d7db046ac Encapsulate username and OTP as EntryField 2020-08-21 18:35:54 +02:00
J-Jamet
46c259bc3e Fix field delete button position 2020-08-21 18:24:41 +02:00
J-Jamet
3bacff91d3 Visibility button for each field, password as EntryField view 2020-08-21 17:31:15 +02:00
J-Jamet
bd79d483d2 Upgrade to 2.8.3 2020-08-21 16:16:35 +02:00
Hosted Weblate
16e31f4881 Merge branch 'origin/master' into Weblate. 2020-08-21 16:14:09 +02:00
ssantos
afa23c393d Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-08-21 16:14:08 +02:00
HARADA Hiroyuki
54d23cb781 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-21 16:14:08 +02:00
random r
c757e410e9 Translated using Weblate (Italian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-08-21 16:14:08 +02:00
J-Jamet
39dd25567d Merge tag '2.8.2' into develop
2.8.2
2020-08-21 16:04:09 +02:00
J-Jamet
32cd998c2a Merge branch 'release/2.8.2' 2020-08-21 16:04:02 +02:00
J-Jamet
691fc6335e Fix warnings 2020-08-21 15:48:58 +02:00
J-Jamet
b0025d1416 Refactor assign history 2020-08-21 13:49:04 +02:00
J-Jamet
2467d8b0e7 Try to fix new extra field 2020-08-21 13:06:13 +02:00
J-Jamet
28993c53e7 Fix keyboard shown 2020-08-21 12:25:32 +02:00
J-Jamet
efdea870f0 Upgrade kotlin to 1.4.0 2020-08-20 17:45:28 +02:00
J-Jamet
b2995ec862 Replace <strong> tags 2020-08-20 17:08:54 +02:00
J-Jamet
2bcc84dbb2 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-08-20 16:49:47 +02:00
J-Jamet
70cc98ce33 Change strings according to #550 2020-08-20 16:48:56 +02:00
J-Jamet
6e055f398d Change focus timestamp variable 2020-08-20 14:20:51 +02:00
J-Jamet
9f6234f032 Fix show button in long tap mode 2020-08-20 14:16:20 +02:00
J-Jamet
6135544b72 Fix extra field cursor after orientation change 2020-08-20 14:04:48 +02:00
HARADA Hiroyuki
5f32ec218b Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-19 04:10:17 +02:00
J-Jamet
3b9a884db2 Remove TODO 2020-08-18 18:08:26 +02:00
J-Jamet
ada6b85868 Fix entry extra field replacement 2020-08-18 18:06:16 +02:00
HARADA Hiroyuki
2f8a4f447c Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-18 18:04:30 +02:00
J-Jamet
9bd6499271 Fix small issue 2020-08-18 17:09:51 +02:00
J-Jamet
76fcc919ef Encapsulate putItems 2020-08-18 16:46:09 +02:00
J-Jamet
a382297edf Encapsulate adapters in AnimatedItemsAdapter 2020-08-18 16:33:48 +02:00
HARADA Hiroyuki
4987dfe4f6 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-18 16:22:12 +02:00
J-Jamet
d1a2e50b8d Edit extra fields as recyclerview 2020-08-18 16:12:18 +02:00
HARADA Hiroyuki
b9e44b6166 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-18 14:12:31 +02:00
HARADA Hiroyuki
af601edc94 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-16 23:32:56 +02:00
Alexander Ritter
6640dcf9cd Translated using Weblate (German)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-08-16 23:32:56 +02:00
J-Jamet
9b2734ed38 Fix populate extra field 2020-08-16 10:40:17 +02:00
J-Jamet
afcfce056f Fix collapse animation 2020-08-16 09:53:47 +02:00
J-Jamet
8f3af2f27b Fix small issues in kitkat 2020-08-15 21:52:39 +02:00
J-Jamet
706aae47b3 Fix small cardView issue 2020-08-15 21:27:35 +02:00
J-Jamet
d494295b21 Harmonize image reverse buttons 2020-08-15 21:06:15 +02:00
J-Jamet
c1600a253b Harmonize image buttons 2020-08-15 20:41:57 +02:00
J-Jamet
a3bc29ad8f Fix expand uri info view 2020-08-15 15:54:08 +02:00
J-Jamet
83225ed157 Fix real attachment deletion 2020-08-15 15:38:46 +02:00
J-Jamet
f13f6dc01f Fix attachments deletion and change entry edit layout 2020-08-15 15:28:25 +02:00
J-Jamet
2d2489443a New icon to create extra field and fix focus 2020-08-15 12:41:16 +02:00
J-Jamet
0e5b7fbfa2 Possibility to remove attachment 2020-08-15 12:01:08 +02:00
HARADA Hiroyuki
d16a8068f7 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-14 16:35:05 +02:00
J-Jamet
c5ef11febc Tint password generator color 2020-08-14 15:50:54 +02:00
J-Jamet
027f31447a Fix delegation 2020-08-14 15:48:18 +02:00
HARADA Hiroyuki
41d1a4e5fb Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-14 09:49:39 +02:00
J-Jamet
924e3191cb Fix entry extra field view 2020-08-14 00:11:08 +02:00
J-Jamet
ebdc6b8fd9 Fix entry extra field view 2020-08-13 19:37:55 +02:00
HARADA Hiroyuki
5c05128cd7 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 18:41:25 +02:00
J-Jamet
5bf5685a12 Refactor extra field 2020-08-13 17:43:40 +02:00
J-Jamet
f7391cb4c4 Refactor extra field 2020-08-13 17:33:03 +02:00
HARADA Hiroyuki
bad7bd8884 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 17:20:25 +02:00
HARADA Hiroyuki
e0524a1656 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 17:05:45 +02:00
HARADA Hiroyuki
f59af9baa3 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 15:47:06 +02:00
HARADA Hiroyuki
b36890ca82 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 15:26:39 +02:00
HARADA Hiroyuki
22703af08b Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 15:12:46 +02:00
HARADA Hiroyuki
c4108269b3 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 14:55:52 +02:00
HARADA Hiroyuki
94c9d090cf Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 09:35:13 +02:00
HARADA Hiroyuki
28b9235a43 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-13 08:16:50 +02:00
librada
3aebae5e15 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 20:02:06 +02:00
librada
2631cb75d6 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 17:46:07 +02:00
librada
07b8b4156f Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 15:49:43 +02:00
librada
7978967c1a Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 14:26:02 +02:00
librada
3f24ff4de3 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 14:13:53 +02:00
librada
7253dd82a6 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 13:41:00 +02:00
librada
2b8eb3ae7e Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 13:36:08 +02:00
librada
429eae71cd Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 13:00:40 +02:00
librada
e5c552defb Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 12:42:27 +02:00
librada
5c950a2e2c Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 12:31:54 +02:00
librada
577ff78189 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 12:11:12 +02:00
librada
3f3cde05f7 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 11:30:28 +02:00
sivemortenfan
b48f2c3276 Translated using Weblate (Malayalam)
Currently translated at 65.4% (293 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-08-12 10:59:27 +02:00
ssantos
8e818846f0 Translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-08-12 10:59:26 +02:00
librada
1554e37f8c Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 10:59:24 +02:00
librada
affaabd011 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 10:47:35 +02:00
librada
f34a8f991c Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-12 08:30:37 +02:00
J-Jamet
c2b14d610b Revert "Small duration change in animation"
This reverts commit 23155279ab.
2020-08-11 17:52:32 +02:00
J-Jamet
02693d0cbb Fix database opening after creation 2020-08-11 16:57:16 +02:00
J-Jamet
23155279ab Small duration change in animation 2020-08-11 16:16:53 +02:00
J-Jamet
2d23f7403d Fix expand icon rotation 2020-08-11 15:59:35 +02:00
J-Jamet
ae411c6fd5 default database button at right 2020-08-10 20:26:23 +02:00
J-Jamet
ab8d6075a9 Allow dark style in free version 2020-08-10 18:10:19 +02:00
J-Jamet
bc5ae29a67 Default database in database selection 2020-08-10 17:36:06 +02:00
librada
1a8aabc30c Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-10 17:20:04 +02:00
J-Jamet
8c51d7f713 Add animation when delete custom field 2020-08-10 12:59:09 +02:00
J-Jamet
8a1485e7ce Change themes 2020-08-10 11:16:04 +02:00
J-Jamet
614145431a Replace info icon 2020-08-10 10:13:00 +02:00
J-Jamet
db25f1999f Remove flickering on the first database list load 2020-08-10 10:02:53 +02:00
J-Jamet
4ed231b9bb Replace and animate database info expand icon 2020-08-10 00:03:23 +02:00
J-Jamet
25a5342c11 Fix database opening after creation 2020-08-09 23:27:49 +02:00
J-Jamet
c7202e3ca9 Fix database list animation 2020-08-09 23:19:01 +02:00
C. Rüdinger
89c2e94cea Translated using Weblate (German)
Currently translated at 99.5% (446 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-08-09 22:32:47 +02:00
Oliver
3dc46771b5 Translated using Weblate (German)
Currently translated at 99.5% (446 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-08-09 22:32:47 +02:00
J-Jamet
0eac4d4d7f Fix database list change 2020-08-09 20:59:34 +02:00
J-Jamet
a0ceb788db Upgrade dependencies 2020-08-09 18:39:00 +02:00
J-Jamet
98fb36d03a Try to fix notification lock 2020-08-09 15:46:39 +02:00
J-Jamet
a670006517 Bottom app bar with center FAB 2020-08-09 14:25:22 +02:00
J-Jamet
9cdbe67cd4 Rollback stop task service before opening, ViewModel implementation seems fix the previous crash 2020-08-08 15:58:25 +02:00
Vachan
bbe8af452c Translated using Weblate (Malayalam)
Currently translated at 65.1% (292 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-08-08 15:32:47 +02:00
librada
f5edf28ce1 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-08 15:32:46 +02:00
J-Jamet
8fc30f590b Update CHANGELOG 2020-08-08 13:36:39 +02:00
J-Jamet
e578f23ebe Fix field order by using LinkedHashMap #611 2020-08-08 13:34:28 +02:00
J-Jamet
99c488fc9e Upgrade CHANGELOG 2020-08-08 10:41:07 +02:00
J-Jamet
f6a710660d Merge branch 'feature/ViewModel' into develop 2020-08-08 10:36:39 +02:00
J-Jamet
a61744bb65 Fix icon color 2020-08-07 21:14:27 +02:00
J-Jamet
17c3078c24 Better thread callback encapsulation 2020-08-07 21:00:20 +02:00
J-Jamet
5fa7731b56 Fix ViewModel methods call 2020-08-07 20:33:06 +02:00
J-Jamet
c8e2be4d8c Fix minor variable name 2020-08-07 16:51:55 +02:00
J-Jamet
e3db613a07 Rename progress database task provider 2020-08-07 16:45:52 +02:00
J-Jamet
0f7839027f Start using ViewModel for internal database action 2020-08-07 16:41:28 +02:00
J-Jamet
31b322a108 Replace AsyncTask by Coroutines 2020-08-07 11:29:16 +02:00
J-Jamet
b3c0494618 Better file attachment download implementation 2020-08-06 16:59:15 +02:00
J-Jamet
78ddb0533d Attachment download as coroutine 2020-08-06 16:35:15 +02:00
Vachan
da2158e7f2 Translated using Weblate (Malayalam)
Currently translated at 62.9% (282 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-08-06 10:32:49 +02:00
Stephan Paternotte
d2a1efb6e7 Translated using Weblate (Dutch)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-08-06 10:32:46 +02:00
librada
98a880db2d Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-08-06 10:32:46 +02:00
J-Jamet
cb82ef8703 Fix bottom app bar color in Kitkat 2020-08-05 17:00:01 +02:00
J-Jamet
d56246767b Better focus implementation 2020-08-05 16:37:30 +02:00
J-Jamet
bb477984aa Fix icons in arabic language 2020-08-05 15:51:06 +02:00
J-Jamet
5a3e650e02 Fix RTL views 2020-08-05 15:23:49 +02:00
J-Jamet
3c96dd2fac Upgrade CHANGELOG 2020-08-05 14:47:21 +02:00
J-Jamet
da051e3ff3 Fix biometric view visibility 2020-08-05 14:44:47 +02:00
J-Jamet
d15b6323c2 Upgrade CHANGELOG 2020-08-05 14:23:29 +02:00
J-Jamet
ec5f8fe4a4 Merge branch 'feature/CustomFieldLayout' into develop 2020-08-05 14:19:59 +02:00
J-Jamet
71d84d76f8 Fix last entry in Magikeyboard memory #653 2020-08-05 14:19:37 +02:00
J-Jamet
d33ed52ec2 Adjust Pan for EntryEdit 2020-08-05 11:00:23 +02:00
J-Jamet
3a970544bb Max password field lines -> 10 2020-08-04 19:58:02 +02:00
J-Jamet
792ac3a2e8 Fix password field 2020-08-04 19:51:22 +02:00
J-Jamet
60bbc27401 Unique password field with password generator button 2020-08-04 19:40:14 +02:00
J-Jamet
cf7cbcb6e6 Focus OTP view after creation 2020-08-04 19:03:04 +02:00
J-Jamet
c126a8eba9 Fix custom field creation 2020-08-04 18:51:00 +02:00
J-Jamet
66a60d0357 Fix manifest 2020-08-04 18:06:51 +02:00
J-Jamet
1acdadd027 Fix styles 2020-08-04 16:28:36 +02:00
J-Jamet
200be9dadd Fix toolbar padding with lock button 2020-08-04 15:19:49 +02:00
J-Jamet
a73e2872a4 Lock button color 2020-08-04 12:14:59 +02:00
J-Jamet
ce6f7729c5 Lock button with toolbar 2020-08-04 11:38:54 +02:00
J-Jamet
c285411371 Rollback lock button 2020-08-04 10:38:49 +02:00
J-Jamet
46394c600e New entry edit layout and custom lock 2020-08-03 20:54:20 +02:00
J-Jamet
bea9cb3248 Fix custom field error 2020-08-03 19:38:08 +02:00
J-Jamet
1087dcd714 New UI for custom field 2020-08-03 18:45:50 +02:00
Vachan
0b63029b7e Translated using Weblate (Malayalam)
Currently translated at 27.0% (121 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2020-08-01 09:47:48 +02:00
J-Jamet
9679d24414 New UI for Biometric 2020-08-01 01:00:53 +02:00
J-Jamet
7947fd53e5 Change biometric button layout 2020-07-31 23:34:00 +02:00
J-Jamet
8dedf75565 Minor style fix 2020-07-31 22:54:44 +02:00
J-Jamet
b5b7c12b49 Fix bar color in splashscreen 2020-07-31 22:15:04 +02:00
J-Jamet
51f4e3cc3a Change CardView margin 2020-07-31 21:59:16 +02:00
J-Jamet
24b0315d2e Update CHANGELOG 2020-07-31 21:31:05 +02:00
J-Jamet
be446220eb Fix themes 2020-07-31 21:29:44 +02:00
Vachan
a3ef2d332e Added translation using Weblate (Malayalam) 2020-07-31 05:33:41 +02:00
Milo Ivir
ba6fe576e3 Translated using Weblate (Croatian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-07-30 08:42:39 +02:00
abidin toumi
abcef38102 Translated using Weblate (Arabic)
Currently translated at 61.3% (275 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-07-30 08:42:39 +02:00
ihor_ck
d5780b2f30 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-07-30 08:42:38 +02:00
librada
f7e498a0a2 Translated using Weblate (Japanese)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-07-30 08:42:00 +02:00
Petri Salminen
51ac7ca2de Translated using Weblate (Finnish)
Currently translated at 67.4% (302 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fi/
2020-07-30 08:41:57 +02:00
Aman ALam
c94535f6b5 Translated using Weblate (Punjabi)
Currently translated at 57.8% (259 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2020-07-25 10:10:55 +02:00
Thomas
07457ae368 Translated using Weblate (Chinese (Traditional))
Currently translated at 51.7% (232 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2020-07-25 10:10:55 +02:00
WaldiS
4767fff08c Translated using Weblate (Polish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-07-25 10:10:55 +02:00
librada
f0c3498ecc Translated using Weblate (Japanese)
Currently translated at 71.4% (320 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-07-25 10:10:43 +02:00
Rodrigo Saldaña
1eca52d0fe Translated using Weblate (Spanish)
Currently translated at 76.3% (342 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-07-25 10:10:40 +02:00
SeerLite
7fbac9ad2f Translated using Weblate (Spanish)
Currently translated at 76.3% (342 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-07-25 10:10:40 +02:00
J-Jamet
6fb80ed50b Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-07-24 09:50:36 +02:00
J-Jamet
47f63ac81b Fix themes for free version 2020-07-24 09:50:26 +02:00
J-Jamet
42cc0b28ba Merge branch 'feature/Merge_Action_tasks_#628' into develop 2020-07-23 13:49:43 +02:00
J-Jamet
993806f781 Refactor Database.getInstance() in Task service 2020-07-22 23:48:07 +02:00
J-Jamet
8a5af33aaa Fix crash 2020-07-22 23:20:16 +02:00
J-Jamet
a974e36e9e Merge Open and Task services 2020-07-22 22:43:21 +02:00
Allan Nordhøy
17bcb2b39e Translated using Weblate (Norwegian Bokmål)
Currently translated at 80.3% (360 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-07-21 19:41:54 +02:00
ssantos
cddf02d0c1 Translated using Weblate (Portuguese (Portugal))
Currently translated at 60.9% (273 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-07-21 19:41:54 +02:00
librada
75ff7ece37 Translated using Weblate (Japanese)
Currently translated at 54.6% (245 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-07-21 19:41:54 +02:00
jan madsen
ec2b407a20 Translated using Weblate (Danish)
Currently translated at 97.3% (436 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-07-21 19:41:53 +02:00
ssantos
1dc9d78e54 Translated using Weblate (Portuguese (Portugal))
Currently translated at 60.4% (271 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_PT/
2020-07-19 03:37:27 +02:00
WaldiS
5742a75c9d Translated using Weblate (Polish)
Currently translated at 99.1% (444 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-07-19 03:37:27 +02:00
zeritti
b5e9ad6d7e Translated using Weblate (Czech)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-07-19 03:37:27 +02:00
Oğuz Ersen
6393025219 Translated using Weblate (Turkish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-07-18 08:42:19 +02:00
Eric
9ab3e289bc Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (448 of 448 strings)

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

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-07-18 08:42:19 +02:00
solokot
c5720a7a03 Translated using Weblate (Russian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-07-18 08:42:18 +02:00
C. Rüdinger
41b15adc6d Translated using Weblate (German)
Currently translated at 98.8% (443 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-07-18 08:42:18 +02:00
J-Jamet
05b962e718 First commit to merge action tasks 2020-07-17 11:02:58 +02:00
Hosted Weblate
1f01ca7b85 Merge branch 'origin/master' into Weblate. 2020-07-17 10:31:51 +02:00
J-Jamet
5d3b4fa5ec Update CHANGELOG and fix descriptions by version 2020-07-17 10:26:26 +02:00
J-Jamet
754d2b2dd3 Merge tag '2.8.1' into develop
2.8.1
2020-07-17 10:12:30 +02:00
J-Jamet
ffad62e3dc Merge branch 'release/2.8.1' 2020-07-17 10:12:19 +02:00
J-Jamet
1c11e16565 Update fastlane README.md 2020-07-17 10:12:09 +02:00
J-Jamet
edc12990b4 Change switch keyboard strings 2020-07-17 10:00:07 +02:00
J-Jamet
12ea234d18 Fix coroutines exceptions #627 2020-07-17 09:32:49 +02:00
Milo Ivir
0461206a61 Translated using Weblate (Croatian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-07-16 23:41:52 +02:00
Serdar Sağlam
663f9e3962 Translated using Weblate (Turkish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-07-16 23:41:52 +02:00
Eric
34ee948c8e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-07-16 23:41:51 +02:00
ihor_ck
1bb9c2e4fe Translated using Weblate (Ukrainian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-07-16 23:41:51 +02:00
solokot
8ab18ce5cc Translated using Weblate (Russian)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-07-16 23:41:51 +02:00
WaldiS
71be16826e Translated using Weblate (Polish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-07-16 23:41:51 +02:00
Oğuz Ersen
926c09d9df Translated using Weblate (Turkish)
Currently translated at 100.0% (448 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-07-15 04:50:15 +02:00
ihor_ck
66c065ae7f Translated using Weblate (Ukrainian)
Currently translated at 98.8% (443 of 448 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-07-15 04:50:15 +02:00
Hosted Weblate
083ed7775c Merge branch 'origin/master' into Weblate. 2020-07-14 18:02:48 +02:00
Thomas
5185452495 Translated using Weblate (Chinese (Traditional))
Currently translated at 50.4% (224 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2020-07-14 18:02:47 +02:00
J-Jamet
fa15f226ab Merge tag '2.8' into develop
2.8
2020-07-14 17:19:30 +02:00
J-Jamet
fea4da2a33 Merge branch 'release/2.8' 2020-07-14 17:19:23 +02:00
J-Jamet
055c933f4b Replace <strong> and </strong> strings 2020-07-14 17:09:52 +02:00
J-Jamet
9bcb867748 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-07-14 17:07:07 +02:00
J-Jamet
26e3c03f5f Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-07-13 08:39:08 +02:00
J-Jamet
c195c3b2d1 Remove unexpected char #622 2020-07-13 08:38:50 +02:00
J-Jamet
f9e0aacfeb Fix clipboard notification after orientation change 2020-07-10 18:08:26 +02:00
J-Jamet
37fef66647 Improve recognition to reset app timeout #562 2020-07-10 17:52:58 +02:00
J-Jamet
9f99b67563 Improve recognition to reset app timeout #562 2020-07-10 17:46:14 +02:00
J-Jamet
fe902648ad Settings to back to the previous keyboard during database credentials and after form filling #601 2020-07-10 13:00:27 +02:00
J-Jamet
13b933cd0b Try to fix biometric prompt in other activities #602 2020-07-09 19:34:57 +02:00
abidin toumi
1d3b1d1d80 Translated using Weblate (Arabic)
Currently translated at 61.0% (271 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-07-08 09:41:52 +02:00
Stephan Paternotte
67a612af3a Translated using Weblate (Dutch)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-07-08 09:41:52 +02:00
J-Jamet
a891683806 Fix close option menu error 2020-07-06 20:05:03 +02:00
J-Jamet
440a72fc42 Move timeout helper call in service 2020-07-06 19:59:11 +02:00
J-Jamet
696d2e5197 Fix RemoteServiceException 2020-07-06 19:55:17 +02:00
J-Jamet
2b17d56fc7 Allow open database during selection mode #608 2020-07-06 17:55:08 +02:00
J-Jamet
a410ef5d9f Fix education hint in selection mode #600 2020-07-06 15:59:14 +02:00
Aman ALam
fe94769541 Translated using Weblate (Punjabi)
Currently translated at 55.6% (247 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2020-07-05 02:41:49 +02:00
WaldiS
c63ae9c00c Translated using Weblate (Polish)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-07-05 02:41:49 +02:00
J-Jamet
d5ece8d007 Upgrade CHANGELOG 2020-07-04 19:19:05 +02:00
J-Jamet
692a971dc0 Fix issue #615 and #612, action loading 2020-07-04 15:45:07 +02:00
J-Jamet
05b8370cc0 Rename saveView by validateButton 2020-07-04 11:58:06 +02:00
J-Jamet
b6111b35a2 Change clipboard strings and remove swipe to clear #605 2020-07-04 11:27:21 +02:00
J-Jamet
4d72687628 Change ACTION_OPEN_DOCUMENT and flags 2020-07-02 13:36:46 +02:00
J-Jamet
8f125983ce Change selection mode toolbar style 2020-07-02 13:10:32 +02:00
J-Jamet
4279825caa Fix search in recycle bin #613 2020-07-02 12:10:04 +02:00
J-Jamet
77ae3a4623 Merge branch 'feature/javaLang_ClassCastException' into develop 2020-07-02 11:59:26 +02:00
J-Jamet
4c222dbc54 Upgrade CHANGELOG 2020-07-02 10:49:24 +02:00
J-Jamet
4e0f93ee8a Merge branch 'develop' into feature/javaLang_ClassCastException 2020-07-02 10:44:03 +02:00
abidin toumi
e99f3e6627 Translated using Weblate (Arabic)
Currently translated at 55.4% (246 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-06-27 01:49:37 +02:00
Milo Ivir
f73877c34a Translated using Weblate (German)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-06-25 16:41:46 +02:00
J-Jamet
abd3f12cae Improve OTP form recognition 2020-06-23 15:53:13 +02:00
J-Jamet
00117f5b7b Rename UnsignedInt methods 2020-06-23 14:34:02 +02:00
J-Jamet
d7d728f93e Rename UnsignedInt and UnsignedLong methods 2020-06-23 14:33:43 +02:00
J-Jamet
dc9217c4ec Remove unused java.lang import 2020-06-23 14:07:03 +02:00
Milo Ivir
95acb13b93 Translated using Weblate (Croatian)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-06-23 12:41:52 +02:00
WaldiS
234cc00d9f Translated using Weblate (Polish)
Currently translated at 99.3% (441 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-06-23 12:41:48 +02:00
Oliver Cervera
d6ba164799 Translated using Weblate (Italian)
Currently translated at 98.6% (438 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-06-23 12:41:47 +02:00
S L
910aa03dc8 Translated using Weblate (Finnish)
Currently translated at 31.0% (138 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fi/
2020-06-23 12:41:46 +02:00
C. Rüdinger
a3e4a4c873 Translated using Weblate (German)
Currently translated at 99.3% (441 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-06-23 12:41:45 +02:00
solokot
2d7c843447 Translated using Weblate (Russian)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-06-21 21:49:03 +02:00
Aman ALam
e342b45473 Translated using Weblate (Punjabi)
Currently translated at 54.5% (242 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2020-06-20 12:37:24 +02:00
Milo Ivir
f354bccd58 Translated using Weblate (Croatian)
Currently translated at 75.4% (335 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-06-20 12:37:17 +02:00
Oğuz Ersen
98073134db Translated using Weblate (Turkish)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-06-20 12:37:16 +02:00
Eric
360666b00b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-06-20 12:37:16 +02:00
ihor_ck
ce4c807870 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-06-20 12:37:15 +02:00
solokot
f2783bdac8 Translated using Weblate (Russian)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-06-20 12:37:15 +02:00
Stephan Paternotte
875ed16c3b Translated using Weblate (Dutch)
Currently translated at 99.5% (442 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-06-20 12:37:14 +02:00
Kunzisoft
383ba56d1f Translated using Weblate (French)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-06-20 12:37:14 +02:00
Oliver
45eb54e624 Translated using Weblate (German)
Currently translated at 99.3% (441 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-06-20 12:37:13 +02:00
zeritti
5aff4e2ed6 Translated using Weblate (Czech)
Currently translated at 100.0% (444 of 444 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-06-20 12:37:13 +02:00
Aman ALam
e73e47dd94 Added translation using Weblate (Punjabi) 2020-06-18 20:51:10 +02:00
Hosted Weblate
1c8ac5efbc Merge branch 'origin/master' into Weblate. 2020-06-18 15:49:42 +02:00
abidin toumi
90fa5e1ecd Translated using Weblate (Arabic)
Currently translated at 54.2% (235 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-06-18 15:49:42 +02:00
J-Jamet
348994917b Upgrade to 2.8 2020-06-18 15:31:15 +02:00
J-Jamet
60dbea1027 Merge tag '2.7' into develop
2.7
2020-06-18 14:59:36 +02:00
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
J-Jamet
955c9992d0 Merge branch 'release/2.5' 2020-05-10 19:32:37 +02:00
J-Jamet
87606818cd Rename ReadMe.md to README.md 2020-05-10 16:18:32 +02:00
J-Jamet
ffcd264bac Upgrade manually Readme with pull request #540 2020-05-10 16:17:41 +02:00
J-Jamet
04c70cf99d Update fastlane full description (En/Fr - Free/Pro) 2020-05-10 15:31:07 +02:00
J-Jamet
0e0b6fca07 Fix small issue 2020-05-10 11:48:56 +02:00
J-Jamet
b24a789352 Fix small string 2020-05-10 11:46:35 +02:00
J-Jamet
3d4f447037 Replace <strong> tags 2020-05-10 11:40:15 +02:00
J-Jamet
7aa52ca00a Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-05-10 11:27:58 +02:00
J-Jamet
a94c9050c5 Update CHANGELOG and full description 2020-05-10 11:05:23 +02:00
J-Jamet
9b18e71e12 Upgrade CHANGELOGS 2020-05-10 10:14:37 +02:00
J-Jamet
d5ff048bd0 Remove allow_copy_password_key from application preferences 2020-05-10 10:12:18 +02:00
Allan Nordhøy
76f44f2573 Translated using Weblate (Romanian)
Currently translated at 91.6% (396 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-05-10 02:13:06 +02:00
Allan Nordhøy
9988f1a76f Translated using Weblate (Norwegian Bokmål)
Currently translated at 77.7% (336 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-05-10 02:13:05 +02:00
Xiang Xu
1559376bc2 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-10 02:13:05 +02:00
ihor_ck
4d0f252acd 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-10 02:13:05 +02:00
Allan Nordhøy
d5a84e66ad Translated using Weblate (Swedish)
Currently translated at 76.8% (332 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2020-05-10 02:12:59 +02:00
Retrial
1dfe3453f4 Translated using Weblate (Greek)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-05-10 02:12:59 +02:00
ihor_ck
a7dc9f31b9 Translated using Weblate (Ukrainian)
Currently translated at 53.7% (232 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-07 09:36:51 +02:00
76c72cfe
d275f18b3c Translated using Weblate (Swedish)
Currently translated at 76.8% (332 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2020-05-07 09:36:48 +02:00
WaldiS
d770429401 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-07 09:36:47 +02:00
Retrial
501f0be99f Translated using Weblate (Greek)
Currently translated at 88.1% (381 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-05-07 09:36:47 +02:00
J-Jamet
a70122f873 Fix small error 2020-05-06 18:19:07 +02:00
J-Jamet
1e1bd15a06 Replace vararg for non-compatible devices 2020-05-06 18:14:41 +02:00
J-Jamet
164fb1f4f5 Fix small warning 2020-05-06 17:45:56 +02:00
J-Jamet
0206514bdb Rollback stylish super implementation 2020-05-06 17:33:12 +02:00
J-Jamet
ecf2b42fa4 Fix field reference 2020-05-06 16:47:47 +02:00
ihor_ck
df683aeea9 Translated using Weblate (Ukrainian)
Currently translated at 32.6% (141 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-05 21:12:01 +02:00
Anonymous
cdd05958f7 Translated using Weblate (Ukrainian)
Currently translated at 32.6% (141 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-05 21:11:59 +02:00
solokot
4ec5fc05fb 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-05 21:11:59 +02:00
Lucas Nunes
4019cafac1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2020-05-05 21:11:58 +02:00
J. Lavoie
4333e179d1 Translated using Weblate (Italian)
Currently translated at 95.3% (412 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-05-05 21:11:56 +02:00
Balázs Meskó
87d67be428 Translated using Weblate (Hungarian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2020-05-05 21:11:55 +02:00
J. Lavoie
350863adff 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-05-05 21:11:55 +02:00
J. Lavoie
d125fc46a0 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-05 21:11:55 +02:00
jan madsen
5f4c079071 Translated using Weblate (Danish)
Currently translated at 98.1% (424 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-05-05 21:11:55 +02:00
zeritti
5ec576a76e 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-05 21:11:54 +02:00
Kunzisoft
9edb00ebbb 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-05-04 20:29:35 +02:00
ihor_ck
59843e5464 Translated using Weblate (Ukrainian)
Currently translated at 15.0% (65 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-04 02:22:13 +02:00
solokot
4fe0ccf807 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-02 20:32:07 +02:00
Anonymous
2ee012d3fe Translated using Weblate (Hungarian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2020-05-02 16:11:02 +02:00
Balázs Meskó
161b4cb5f5 Translated using Weblate (Hungarian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2020-05-02 16:11:02 +02:00
Anonymous
f9bee68d71 Translated using Weblate (Hungarian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2020-05-02 16:10:34 +02:00
Balázs Meskó
e0d98aca1b Translated using Weblate (Hungarian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2020-05-02 16:08:07 +02:00
sshshsjsjaja
d47518c00c 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-02 15:55:55 +02:00
J-Jamet
58f97dc3ab Upgrade to versionCode 33 2020-05-01 13:48:54 +02:00
J-Jamet
c7706cb80c Merge tag '2.5RC2' into develop
2.5RC2
2020-05-01 13:29:00 +02:00
J-Jamet
49bcc877ef Merge branch 'release/2.5RC2' 2020-05-01 13:28:50 +02:00
J-Jamet
4b81dd552e Update screens 2020-05-01 13:11:31 +02:00
J-Jamet
ff63aaf3f3 Remove unused file types 2020-04-30 21:14:15 +02:00
J-Jamet
39cbd1477b Upgrade CHANGELOG 2020-04-30 18:19:37 +02:00
J-Jamet
3741cc558a Remove field reference URL 2020-04-30 18:02:12 +02:00
J-Jamet
2a314ca3c1 Merge branch 'translations' into develop 2020-04-30 17:51:50 +02:00
J-Jamet
10f9564825 Remove unused comment 2020-04-30 17:51:23 +02:00
J-Jamet
1ae87c9b18 Fix small string issues 2020-04-30 17:50:10 +02:00
J-Jamet
24301ba462 Fix string strong tag 2020-04-30 17:43:19 +02:00
J-Jamet
ff6481274f Fix small string bug 2020-04-30 17:36:43 +02:00
J-Jamet
866df585a2 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-04-30 17:24:48 +02:00
J-Jamet
416bec04a1 Fix context 2020-04-30 17:07:52 +02:00
J-Jamet
f747d6725e Add flavor dimension 2020-04-30 17:03:43 +02:00
J-Jamet
8846918e55 Fix file manager dialog 2020-04-30 16:30:52 +02:00
J-Jamet
e347aefcd9 Manual merge of strings #460 2020-04-30 16:04:41 +02:00
J-Jamet
0a0676af3a Android backup management 2020-04-30 15:45:30 +02:00
Mik
7a69b63b4f Translated using Weblate (Italian)
Currently translated at 97.0% (421 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-30 03:32:39 +02:00
J-Jamet
fab5626741 Fix error message in password generator 2020-04-29 17:46:33 +02:00
J-Jamet
c6832d6478 Check permission in onResume 2020-04-29 16:56:47 +02:00
J-Jamet
f451597746 Add thread sleep 2020-04-29 16:35:17 +02:00
J-Jamet
a92e5b5156 Remove dialog task listener (issue dialog still in view) 2020-04-29 15:16:58 +02:00
J-Jamet
786b3b26ea Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-04-28 21:42:40 +02:00
J-Jamet
2e9fd2fd79 Merge branch 'feature/fix_opening' into develop 2020-04-28 21:42:18 +02:00
J-Jamet
3be2b9893b Move onActionFinish?.invoke(actionTask, result) 2020-04-26 20:00:47 +02:00
J-Jamet
7f6bed4f5f Replace EditText by TextInputEditText in InputLayout 2020-04-26 10:51:16 +02:00
J-Jamet
37322f284a Merge branch 'develop' into feature/fix_opening 2020-04-26 10:17:46 +02:00
J-Jamet
4106bb1792 Fix lock loop 2020-04-26 10:16:56 +02:00
J-Jamet
229db1242a Listener for task dialog 2020-04-26 09:10:18 +02:00
J-Jamet
8201b42135 Fix progress task dialog 2020-04-25 15:41:33 +02:00
J-Jamet
24818575dc Finish database task only if a binder is attach (to fix too fast opening) 2020-04-25 14:19:50 +02:00
J-Jamet
213050e7f2 Better task listener implementation 2020-04-24 22:09:46 +02:00
J-Jamet
1efaf4e3ea Kotlinized VariantDictionnary and fix database creation 2020-04-24 20:35:36 +02:00
J-Jamet
5532147992 Update CHANGELOG 2020-04-24 18:32:11 +02:00
J-Jamet
550b43094d Fix default username in existing entry #535 2020-04-24 18:30:17 +02:00
J-Jamet
5e831837c8 Update gradle kotlin 2020-04-24 18:20:07 +02:00
J-Jamet
480e88a088 Update gradle 2020-04-24 18:19:35 +02:00
J-Jamet
81cbcbe8af Upgrade TapTargetView lib to 1.13.0 2020-04-24 18:15:17 +02:00
J-Jamet
5649634809 Fix toolbar icon color after theme change 2020-04-24 17:55:44 +02:00
J-Jamet
69a253f738 Remove unused preference theme 2020-04-23 22:39:04 +02:00
J-Jamet
fbc8cfddb8 Fix purple style 2020-04-23 21:59:32 +02:00
J-Jamet
3e1024804c Try to fix preference icons 2020-04-23 21:37:24 +02:00
J-Jamet
cf0b51be00 Fix style purple 2020-04-23 17:53:44 +02:00
J-Jamet
5b295a2a8f Fix pref icon color for KitKat 2020-04-23 15:23:23 +02:00
Andrew
ebb3d7a149 Translated using Weblate (Russian)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-04-23 15:11:22 +02:00
J-Jamet
73ab348d11 Fix keyfile name view 2020-04-23 14:59:21 +02:00
J-Jamet
8ce17086f8 Fix show lock button in setting orientation change 2020-04-23 14:51:32 +02:00
J-Jamet
45cffc93b1 Try to fix theme issue #509 2020-04-23 14:32:59 +02:00
J-Jamet
71cf4d5a34 Fix requireContext, requireArguments and import 2020-04-23 13:43:57 +02:00
J-Jamet
b79a4154af Fix deprecated FragmentManager 2020-04-23 13:35:42 +02:00
J-Jamet
ff818f8472 Upgrade Preference lib 2020-04-23 12:37:12 +02:00
Kunzisoft
b540d32ca3 Added translation using Weblate (Bulgarian) 2020-04-23 09:45:08 +02:00
J-Jamet
895a11d45f Fix opening database wait 2020-04-22 21:07:56 +02:00
J-Jamet
bdafae6132 Fix small warning 2020-04-22 20:50:59 +02:00
J-Jamet
f45d9ce6da Merge branch 'feature/UnsignedValues' into develop 2020-04-22 20:33:35 +02:00
J-Jamet
7456e2c8f5 Refactor key encryption methods and add unit tests 2020-04-22 20:23:23 +02:00
J-Jamet
fc51b50fe6 Fix download_progression string 2020-04-22 18:57:55 +02:00
J-Jamet
b31aa26975 Update CHANGELOG 2020-04-22 18:51:32 +02:00
J-Jamet
49801e1b14 Merge branch 'feature/KeeWeb_Database' into develop 2020-04-22 18:49:50 +02:00
J-Jamet
1453464cbd Remove unused code 2020-04-22 17:46:00 +02:00
J-Jamet
b9be8ff13d Fix KDBX header reader for KeeWeb database #533 2020-04-22 17:30:20 +02:00
J-Jamet
9663c3cadd Add UnsignedInt and UnsignedLong 2020-04-22 15:55:21 +02:00
J-Jamet
da5490bc0a Remove unused import 2020-04-22 15:37:40 +02:00
anonymous
df9b1b9fbb Translated using Weblate (Russian)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-04-22 14:33:57 +02:00
zeritti
6a0a3ded13 Translated using Weblate (Czech)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-04-21 19:11:21 +02:00
J-Jamet
ac7f4a08c3 Replace empty recycle bin icon 2020-04-20 19:12:16 +02:00
J-Jamet
e5ff5e3364 Update CHANGELOG 2020-04-20 19:09:24 +02:00
J-Jamet
f0ac19fcc1 Fix "Go" button #523 2020-04-20 19:07:09 +02:00
J-Jamet
ce23d34923 Fix #530 2020-04-20 18:41:57 +02:00
WaldiS
bdbba87f5a Translated using Weblate (Polish)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-04-20 04:11:21 +02:00
Filippo De Bortoli
fa8ef0477b Translated using Weblate (Italian)
Currently translated at 89.1% (387 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-20 04:11:21 +02:00
Jeannette L
3e9ec4cfb6 Translated using Weblate (Italian)
Currently translated at 89.1% (387 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-20 04:11:20 +02:00
J-Jamet
ad1c9d8129 Merge branch 'feature/SearchParameters' into develop 2020-04-18 13:09:39 +02:00
J-Jamet
7aaac4c13c Encapsulate search and UUID hex string 2020-04-18 13:09:17 +02:00
J-Jamet
a6c71c3d54 StringUtil refactoring 2020-04-18 11:29:51 +02:00
J-Jamet
05714f38dc Add search in url for search info 2020-04-18 11:23:20 +02:00
J-Jamet
4ef5e4d8ae Refactor search parameters and Autofill search 2020-04-17 16:15:55 +02:00
Oğuz Ersen
5fd0e1d6fe Translated using Weblate (Turkish)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-16 13:11:25 +02:00
Allan Nordhøy
97faf5bef3 Translated using Weblate (Norwegian Bokmål)
Currently translated at 79.0% (343 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-04-16 13:11:25 +02:00
Destiny Li
bd77128733 Translated using Weblate (English)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-04-16 13:11:24 +02:00
Destiny Li
935debc6bf Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-04-16 13:11:24 +02:00
solokot
699ed19b6a Translated using Weblate (Russian)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-04-16 13:11:24 +02:00
Jeannette L
126e5a94c2 Translated using Weblate (French)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-04-16 13:11:23 +02:00
sshshsjsjaja
792bd36ea7 Translated using Weblate (German)
Currently translated at 100.0% (434 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-04-16 13:11:23 +02:00
jan madsen
04dfee1b43 Translated using Weblate (Danish)
Currently translated at 99.0% (430 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-04-16 13:11:23 +02:00
Carles Sadurní
6a08cfeea9 Translated using Weblate (Catalan)
Currently translated at 61.0% (265 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ca/
2020-04-16 13:11:22 +02:00
J-Jamet
29a0f6c9f6 Small amelioration 2020-04-15 20:06:14 +02:00
J-Jamet
e2bdf26d82 Fix autofill crash #520 2020-04-15 14:44:13 +02:00
Kunzisoft
1643949110 Translated using Weblate (French)
Currently translated at 99.7% (433 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-04-15 12:50:29 +02:00
J-Jamet
577dabd727 Better HashedBlockOutputStream implementation 2020-04-15 12:11:45 +02:00
J-Jamet
ed4bd0693f Fix small warning 2020-04-15 12:02:51 +02:00
J-Jamet
0f2982b34d Try to fix bad icon exception 2020-04-15 11:52:22 +02:00
C. Rüdinger
0954094800 Translated using Weblate (German)
Currently translated at 98.6% (428 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-04-14 23:35:52 +02:00
sshshsjsjaja
22dcfafc62 Translated using Weblate (German)
Currently translated at 98.6% (428 of 434 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-04-14 23:35:51 +02:00
J-Jamet
dd34051426 Update CHANGELOG 2020-04-14 20:28:25 +02:00
J-Jamet
6feaf2cb8a Update Autofill compatibility 2020-04-14 20:27:08 +02:00
J-Jamet
603f64ea92 Check TODOs 2020-04-14 20:23:50 +02:00
J-Jamet
568f9ab0d0 Check TODOs 2020-04-14 19:54:02 +02:00
J-Jamet
a2ff1c33e6 Update CHANGELOG 2020-04-14 19:33:29 +02:00
J-Jamet
84452e9fc0 Spongy Castle by Bouncy Castle replacement 2020-04-13 13:39:45 +02:00
J-Jamet
5a6ae453cf Upgrade strings comments 2020-04-13 10:03:49 +02:00
Hosted Weblate
cde3e3361d Merge branch 'origin/master' into Weblate. 2020-04-13 08:58:48 +02:00
Oğuz Ersen
25f01192a4 Translated using Weblate (Turkish)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-13 08:58:47 +02:00
Carles Sadurní
bacb08ec65 Translated using Weblate (Catalan)
Currently translated at 16.7% (72 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ca/
2020-04-13 08:58:47 +02:00
anonymous
36c905ee1c Translated using Weblate (Catalan)
Currently translated at 18.1% (78 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ca/
2020-04-12 22:44:08 +02:00
Carles Sadurní
6b9280534a Translated using Weblate (Catalan)
Currently translated at 18.1% (78 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ca/
2020-04-12 22:44:08 +02:00
J-Jamet
f94c6e850f Add History of each entry in description 2020-04-12 21:20:54 +02:00
J-Jamet
f4cecf6906 Upgrade to version 2.5 2020-04-12 20:51:02 +02:00
J-Jamet
a81d3766f8 Merge tag '2.5RC1' into develop
2.5RC1
2020-04-12 20:32:12 +02:00
J-Jamet
7182c2e66d Merge branch 'release/2.5RC1' 2020-04-12 20:32:03 +02:00
J-Jamet
503316bc70 Fix navigation bar color for light theme 2020-04-12 20:08:39 +02:00
J-Jamet
d5af59f2c7 Merge branch 'translations' into release/2.5RC1 2020-04-12 20:03:44 +02:00
J-Jamet
cb3ac1ad3a version 2.5RC1 2020-04-12 19:36:51 +02:00
J-Jamet
e161080e4c Fix special button 2020-04-11 17:36:24 +02:00
J-Jamet
ceab7f917b Upgrade CHANGELOG 2020-04-11 16:21:27 +02:00
J-Jamet
41d8066c4c Fix autofill bad recognition for key-value format #513 2020-04-11 16:16:50 +02:00
J-Jamet
e373cbd776 File manager explanation link 2020-04-11 12:23:46 +02:00
J-Jamet
05ea6b6b10 Change background color and fix bottom button 2020-04-10 20:37:56 +02:00
J-Jamet
28eed3ae71 New file selection layout 2020-04-10 20:15:08 +02:00
Mert Sezer
535c67ac9b Translated using Weblate (Turkish)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-10 16:09:45 +02:00
J-Jamet
68027a6e15 Linkfy notes #426 2020-04-10 13:22:26 +02:00
J-Jamet
12dea6b499 Add new autofill hint for username 2020-04-10 12:32:38 +02:00
J-Jamet
d8bd078a02 Fix custom fields duplication #257 2020-04-10 11:32:23 +02:00
J-Jamet
439bc109b0 Update CHANGELOG 2020-04-09 21:42:16 +02:00
J-Jamet
b1ec93ceb5 Add navigation bar color #510 2020-04-09 21:38:32 +02:00
J-Jamet
44b9aa0e48 Style black as separate file 2020-04-09 21:31:48 +02:00
J-Jamet
0a59063027 Add scrollbar in nodes list 2020-04-09 20:33:12 +02:00
Oğuz Ersen
5db4608abd Translated using Weblate (Turkish)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-09 06:45:37 +02:00
J-Jamet
6ece2aa6cb Add autofill web domain and app id 2020-04-08 20:50:28 +02:00
J-Jamet
95ee45f666 Merge branch 'feature/Autofill_Domain' into develop 2020-04-08 17:55:42 +02:00
J-Jamet
556e90b8d8 Fix autofill response 2020-04-08 17:17:29 +02:00
J-Jamet
42841e6247 Setting for autofill automatic search 2020-04-08 16:55:30 +02:00
J-Jamet
324c82248a Refactor magikeyboard settings and add autofill settings 2020-04-08 15:44:14 +02:00
J-Jamet
94f5a47918 Catch exception during autofill parse 2020-04-08 14:11:18 +02:00
J-Jamet
3f70990956 Better autofill workflow and add autofill icon for each entry 2020-04-08 13:02:15 +02:00
J-Jamet
d77635e572 Fix autofill auto search 2020-04-07 21:01:26 +02:00
solokot
0f26f1b751 Translated using Weblate (Russian)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-04-07 01:36:50 +02:00
J-Jamet
456bc22138 Encapsulate search methods and search without UI 2020-04-06 21:43:55 +02:00
J-Jamet
b6fe91e396 Fix small warning 2020-04-06 21:36:50 +02:00
J-Jamet
0fb4d26949 Add auto search info 2020-04-06 17:36:51 +02:00
J-Jamet
3b3583a416 Retrieve application id and domain 2020-04-06 11:41:16 +02:00
J-Jamet
cac1d576c8 Upgrade Autofill algorithm 2020-04-06 10:33:44 +02:00
J-Jamet
9cba0d0a48 Message to indicate file revoked 2020-04-06 10:12:09 +02:00
J-Jamet
3bf11e9dc0 Remove unused import 2020-04-06 09:41:02 +02:00
Fabio Iacovino
edbb160ac6 Translated using Weblate (Italian)
Currently translated at 90.4% (388 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-06 00:22:25 +02:00
WaldiS
ee111dc63c Translated using Weblate (Polish)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-04-05 17:58:26 +02:00
Filippo De Bortoli
b06edb756a Translated using Weblate (Italian)
Currently translated at 89.7% (385 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-05 17:13:40 +02:00
anonymous
fd745494e0 Translated using Weblate (Italian)
Currently translated at 89.7% (385 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-05 17:13:40 +02:00
Fabio Iacovino
702bf3f479 Translated using Weblate (Italian)
Currently translated at 89.7% (385 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-05 17:13:40 +02:00
Fabio Iacovino
6adc02a91f Translated using Weblate (Italian)
Currently translated at 85.3% (366 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-05 17:07:29 +02:00
anonymous
55bae5a130 Translated using Weblate (Italian)
Currently translated at 85.3% (366 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-05 17:07:29 +02:00
Filippo De Bortoli
1aae817b17 Translated using Weblate (Italian)
Currently translated at 85.3% (366 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-04-05 17:07:29 +02:00
Oğuz Ersen
8afc8c23fb Translated using Weblate (Turkish)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-05 03:01:39 +02:00
Allan Nordhøy
36e473b139 Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.6% (329 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-04-05 03:01:38 +02:00
Allan Nordhøy
e529723f86 Translated using Weblate (English)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-04-05 03:01:38 +02:00
Dwhite Reeves
6c5112c142 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-04-05 03:01:38 +02:00
Allan Nordhøy
77ac68a603 Translated using Weblate (Dutch)
Currently translated at 77.6% (333 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-04-05 03:01:37 +02:00
Éfrit
e816f40872 Translated using Weblate (French)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-04-05 03:01:37 +02:00
zeritti
65313f114b Translated using Weblate (Czech)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-04-05 03:01:37 +02:00
J-Jamet
ef1f1342f5 Upgrade CHANGELOG 2020-04-04 18:49:22 +02:00
J-Jamet
9205fe6c08 Merge branch 'feature/Lock_Button' into develop 2020-04-04 18:43:03 +02:00
J-Jamet
75df3e81fe Fix style 2020-04-04 18:42:35 +02:00
J-Jamet
47fffbadb5 Setting to show the lock button 2020-04-04 18:25:48 +02:00
J-Jamet
78354473fa Fix lock button color and education screen 2020-04-04 17:53:04 +02:00
J-Jamet
8d7efb44b5 Change lock button color 2020-04-03 22:21:50 +02:00
J-Jamet
cab00b3d8c Change lock button color 2020-04-03 22:18:33 +02:00
Mert Sezer
8efab01336 Translated using Weblate (Turkish)
Currently translated at 99.5% (427 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-03 21:41:26 +02:00
Oğuz Ersen
66feb8beb4 Translated using Weblate (Turkish)
Currently translated at 99.5% (427 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-03 21:41:26 +02:00
Mert Sezer
ca4cccffeb Translated using Weblate (Turkish)
Currently translated at 99.3% (426 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-03 21:40:34 +02:00
Oğuz Ersen
51b1760c50 Translated using Weblate (Turkish)
Currently translated at 99.3% (426 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-03 21:40:33 +02:00
J-Jamet
42e1bda365 Change lock button color 2020-04-03 21:32:32 +02:00
J-Jamet
194b6b557a Add lock button elevation and border 2020-04-03 21:17:38 +02:00
Dwhite Reeves
e7bc439997 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-04-03 15:44:41 +02:00
Allan Nordhøy
ef76cce0ac Translated using Weblate (Romanian)
Currently translated at 95.3% (409 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-04-03 13:26:34 +02:00
Allan Nordhøy
63eec6d969 Translated using Weblate (Turkish)
Currently translated at 96.9% (416 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-03 13:26:34 +02:00
WaldiS
719ae74c06 Translated using Weblate (Polish)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-04-03 13:26:33 +02:00
Mert Sezer
37cf424eb8 Translated using Weblate (Turkish)
Currently translated at 96.9% (416 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-01 17:46:51 +02:00
anonymous
3a87f7ba9d Translated using Weblate (Turkish)
Currently translated at 96.9% (416 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-04-01 17:46:50 +02:00
J-Jamet
275428d825 First commit for new lock button 2020-04-01 14:57:31 +02:00
Pavel Borecki
7b9dac86ca Translated using Weblate (Czech)
Currently translated at 96.7% (415 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-04-01 03:28:42 +02:00
J-Jamet
46496ee2cc Merge branch 'damoasda-translation-update' into develop 2020-03-31 21:58:21 +02:00
J-Jamet
110cc402cc Add keyfile selection view 2020-03-31 21:48:51 +02:00
J-Jamet
587f006259 Long click to use GET_CONTENT 2020-03-31 19:46:43 +02:00
Moasda
ec45c0df81 Translated using Weblate (German)
Currently translated at 99.7% (428 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-30 22:24:51 +02:00
jan madsen
dc575aeca4 Translated using Weblate (Danish)
Currently translated at 98.3% (422 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-03-30 22:24:51 +02:00
Herbert Reiter
a3f790f000 Fix inconsistencies with translation arguments (e.g. %1$s), escape % character 2020-03-30 22:08:50 +02:00
Herbert Reiter
4e9e188d02 Add and fix German translations 2020-03-30 22:03:09 +02:00
J-Jamet
abb17efae4 Merge branch 'feature/File_Manager_Access' into develop 2020-03-30 18:17:24 +02:00
Hosted Weblate
16be990502 Merge branch 'origin/master' into Weblate. 2020-03-30 08:48:35 +02:00
anonymous
d1a496f9a3 Translated using Weblate (German)
Currently translated at 99.7% (428 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-30 03:17:18 +02:00
Allan Nordhøy
cd730fcfef Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.9% (330 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-03-29 23:06:21 +02:00
Moasda
1b65bf665b Translated using Weblate (German)
Currently translated at 99.7% (428 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-29 23:06:21 +02:00
J-Jamet
6f4735790c Fix autofill for Android app #502 2020-03-29 22:00:24 +02:00
J-Jamet
040666f89d Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2020-03-29 20:19:42 +02:00
J-Jamet
227cb800c3 Merge branch 'damoasda-readme-fix' 2020-03-29 16:15:44 +02:00
Herbert Reiter
0052569a14 Fix FAQ link to wiki page 2020-03-29 15:41:49 +02:00
J-Jamet
f7561c4888 Upgrade to version 2.5beta31 2020-03-29 15:22:34 +02:00
Destiny Li
92200f19e7 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-29 14:09:36 +02:00
Éfrit
4c01f18a62 Translated using Weblate (French)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-03-29 14:09:36 +02:00
anonymous
a6ce3e49fe Translated using Weblate (German)
Currently translated at 99.5% (427 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-29 14:09:36 +02:00
Oliver
1b3a5d1bf6 Translated using Weblate (German)
Currently translated at 99.5% (427 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-29 14:09:35 +02:00
J-Jamet
db7bdc63c8 Fix #501 2020-03-28 18:13:09 +01:00
J-Jamet
7aca550f02 Merge branch 'develop' into feature/File_Manager_Access 2020-03-28 17:47:14 +01:00
J-Jamet
b60980b3fd Upgrade to 2.5beta31 2020-03-28 17:46:50 +01:00
J-Jamet
b578c2c584 Add write permission 2020-03-28 17:30:57 +01:00
solokot
fc45bd624e Translated using Weblate (Russian)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-27 20:06:43 +01:00
anonymous
17be3d9d2c Translated using Weblate (Russian)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-27 20:03:48 +01:00
solokot
5b3a38a7bc Translated using Weblate (Russian)
Currently translated at 100.0% (429 of 429 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-27 20:03:47 +01:00
Hosted Weblate
4403835d50 Merge branch 'origin/master' into Weblate. 2020-03-27 18:36:55 +01:00
C. Rüdinger
b7a3d3eb46 Translated using Weblate (German)
Currently translated at 99.5% (424 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-27 18:36:54 +01:00
J-Jamet
29846b22fe Merge tag '2.5beta30' into develop
2.5beta30
2020-03-27 18:13:28 +01:00
J-Jamet
32d235e8c7 Merge branch 'release/2.5beta30' 2020-03-27 18:13:21 +01:00
J-Jamet
cb982b3513 Fix strong tag 2020-03-27 17:53:42 +01:00
J-Jamet
d7ed6c26dd Merge branch 'develop' into translations 2020-03-27 17:49:29 +01:00
J-Jamet
8ff19f7e68 First string pass according to #460 2020-03-27 17:43:31 +01:00
J-Jamet
729e062c3a Add error when create database file 2020-03-27 17:12:54 +01:00
J-Jamet
7d0340ac07 Upgrade CHANGELOG 2020-03-27 16:57:35 +01:00
J-Jamet
01960e74c1 Fix check file ANR #494 2020-03-27 16:36:57 +01:00
anonymous
8e40250985 Translated using Weblate (German)
Currently translated at 96.4% (411 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-27 00:46:37 +01:00
C. Rüdinger
8ae2edb61a Translated using Weblate (German)
Currently translated at 96.4% (411 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-27 00:46:37 +01:00
J-Jamet
0baa7bcbf1 Change discard button 2020-03-26 16:36:17 +01:00
J-Jamet
fffee48918 Upgrade version to 2.5beta30 2020-03-26 14:50:20 +01:00
J-Jamet
515abb6e14 Better UUID view 2020-03-26 14:45:51 +01:00
J-Jamet
6c1c3ff87f New method to wait 1.5 seconds after screen turns off 2020-03-26 13:38:20 +01:00
J-Jamet
5b65575c7a Add comment to ignore autocomplete off 2020-03-26 12:57:24 +01:00
J-Jamet
0f258fc5f8 Upgrade autofill algorithm 2020-03-26 12:47:32 +01:00
anonymous
206bc661dc Translated using Weblate (German)
Currently translated at 96.2% (410 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-25 23:44:32 +01:00
J-Jamet
d0e35b109e Revert : Fix Nextcloud File Upload conflict #497 2020-03-25 22:48:15 +01:00
J-Jamet
61769c4f20 Fix Nextcloud File Upload conflict #497 2020-03-25 21:07:36 +01:00
Hosted Weblate
95778ee5f4 Merge branch 'origin/master' into Weblate. 2020-03-25 12:21:35 +01:00
anonymous
155030fdca Translated using Weblate (Italian)
Currently translated at 79.5% (339 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-03-25 12:21:35 +01:00
Filippo De Bortoli
98237ef76c Translated using Weblate (Italian)
Currently translated at 79.5% (339 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-03-25 12:21:34 +01:00
J-Jamet
f0a7b38199 Merge tag '2.5beta29' into develop
2.5beta29
2020-03-25 12:06:20 +01:00
J-Jamet
9fc5e6751b Merge branch 'release/2.5beta29' 2020-03-25 12:06:08 +01:00
J-Jamet
4c1630312b Add UUID color 2020-03-25 11:46:43 +01:00
J-Jamet
d397c5c996 Add UUID ref for entry 2020-03-25 11:22:19 +01:00
J-Jamet
f6c41b5a60 Replace the strong nodes 2020-03-24 20:49:33 +01:00
J-Jamet
06eb5c01c3 Update versions 2020-03-24 20:44:50 +01:00
J-Jamet
7df49f91e8 Merge branch 'release/2.5beta29' of github.com:Kunzisoft/KeePassDX into release/2.5beta29 2020-03-24 20:10:27 +01:00
J-Jamet
96dcbb0ce7 Merge branch 'develop' into release/2.5beta29 2020-03-24 20:09:47 +01:00
J-Jamet
5f828fb986 Fix setting 2020-03-24 20:09:30 +01:00
J-Jamet
533d663938 Merge branch 'translations' into develop 2020-03-24 19:44:38 +01:00
J-Jamet
ae788503a9 Fix html_about licence 2020-03-24 19:44:15 +01:00
anonymous
cf0acd9c73 Translated using Weblate (Italian)
Currently translated at 78.4% (334 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-03-24 11:42:45 +01:00
Filippo De Bortoli
0857f2f1cf Translated using Weblate (Italian)
Currently translated at 78.4% (334 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-03-24 11:42:43 +01:00
Ema Panz
c05d412bdb Translated using Weblate (Italian)
Currently translated at 71.1% (303 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-03-24 11:18:14 +01:00
anonymous
c8e0ce717d Translated using Weblate (Italian)
Currently translated at 71.1% (303 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-03-24 11:18:14 +01:00
J-Jamet
cc3485b201 Update Readme 2020-03-23 21:10:28 +01:00
J-Jamet
81ea7080c2 Show UUID as KeePass UUID 2020-03-21 20:25:37 +01:00
J-Jamet
76ff6f5ae0 Fix reference loop 2020-03-21 19:01:05 +01:00
J-Jamet
0c0d0b7a6f Encapsulate readonly for launch method 2020-03-21 17:23:17 +01:00
J-Jamet
ec8cf1f6b7 Move autofill setting up 2020-03-21 17:16:49 +01:00
J-Jamet
da44310d1b Fix focus validation button 2020-03-21 17:03:36 +01:00
J-Jamet
4bd9c84bb0 Add dialog to validate discard entry changes 2020-03-21 16:52:50 +01:00
J-Jamet
3b1269a770 Fix bind listeners 2020-03-21 16:12:07 +01:00
J-Jamet
7c986ccee8 Fix card_view_margin issue 2020-03-21 16:08:23 +01:00
J-Jamet
903bad8f36 Fix launch of open db service exception 2020-03-21 14:36:33 +01:00
J-Jamet
4b9577437c Hide add button when nodes are selected 2020-03-21 12:27:18 +01:00
J-Jamet
c316011fbc Show toast on invalid key exception 2020-03-21 12:16:45 +01:00
J-Jamet
3fb1f18c22 Education screen for OTP and entry edit menu 2020-03-19 19:47:51 +01:00
J-Jamet
53935058f5 Add OTP icon 2020-03-19 19:16:38 +01:00
J-Jamet
a3860c9581 Generate password icon as dice 2020-03-19 18:34:14 +01:00
J-Jamet
dc20899d26 Update CHANGELOG 2020-03-19 17:48:56 +01:00
J-Jamet
62ac3ddb75 Merge branch 'feature/Autofill_Improvement' into develop 2020-03-19 17:23:24 +01:00
J-Jamet
b792a61bf9 Improve hint "on" and "off" recognition 2020-03-19 15:18:06 +01:00
J-Jamet
aae9f9e1cb Warning when cancel autofill 2020-03-19 14:59:33 +01:00
J-Jamet
d098bf5e6a Upgrade Autofill algorithm 2020-03-19 14:35:22 +01:00
J-Jamet
b0e8a3ecd9 Add expiration datetime 2020-03-18 12:03:12 +01:00
J-Jamet
4efa684022 Merge branch 'feature/Edit_Expired_Date' into develop 2020-03-18 11:53:46 +01:00
J-Jamet
f2c8082990 Fix date picker kitkat issue 2020-03-18 11:53:21 +01:00
J-Jamet
1abba80045 Fix dialog theme 2020-03-18 11:45:52 +01:00
J-Jamet
68564a2b75 Merge branch 'develop' into feature/Edit_Expired_Date 2020-03-18 09:46:28 +01:00
J-Jamet
385b701b38 Fix cardview margin 2020-03-18 09:42:36 +01:00
Éfrit
11c9a1d707 Translated using Weblate (French)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-03-17 00:42:55 +01:00
J-Jamet
c5aef6b561 New entry edit tool menu style 2020-03-15 12:21:26 +01:00
J-Jamet
dfcf73cfd0 Merge branch 'develop' into feature/Edit_Expired_Date 2020-03-14 21:15:58 +01:00
J-Jamet
7fc9389700 Always show menu 2020-03-14 21:15:37 +01:00
J-Jamet
d1af7349bc Edit button as validation 2020-03-14 20:51:47 +01:00
J-Jamet
0fd955197d Expires selection 2020-03-14 20:16:36 +01:00
Destiny Li
cbf33507d1 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-14 17:37:29 +01:00
WaldiS
bc60a5d97e Translated using Weblate (Polish)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-03-14 17:37:27 +01:00
zeritti
57596b2991 Translated using Weblate (Czech)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-03-14 17:37:23 +01:00
solokot
43b3602a52 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-14 17:37:22 +01:00
J-Jamet
c09ec961b8 Merge branch 'feature/Entry_Edit_BottomBar' into develop 2020-03-14 11:00:47 +01:00
J-Jamet
d140b453b2 Merge branch 'feature/Entry_Edit_BottomBar' into develop 2020-03-14 10:36:52 +01:00
J-Jamet
9eb42636ec Change read icons 2020-03-13 21:58:32 +01:00
J-Jamet
ee2d663fce New icons for entry edit tools 2020-03-13 21:33:38 +01:00
J-Jamet
8e83615a22 Add Edit Toolbar menu on top 2020-03-13 17:06:09 +01:00
J-Jamet
0ff129c5ca Edit Entry with Card View 2020-03-13 11:06:56 +01:00
WaldiS
e49858439f Translated using Weblate (Polish)
Currently translated at 99.5% (424 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-03-12 20:33:30 +01:00
zeritti
3df07f7f47 Translated using Weblate (Czech)
Currently translated at 99.5% (424 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-03-12 20:33:30 +01:00
Aurel F
ff9e179593 Translated using Weblate (Romanian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-03-12 20:33:28 +01:00
J-Jamet
7539fee04b Add BottomBar in EntryEdit 2020-03-12 19:15:03 +01:00
J-Jamet
71a339a58f Suppress small warning 2020-03-12 17:15:17 +01:00
J-Jamet
9ef2ea016b Suppress deprecation for Keyboard 2020-03-12 17:14:46 +01:00
J-Jamet
de4936a16d Set nullable getSystemService 2020-03-12 17:05:53 +01:00
J-Jamet
574d2b8904 Wait 3 seconds before the lock after the screen turns off #59 2020-03-12 16:56:46 +01:00
J-Jamet
1f3f7634e7 Allow empty title in entries #423 2020-03-12 14:41:02 +01:00
J-Jamet
3c0725baff Fix remember key file option 2020-03-12 14:24:33 +01:00
J-Jamet
b0e1411012 Update CHANGELOG 2020-03-12 14:20:48 +01:00
J-Jamet
39daf4714d Merge branch 'feature/Delete_Registered_Keyfile_New_Credentials' into develop 2020-03-12 14:17:35 +01:00
J-Jamet
4706afa823 Fix credentials options 2020-03-12 14:16:30 +01:00
J-Jamet
25977d389d Add DAO command to delete registered keyfile 2020-03-12 13:18:36 +01:00
J-Jamet
f760110569 default_database_path_key in strings.xml 2020-03-12 09:28:46 +01:00
J-Jamet
133e78fe97 Update CHANGELOG 2020-03-12 09:20:29 +01:00
J-Jamet
d92e0c8620 Fix magikeyboard lock 2020-03-11 19:17:51 +01:00
J-Jamet
62fdb69d6b Fix small element 2020-03-11 18:56:45 +01:00
J-Jamet
def57c9fb2 Merge branch 'feature/Lock_Database' issue 483 2020-03-11 18:42:34 +01:00
J-Jamet
21c9c898c3 Add lock timer in service, notification remains lock to capture the broadcast 2020-03-11 18:30:11 +01:00
J-Jamet
1f03c922c2 Encapsulate lock broadcast 2020-03-11 16:46:44 +01:00
J-Jamet
3f6ae6bdac Fix node update #487 2020-03-11 12:42:18 +01:00
jan madsen
60615ee1eb Translated using Weblate (Danish)
Currently translated at 98.5% (420 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-03-10 20:23:08 +01:00
J-Jamet
92b0d1bfa9 Upgrade to version 2.5beta29 2020-03-10 19:02:37 +01:00
J-Jamet
237988dc1f Merge tag '2.5beta28' into develop
2.5beta28
2020-03-10 19:00:08 +01:00
J-Jamet
a846ec29ca Merge branch 'release/2.5beta28' 2020-03-10 18:59:59 +01:00
J-Jamet
4533e96bff Upgrade CHANGELOG 2020-03-10 18:48:57 +01:00
J-Jamet
0a401c3ac9 Fix strings 2020-03-10 18:41:35 +01:00
J-Jamet
468abaf077 Fix strings 2020-03-10 18:29:19 +01:00
J-Jamet
4ccf2f641c Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into develop 2020-03-10 18:14:14 +01:00
Dominik Baláž
34eb2785cf Translated using Weblate (Slovak)
Currently translated at 21.5% (92 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sk/
2020-03-10 17:21:26 +01:00
anonymous
09dbfe323e Translated using Weblate (Slovak)
Currently translated at 21.5% (92 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sk/
2020-03-10 17:21:26 +01:00
Destiny Li
1f06c5b425 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-10 11:33:21 +01:00
Destiny Li
b98e089f7a Translated using Weblate (Chinese (Traditional))
Currently translated at 48.3% (206 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2020-03-10 11:33:20 +01:00
Aurel F
a0ad06ed0a Translated using Weblate (Romanian)
Currently translated at 40.8% (174 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-03-10 11:33:18 +01:00
solokot
ec63365429 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-10 11:33:10 +01:00
J-Jamet
2cb85e4346 Update items after appearance change #452 2020-03-10 08:58:22 +01:00
J-Jamet
0d7c479c51 Merge branch 'feature/Migration_SDK_29' into develop 2020-03-10 08:40:53 +01:00
J-Jamet
5a6c21e662 Try to fix read only bug #480 2020-03-10 08:38:49 +01:00
J-Jamet
d6cadac98f Fix small warning 2020-03-08 13:22:11 +01:00
J-Jamet
dac2fc2c37 Use PreferenceManager from AndroidX 2020-03-08 13:10:16 +01:00
J-Jamet
0fb45cef0d Encapsulate preferences 2020-03-08 13:04:25 +01:00
anonymous
5ebdbd4003 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-08 12:08:21 +01:00
Destiny Li
b30f1023cb Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-08 12:08:21 +01:00
J-Jamet
e5f65a4d1e Fix % issue in string 2020-03-08 11:48:47 +01:00
J-Jamet
ab42a65aa4 Fix null issues 2020-03-08 11:41:13 +01:00
J-Jamet
e351456bfe First pass migration SDK 29 2020-03-08 11:03:21 +01:00
J-Jamet
452e68b08f Fix C cast warning 2020-03-08 10:52:29 +01:00
J-Jamet
d65beed7a1 Fix small warnings 2020-03-08 10:49:06 +01:00
J-Jamet
f5a5a0e8cb Add generated JSON for database 2020-03-08 10:41:52 +01:00
solokot
98380a0906 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-08 10:20:37 +01:00
J-Jamet
22fe7508f3 Fix doForEachChild warning 2020-03-08 10:16:31 +01:00
J-Jamet
c8e241fc76 Fix Room incremental warning 2020-03-08 09:50:32 +01:00
J-Jamet
2c943e00d0 Fix writeEnum warning 2020-03-08 09:50:07 +01:00
J-Jamet
7ddb83b72d Fix DateFormatter warning 2020-03-08 09:36:45 +01:00
Kunzisoft
50bac01699 Translated using Weblate (French)
Currently translated at 99.7% (425 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-03-08 09:33:23 +01:00
Aurel F
e0a92dfadd Translated using Weblate (Romanian)
Currently translated at 12.2% (52 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-03-08 09:33:22 +01:00
solokot
b50c951091 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-08 09:33:17 +01:00
Kunzisoft
2f589a95a9 Translated using Weblate (English)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-03-08 09:33:15 +01:00
J-Jamet
53eac86a95 Update AndroidX dependencies and fix small warning 2020-03-08 09:17:18 +01:00
J-Jamet
9412f8955e Update kotlin to 1.3.61 2020-03-08 09:07:14 +01:00
J-Jamet
71c98d82b1 Update gradle to 5.6.4 2020-03-08 09:00:56 +01:00
J-Jamet
42c1a925b4 Upgrade app to 2.54beta28 2020-03-08 08:59:41 +01:00
J-Jamet
1e84534ffd Merge tag '2.5beta27' into develop
2.5beta27
2020-03-07 14:41:37 +01:00
J-Jamet
b087733e37 Merge branch 'release/2.5beta27' 2020-03-07 14:41:29 +01:00
J-Jamet
675efe29ac Fix unused string 2020-03-07 14:31:08 +01:00
J-Jamet
9833af8225 Update french translations 2020-03-07 14:13:10 +01:00
J-Jamet
790c624571 Fix strong html 2020-03-07 14:06:50 +01:00
J-Jamet
67a70a8453 Merge branch 'translations' into develop 2020-03-07 13:57:47 +01:00
J-Jamet
64bb05e2dd Update CHANGELOG 2020-03-07 13:29:09 +01:00
J-Jamet
c111db6e73 Rename preference keys 2020-03-07 13:25:53 +01:00
J-Jamet
24c5915bd3 Setting to request a search when opening a database #220 2020-03-07 13:18:45 +01:00
J-Jamet
04c3717618 Remove screenshot from bug report 2020-03-07 12:41:57 +01:00
J-Jamet
78275a0984 Fix search empty list 2020-03-07 12:37:46 +01:00
J-Jamet
bd908ed10d Update CHANGELOG 2020-03-07 12:01:03 +01:00
J-Jamet
5473deec95 Show URL before username when title is empty #463 2020-03-07 11:58:47 +01:00
Ettore Atalan
653258afd2 Translated using Weblate (German)
Currently translated at 99.7% (418 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-03-07 03:33:06 +01:00
J-Jamet
00a2210eea Fix button menu color 2020-03-06 17:36:02 +01:00
J-Jamet
ec5688a013 Remove autofill setting for incompatible devices 2020-03-06 17:29:48 +01:00
J-Jamet
fc0c7b5708 Update CHANGELOG 2020-03-06 15:54:02 +01:00
J-Jamet
464f7ac486 Sorted list and comparator improvement 2020-03-06 15:46:08 +01:00
solokot
fb2457146c Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-29 19:33:06 +01:00
solokot
d90870838e Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-28 19:15:38 +01:00
Andrew
8c45f23291 Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-28 19:15:37 +01:00
Kunzisoft
315a3efa52 Added translation using Weblate (Romanian) 2020-02-27 14:01:57 +01:00
J-Jamet
28abb5ae6f Delete password from starting event #461 2020-02-27 13:26:41 +01:00
J-Jamet
bb78d89682 Try to fix aliased text #414 2020-02-27 13:17:01 +01:00
J-Jamet
fd36e19168 Update CHANGELOG 2020-02-27 12:57:31 +01:00
J-Jamet
58db516e44 Fix refresh appearance settings #452 #451 2020-02-27 12:54:47 +01:00
J-Jamet
2b875e94dc Add GZip string to attachment view if database is compressed 2020-02-27 12:38:16 +01:00
J-Jamet
0ba2447f55 Change about page 2020-02-27 10:16:43 +01:00
solokot
8e684d0d3a Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-25 23:32:46 +01:00
MrEnderfall
ce3c1d4685 Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-25 23:32:46 +01:00
J-Jamet
2cd77d47eb Move up remember keyfile locations setting 2020-02-23 13:43:09 +01:00
J-Jamet
ac9366e351 Update CHANGELOGS 2020-02-23 13:39:57 +01:00
J-Jamet
af356586f8 Merge branch 'feature/Check_Broken_Link' into develop 2020-02-23 13:33:56 +01:00
J-Jamet
7650db81a4 Hide broken database links 2020-02-23 13:15:09 +01:00
J-Jamet
8925c86afd Fix remember key file after press back 2020-02-23 12:49:40 +01:00
J-Jamet
8f1836009e Fix database and keyfile locations settings 2020-02-23 12:39:39 +01:00
J-Jamet
5fcf3f9b95 Fix erasing file 2020-02-23 10:47:28 +01:00
Kunzisoft
1c466d9e40 Translated using Weblate (French)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-02-22 17:33:01 +01:00
WaldiS
b97c2d9cbc Translated using Weblate (Polish)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-02-22 17:33:01 +01:00
zeritti
3d970e4967 Translated using Weblate (Czech)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-02-22 17:33:01 +01:00
J-Jamet
765c8f53dd Remove permission variable and rename preference 2020-02-20 19:53:49 +01:00
J-Jamet
4e81caeadf Remove unused external storage permission for Sdk > 18 2020-02-20 19:41:48 +01:00
J-Jamet
08b10e4d58 Update string 2020-02-20 19:35:52 +01:00
J-Jamet
f8594f72e8 Fix small elements 2020-02-20 19:31:44 +01:00
J-Jamet
24ebee07cd Fix small elements 2020-02-20 19:26:03 +01:00
J-Jamet
a06ebb0991 Force read only when file is not writable 2020-02-20 19:20:00 +01:00
J-Jamet
cd5d4498e7 Fix small element 2020-02-20 16:11:50 +01:00
J-Jamet
0bd62780c6 Check if uri is broken 2020-02-20 14:13:11 +01:00
J-Jamet
896f9327d6 Fix error messages #431 2020-02-20 11:58:00 +01:00
J-Jamet
cc83a99efe Try to fix #465 2020-02-20 09:06:11 +01:00
J Smith
b6da20fef7 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-02-19 23:53:44 +01:00
Kunzisoft
2912678559 Translated using Weblate (French)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-02-19 23:53:38 +01:00
WaldiS
409e870ef0 Translated using Weblate (Polish)
Currently translated at 99.5% (417 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-02-19 23:53:38 +01:00
Kunzisoft
3d84074a0a Translated using Weblate (English)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-02-19 23:53:37 +01:00
Oğuz Ersen
a717fdfed4 Translated using Weblate (Turkish)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-02-19 23:53:36 +01:00
J-Jamet
be1f68015b Merge branch 'master' into develop 2020-02-17 19:05:23 +01:00
WaldiS
2c29dcf1f6 Translated using Weblate (Polish)
Currently translated at 99.0% (415 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-02-17 00:50:57 +01:00
Filip Miletic
2b1173177f Translated using Weblate (Croatian)
Currently translated at 79.4% (333 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-02-17 00:50:55 +01:00
jan madsen
3c0f7dc79c Translated using Weblate (Danish)
Currently translated at 98.8% (414 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-02-17 00:50:42 +01:00
marzzzello
39d813bf3a Translated using Weblate (German)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-02-17 00:50:40 +01:00
Filip Miletic
5e2bc0d05b Translated using Weblate (Croatian)
Currently translated at 51.3% (215 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-02-14 04:18:25 +01:00
iLocIT!
ec751159ae Translated using Weblate (German)
Currently translated at 89.5% (375 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-02-14 04:18:02 +01:00
Filip Miletic
dda8b95f83 Translated using Weblate (Croatian)
Currently translated at 11.0% (46 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-02-13 19:31:33 +01:00
Filip Miletic
286012fe2a Added translation using Weblate (Croatian) 2020-02-13 11:04:02 +01:00
Jérémy JAMET
ab27299789 Update description for other KeePass app 2020-02-12 17:09:14 +01:00
Éfrit
dfcdd5aa88 Translated using Weblate (French)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-02-11 21:50:45 +01:00
Allan Nordhøy
a05ea52689 Translated using Weblate (Italian)
Currently translated at 72.8% (305 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-02-11 21:50:45 +01:00
zeritti
de12b5de5b Translated using Weblate (Czech)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-02-11 21:50:44 +01:00
solokot
57b03eaca4 Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-11 21:50:43 +01:00
Retrial
36bd00b760 Translated using Weblate (Greek)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-02-11 21:50:42 +01:00
Oğuz Ersen
4578a9974a Translated using Weblate (Turkish)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-02-11 21:50:33 +01:00
J-Jamet
d0371f58c6 Capture exception to avoid crash after clear clipboard 2020-02-08 17:39:08 +01:00
solokot
9f80457351 Translated using Weblate (Russian)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-08 16:39:00 +01:00
J-Jamet
56daf6f676 Remove JVMOverload in ClipboardHelper 2020-02-08 12:09:12 +01:00
J-Jamet
7f7b8d423b Merge branch 'translations' into develop 2020-02-08 11:34:35 +01:00
J-Jamet
031afc80cb Fix contribution strings 2020-02-08 11:32:56 +01:00
J-Jamet
b77e28b04d Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-02-08 11:27:36 +01:00
Allan Nordhøy
2f8c3fdcfe Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.4% (341 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-02-08 11:27:15 +01:00
solokot
f501a87099 Translated using Weblate (Russian)
Currently translated at 99.8% (418 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-02-08 11:27:14 +01:00
Kunzisoft
d0ec5f26dd Translated using Weblate (English)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-02-08 11:27:13 +01:00
Mesut Akcan
97776e9329 Translated using Weblate (Turkish)
Currently translated at 98.3% (412 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-02-08 11:27:11 +01:00
Kunzisoft
a19356c49e Translated using Weblate (French)
Currently translated at 100.0% (419 of 419 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-02-08 11:21:45 +01:00
J-Jamet
4f16918cf0 Remove unused strings 2020-02-08 11:19:45 +01:00
J-Jamet
1af9761144 Merge branch 'master' into develop 2020-02-07 22:14:20 +01:00
J-Jamet
d74e814c79 Fix fastlane data 2020-02-07 22:05:58 +01:00
J-Jamet
16d09bca6c Merge tag '2.5.0.0beta26' into develop
2.5.0.0beta26
2020-02-07 21:45:51 +01:00
J-Jamet
462c29b769 Merge branch 'release/2.5.0.0beta26' 2020-02-07 21:45:40 +01:00
J-Jamet
3939276d58 Fix translations 2020-02-07 19:44:21 +01:00
J-Jamet
ff85f18c4c Update ReadMe.md 2020-02-07 19:24:12 +01:00
J-Jamet
dd14fe4123 Fix exception after changing theme 2020-02-07 19:20:43 +01:00
J-Jamet
d804659ee2 Change blue color of classic dark style 2020-02-07 19:10:48 +01:00
J-Jamet
e3152cf901 Remove AMOLED string for Black theme 2020-02-07 18:57:07 +01:00
J-Jamet
de236f321f Upgrade CHANGELOG 2020-02-07 18:26:27 +01:00
J-Jamet
66f4611866 Restore and delete entry history #335 2020-02-07 18:22:37 +01:00
heta1121
6a6ef052af Translated using Weblate (Swedish)
Currently translated at 94.9% (388 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2020-02-06 19:07:41 +01:00
J-Jamet
4e4606dabd Fix strings #436 2020-01-31 20:14:53 +01:00
J-Jamet
0ce11103ab Update CHANGELOG 2020-01-31 19:33:24 +01:00
J-Jamet
899d0e0557 Fix expired entries views 2020-01-31 19:29:40 +01:00
J-Jamet
4aefeff41f Hide expired entries from quick search when setting is activated #453 2020-01-31 17:26:36 +01:00
J-Jamet
08d59e50e8 Add android:resizeableActivity="true" for DeX mode 2020-01-31 16:48:15 +01:00
J-Jamet
e6c06aba8c Merge branch 'qtwyeuritoiy-feature/amoled_black' into develop 2020-01-31 13:12:37 +01:00
J-Jamet
e5c2a04922 Merge branch 'feature/amoled_black' of git://github.com/qtwyeuritoiy/KeePassDX into qtwyeuritoiy-feature/amoled_black 2020-01-31 13:12:18 +01:00
J-Jamet
c134ccf8d9 Encapsulate filters 2020-01-29 20:20:39 +01:00
J-Jamet
4f959d1ff6 Merge branch 'feature/hide_expired_entries' of git://github.com/qtwyeuritoiy/KeePassDX into qtwyeuritoiy-feature/hide_expired_entries 2020-01-29 17:22:40 +01:00
J-Jamet
1c06d93951 Fix custom fields in Magikeyboard 2020-01-29 17:10:26 +01:00
J-Jamet
b2dff29baa Auto performed "Go" key in Magikeyboard 2020-01-29 14:13:13 +01:00
J-Jamet
72633e9472 Change KEYCODE_ENTER by IME_ACTION_GO #369 2020-01-29 13:34:32 +01:00
J-Jamet
898a88f7d8 Fix app description 2020-01-27 12:52:46 +01:00
J-Jamet
c2f09f6666 Change "KeePass DX" name to "KeePassDX" and fix small issues #411 2020-01-27 12:43:45 +01:00
J-Jamet
d45bcbc347 Fix empty space in entry content 2020-01-27 11:18:54 +01:00
Jihoon Kim
1f834567f8 [Feature/HideExpiredEntries] Move 'Hide Expired Entries' Switch to 'Other' Category
Signed-off-by: Jihoon Kim <imsesaok@tuta.io>
2020-01-27 17:39:26 +08:00
Jihoon Kim
0b62c04867 [Feature/AmoledBlack] Add AMOLED Black Theme
Signed-off-by: Jihoon Kim <imsesaok@tuta.io>
2020-01-27 17:00:24 +08:00
J-Jamet
c71bb2a570 Password display box multiline #225 2020-01-26 18:02:11 +01:00
J-Jamet
0a575b5bf8 Prevent capture for all screens 2020-01-26 15:47:50 +01:00
J-Jamet
6f2bf903c5 Fix storage permission 2020-01-26 13:26:09 +01:00
Rodrigo Saldaña
210ad4b8db Translated using Weblate (Spanish)
Currently translated at 88.5% (362 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2020-01-25 19:21:30 +01:00
Allan Nordhøy
b42cf0e204 Translated using Weblate (Norwegian Bokmål)
Currently translated at 87.5% (358 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-01-23 09:21:33 +01:00
solokot
2045d3aab8 Translated using Weblate (Russian)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-01-23 09:21:32 +01:00
Allan Nordhøy
e20cb9431d Translated using Weblate (Danish)
Currently translated at 95.6% (391 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-01-23 09:21:31 +01:00
J-Jamet
7161eaea8b Allow write permission for specific file managers 2020-01-22 16:37:38 +01:00
J-Jamet
b786da52f5 Add error snackbar for error in entry edit view #431 2020-01-22 13:01:15 +01:00
J-Jamet
ccbfec838d Fix disclaimer formal string 2020-01-22 12:18:19 +01:00
J-Jamet
f5c1872225 Fix show read only warning 2020-01-22 10:53:24 +01:00
heta1121
3001013bad Translated using Weblate (Swedish)
Currently translated at 85.6% (350 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2020-01-21 17:21:30 +01:00
Allan Nordhøy
1280803e5e Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.9% (343 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-01-19 15:22:00 +01:00
heta1121
f84fc07fe0 Translated using Weblate (Swedish)
Currently translated at 85.1% (348 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2020-01-19 15:22:00 +01:00
J-Jamet
d83e53f589 Fix read only for recycle bin 2020-01-19 12:17:27 +01:00
J-Jamet
52ba2c53f1 Fix progress for Android < 5 2020-01-18 15:23:51 +01:00
J-Jamet
f266e1de4c Add string to open the attachment downloaded 2020-01-18 12:24:21 +01:00
J-Jamet
5a0aafd3ce Update CHANGELOG 2020-01-18 12:19:56 +01:00
J-Jamet
c7ce07a43c Change file size format 2020-01-18 12:15:14 +01:00
J-Jamet
a73644c285 Merge branch 'feature/Stream_Binaries' into develop 2020-01-18 12:03:55 +01:00
J-Jamet
e28f1ffc99 Fix attachment orientation change 2020-01-18 11:33:17 +01:00
Deleted User
afc691b2f4 Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.9% (343 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-01-16 06:27:50 +01:00
J-Jamet
00f6eb83c3 Fix close notification 2020-01-15 05:52:32 +01:00
J-Jamet
bbf51ebbec Multiple attachments download and add file compression 2020-01-14 19:44:10 +01:00
Jihoon Kim
7816c8f16e [Feature/HideExpiredEntries] Apply 'Hide Expired Entries' Setting And Adjust Item Count Accordingly
Signed-off-by: Jihoon Kim <imsesaok@tuta.io>
2020-01-14 17:28:27 +08:00
Jihoon Kim
fdbcba2412 [Feature/HideExpiredEntries] Add Preference Entry for 'Hide Expired Entries'
Signed-off-by: Jihoon Kim <imsesaok@tuta.io>
2020-01-14 17:28:27 +08:00
J-Jamet
50dc6cb0aa Fix download attachment 2020-01-13 10:05:34 +01:00
J-Jamet
e413198d12 Download attachment dynamic string 2020-01-10 19:40:00 +01:00
solokot
72592772f9 Translated using Weblate (Russian)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-01-09 09:21:27 +01:00
solokot
f918206bcd Translated using Weblate (Russian)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-01-07 22:27:33 +01:00
J-Jamet
6b34d67da8 Remove WRITE_EXTERNAL_STORAGE for Android > 18
Download attachment as service
2020-01-07 19:43:41 +01:00
Retrial
04fb093d4d Translated using Weblate (Greek)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-01-04 18:21:28 +01:00
J-Jamet
7de0e0cc4a Add Attachment view 2019-12-31 14:34:51 +01:00
J-Jamet
5cf7688e38 Merge branch 'develop' into feature/Stream_Binaries 2019-12-31 12:05:48 +01:00
J-Jamet
97cd06b52b Merge branch 'feature/Duplicate_UUID_Database1' into develop 2019-12-31 11:23:44 +01:00
J-Jamet
6d522ead1d Fix illegal argument exception and refactor KDB parser code 2019-12-31 08:26:15 +01:00
J-Jamet
8e0fae62f3 Merge branch 'develop' into feature/Stream_Binaries 2019-12-30 14:09:05 +01:00
J-Jamet
af72098d60 Refactor bytes utility methods 2019-12-30 12:59:50 +01:00
Taeko Hasegawa
62da582f4e Translated using Weblate (Japanese)
Currently translated at 36.4% (149 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2019-12-23 14:21:24 +01:00
J-Jamet
f3efa6eddc Add parameter to fix duplicate UUID in DatabaseV1 2019-12-22 18:26:35 +01:00
J-Jamet
c85fb7bd0a Better element output KDB implementation 2019-12-22 18:13:26 +01:00
J-Jamet
fc7b183461 Update CHANGELOG 2019-12-22 17:51:48 +01:00
J-Jamet
a378810f88 Improvement code for ClipboardHelper 2019-12-21 21:36:33 +01:00
J-Jamet
2f5b322fad Fix crash during clean clipboard in Android 9 2019-12-21 21:31:12 +01:00
J-Jamet
efb9b50f85 Fix issue #127 KDBX binaries 2019-12-21 21:18:58 +01:00
J-Jamet
84fdef8eb6 Merge branch 'develop' into feature/Stream_Binaries 2019-12-21 19:46:05 +01:00
J-Jamet
76050a261b Update to version 2.5.0.0beta26 2019-12-21 19:16:30 +01:00
Éfrit
2667361450 Translated using Weblate (French)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-12-19 17:18:38 +01:00
Éfrit
a2b3313cc0 Translated using Weblate (French)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-12-18 22:50:52 +01:00
J-Jamet
d343446235 Check file size to not corrupt a database v1 if too high 2019-12-18 18:58:26 +01:00
J-Jamet
cbce70f8a4 Save KDB binaries as file 2019-12-18 18:46:50 +01:00
WaldiS
4573d6b6fb Translated using Weblate (Polish)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-12-18 14:21:21 +01:00
Chen Wang
973305d13c Translated using Weblate (Chinese (Simplified))
Currently translated at 99.3% (406 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2019-12-16 08:21:13 +01:00
solokot
4637016372 Translated using Weblate (Russian)
Currently translated at 99.8% (408 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2019-12-16 08:21:12 +01:00
Chen Wang
698ba4f7f1 Translated using Weblate (English)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2019-12-16 08:21:11 +01:00
Oğuz Ersen
502ebabf1f Translated using Weblate (Turkish)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-12-16 08:21:10 +01:00
WaldiS
13f88626ca Translated using Weblate (Polish)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-12-08 15:13:26 +01:00
zeritti
a39f58f7b5 Translated using Weblate (Czech)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2019-12-08 15:13:25 +01:00
nautilusx
aeb36468ce Translated using Weblate (German)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-12-08 15:13:23 +01:00
J-Jamet
fdd196526d Better InputStream / OutputStream close 2019-12-05 19:28:54 +01:00
Mattias Münster
ecca892b16 Translated using Weblate (Swedish)
Currently translated at 25.9% (106 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2019-12-04 02:05:37 +01:00
Rudah Ximenes Alvarenga
03343d0301 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2019-12-04 02:05:36 +01:00
Allan Nordhøy
a61c8b0cb6 Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.6% (342 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2019-12-02 03:33:26 +01:00
Kunzisoft
a92129da00 Translated using Weblate (French)
Currently translated at 99.5% (407 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-12-02 03:33:24 +01:00
Allan Nordhøy
0b783d6390 Translated using Weblate (English)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2019-12-02 03:33:23 +01:00
jan madsen
9aa1a2e30e Translated using Weblate (Danish)
Currently translated at 95.8% (392 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2019-12-02 03:33:23 +01:00
C. Rüdinger
15b3c69514 Translated using Weblate (German)
Currently translated at 99.5% (407 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-12-02 03:33:21 +01:00
Oğuz Ersen
f2722e09ec Translated using Weblate (Turkish)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-12-02 03:33:21 +01:00
Deleted User
b442859be0 Translated using Weblate (German)
Currently translated at 100.0% (409 of 409 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-12-01 17:45:31 +01:00
J-Jamet
1496a2efb1 Fix database decryption with attachment 2019-11-30 19:26:26 +01:00
J-Jamet
a0edb111f0 Merge branch 'develop' into feature/Stream_Binaries 2019-11-30 18:27:21 +01:00
J-Jamet
6bcf54fe29 Merge tag '2.5.0.0beta25' into develop
2.5.0.0beta25
2019-11-30 17:43:19 +01:00
J-Jamet
3d7e24816a Merge branch 'release/2.5.0.0beta25' 2019-11-30 17:43:05 +01:00
J-Jamet
f5e02ec63f Merge branch 'translations' into develop 2019-11-30 17:27:39 +01:00
J-Jamet
ed1f4ebace Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2019-11-30 17:27:20 +01:00
J-Jamet
eb0e496cfd Try to decrypt DatabaseV1 by InputStream 2019-11-30 17:02:09 +01:00
J-Jamet
8b9fc30a6d Upgrade description 2019-11-30 10:12:43 +01:00
J-Jamet
12c2a6e99c Refactor bytes utility methods 2019-11-29 14:19:13 +01:00
J-Jamet
714433b62d Refactor stream methods 2019-11-28 16:32:16 +01:00
J-Jamet
e42933d786 Move SortNodeEnum 2019-11-27 22:49:59 +01:00
J-Jamet
e9531e4edd Merge branch 'feature/Refactor_Class' into develop 2019-11-27 19:21:36 +01:00
J-Jamet
0cd9cd294d Move database elements in packages 2019-11-27 19:19:42 +01:00
J-Jamet
b03fb12fca Refactor Input and Output 2019-11-27 18:59:09 +01:00
J-Jamet
b7b2e8dc4e Change class by KDB and KDBX 2019-11-27 18:51:28 +01:00
J-Jamet
96568abc51 Update CHANGELOG 2019-11-27 17:36:40 +01:00
J-Jamet
a180688858 Merge branch 'feature/OOM' into develop 2019-11-27 17:34:44 +01:00
J-Jamet
2590067558 Fix exception message 2019-11-27 17:34:26 +01:00
J-Jamet
b5499238f7 Change binary attachment compression after change compression setting 2019-11-27 16:46:14 +01:00
J-Jamet
cc5b96f539 Fix OOM by stream implementation and add KDBX version for DatabaseV2 2019-11-26 17:21:33 +01:00
J-Jamet
32343dc937 Refactor binary class 2019-11-26 11:07:29 +01:00
J-Jamet
1e71dd3031 Better binary reader 2019-11-25 21:14:39 +01:00
J-Jamet
ebf6f6a52a Replace Base64 lib 2019-11-25 19:25:08 +01:00
J-Jamet
6bf6d661af New databaseV2 XML write methods 2019-11-25 18:20:02 +01:00
J-Jamet
fe16879f35 New method to clear the clipboard 2019-11-25 15:12:27 +01:00
J-Jamet
ead384d1bb Update invalid credentials error message 2019-11-25 14:20:28 +01:00
J-Jamet
1ebdc0bacd Fix copy and move entry crash in root for DatabaseV1 2019-11-25 14:17:07 +01:00
zeritti
8eca8cdd53 Translated using Weblate (Czech)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2019-11-25 14:04:59 +01:00
J-Jamet
24c61b1b37 Partial fix of Database V1 node deletion #394 2019-11-25 13:59:32 +01:00
J-Jamet
ea18cc7166 Remove unused element 2019-11-21 18:09:54 +01:00
J-Jamet
387c499829 Fix expires for new entry in DatabaseV1 2019-11-21 17:01:57 +01:00
J-Jamet
339470dd6e Fix open button 2019-11-21 16:15:21 +01:00
J-Jamet
02d1089dbc Better biometric state management 2019-11-21 13:12:38 +01:00
J-Jamet
1bc0932cec Fix fingerprint animation 2019-11-21 12:13:08 +01:00
J-Jamet
76cc2739c8 Change biometric prompt messages 2019-11-21 11:58:59 +01:00
J-Jamet
b23908aec2 Change biometric error 2019-11-21 10:50:49 +01:00
J-Jamet
6b1b8c0f7b Add biometric error message 2019-11-21 10:44:22 +01:00
J-Jamet
06320a7eba Add sw600dp-port dimen 2019-11-21 10:13:04 +01:00
WaldiS
fc02145d0c Translated using Weblate (Polish)
Currently translated at 99.7% (398 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-11-21 10:04:56 +01:00
Gaurav Sehar
5360738775 Translated using Weblate (Hindi)
Currently translated at 23.3% (93 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hi/
2019-11-21 10:04:54 +01:00
J-Jamet
0957df752a Fix creating database 2019-11-21 10:04:34 +01:00
J-Jamet
fe56d06b5d Merge branch 'develop' of github.com:Kunzisoft/KeePassDX into develop 2019-11-21 09:16:34 +01:00
J-Jamet
f4955b16cd Remove specific ndk version to avoid error on FDroid 2019-11-20 23:10:56 +01:00
J-Jamet
07692ba73d Implicit confirmation for biometric #390 2019-11-20 19:36:05 +01:00
J-Jamet
64ac3e8f32 Change reader header and data equals 2019-11-20 16:06:59 +01:00
J-Jamet
8013d3109a Small code change 2019-11-20 12:55:14 +01:00
J-Jamet
be6f01dc99 Fix PWDate and blocks 2019-11-20 12:40:56 +01:00
Mattias Münster
30f7779ec6 Translated using Weblate (Swedish)
Currently translated at 26.8% (107 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2019-11-20 00:04:47 +01:00
solokot
6b5823ca70 Translated using Weblate (Russian)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2019-11-20 00:04:45 +01:00
J-Jamet
d4a09ed569 Merge branch 'feature/Manually_Save_Satabase' into develop 2019-11-19 19:18:00 +01:00
J-Jamet
84fe409c4b Nested fragment for general and database settings 2019-11-18 21:18:34 +01:00
J-Jamet
51d90891ad Fix auto save database 2019-11-18 19:59:50 +01:00
J-Jamet
b1fa06099c Refactor action database and add new execution command string 2019-11-18 19:55:17 +01:00
J-Jamet
fa9d8ad6ad Refactor progress dialog thread / save database menu 2019-11-18 17:54:13 +01:00
Azurak
6703d7b451 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2019-11-17 02:04:55 +01:00
Azurak
73afd44d9c Translated using Weblate (Chinese (Traditional))
Currently translated at 48.4% (193 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2019-11-17 02:04:53 +01:00
Stephan Paternotte
93cb93bb9b Translated using Weblate (Dutch)
Currently translated at 99.2% (396 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2019-11-17 02:04:49 +01:00
WaldiS
82902cff71 Translated using Weblate (Polish)
Currently translated at 95.7% (382 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-11-17 02:04:46 +01:00
Azurak
3657f7e54c Translated using Weblate (English)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2019-11-17 02:04:44 +01:00
Kunzisoft
a57a2f738d Translated using Weblate (English)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2019-11-17 02:04:44 +01:00
jan madsen
b93592d703 Translated using Weblate (Danish)
Currently translated at 96.0% (383 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2019-11-17 02:04:44 +01:00
C. Rüdinger
fd288e624b Translated using Weblate (German)
Currently translated at 99.7% (398 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-11-17 02:04:42 +01:00
Rudah Ximenes Alvarenga
095fa3f6ef Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2019-11-17 02:04:41 +01:00
Oğuz Ersen
b1f6c578ad Translated using Weblate (Turkish)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-11-17 02:04:37 +01:00
Mesut Akcan
1bc991bfcb Translated using Weblate (Turkish)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-11-17 02:04:32 +01:00
J-Jamet
02feb478e8 Add autosave database setting 2019-11-16 20:18:07 +01:00
J-Jamet
c2df79f0c9 Fix save database in read only mode 2019-11-16 19:36:29 +01:00
J-Jamet
ef13965747 Fix save database in read only mode 2019-11-16 18:34:39 +01:00
Kunzisoft
13421601de Translated using Weblate (French)
Currently translated at 99.7% (398 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-11-16 11:53:24 +01:00
Azurak
5a9b46c4b5 Translated using Weblate (Chinese (Traditional))
Currently translated at 33.3% (133 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2019-11-15 18:31:47 +01:00
Thomas
6268642097 Translated using Weblate (Chinese (Traditional))
Currently translated at 33.3% (133 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2019-11-15 18:31:45 +01:00
J-Jamet
12eadbc092 Update CHANGELOG 2019-11-14 16:35:23 +01:00
J-Jamet
c9475d1dc2 Fix concurrent exception when update group 2019-11-14 16:28:44 +01:00
J-Jamet
56805defb6 Merge branch 'feature/RecyclerBin' into develop 2019-11-14 15:57:09 +01:00
J-Jamet
477a784201 Empty recycle bin 2019-11-14 15:56:30 +01:00
J-Jamet
f54bac15c9 Add recycle bin setting and fix delete node 2019-11-14 13:14:02 +01:00
J-Jamet
ae28ebe701 Add dialog when permanently delete nodes 2019-11-14 09:59:55 +01:00
oskamuelller4fs
f16adf00da Translated using Weblate (German)
Currently translated at 100.0% (399 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-11-14 03:20:56 +01:00
C. Rüdinger
d17699f6f7 Translated using Weblate (German)
Currently translated at 96.2% (384 of 399 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-11-14 01:43:58 +01:00
J-Jamet
8afcf043ee Fix database name 2019-11-13 20:06:44 +01:00
J-Jamet
dda9d034aa Same feature as KeePass2 for entry history 2019-11-13 19:17:36 +01:00
J-Jamet
652bad51b4 Fix infinite dialog after entry is save #387 2019-11-13 18:54:04 +01:00
J-Jamet
4d2ccc0789 Remove unused onPreferenceClick 2019-11-13 17:42:50 +01:00
J-Jamet
0e1c21e0f4 Small code change 2019-11-13 17:31:38 +01:00
J-Jamet
8d3f58b2cc Merge branch 'feature/RefactorImporter' into develop 2019-11-13 17:29:30 +01:00
J-Jamet
be78905d85 Rename input output utility class for db 2019-11-13 17:04:41 +01:00
J-Jamet
b3f232c840 Upgrade Importer V3 2019-11-13 15:57:52 +01:00
J-Jamet
075a16c1c3 Remove OTP menu from DatabaseV1 2019-11-13 12:58:10 +01:00
J-Jamet
18a13e6266 Fix OTP base32 length and remove spaces 2019-11-13 12:46:52 +01:00
Jérémy JAMET
7149bdbc3a Update bug_report.md 2019-11-12 20:03:19 +01:00
J-Jamet
9a4c4aa9bf Fix string bugs 2019-11-12 17:38:08 +01:00
Hosted Weblate
2b32cab9d1 Merge branch 'origin/master' into Weblate. 2019-11-12 17:06:11 +01:00
J-Jamet
66611db261 Fix TOTP secret uppercase #381 2019-11-12 15:45:40 +01:00
J-Jamet
fdc2095b42 Remove access view 2019-11-12 15:38:12 +01:00
J-Jamet
2f9cab0da2 Upgrade to 2.5.0.0beta25 2019-11-12 13:21:21 +01:00
J-Jamet
bd0d474751 Upgrade Pro description 2019-11-12 13:08:47 +01:00
J-Jamet
cca0ab2669 Merge tag '2.5.0.0beta24' into develop
2.5.0.0beta24
2019-11-12 12:35:28 +01:00
J-Jamet
cb5ca575d5 Merge branch 'release/2.5.0.0beta24' 2019-11-12 12:35:16 +01:00
J-Jamet
f4caaad9ee Fix invalid_db_same_uuid error 2019-11-12 12:09:58 +01:00
J-Jamet
b9cfb32a20 Fix OTP dialog 2019-11-12 11:56:19 +01:00
J-Jamet
095e5e5dd6 Add FLAG_GRANT_PREFIX_URI_PERMISSION flag 2019-11-12 10:43:32 +01:00
J-Jamet
ffc58688d8 Upgrade Gradle 2019-11-12 09:38:36 +01:00
Allan Nordhøy
6a69a7f416 Translated using Weblate (Norwegian Bokmål)
Currently translated at 94.5% (360 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2019-11-11 23:04:19 +01:00
J-Jamet
b4188b4712 Fix small bugs 2019-11-11 16:50:05 +01:00
J-Jamet
4a22c28df4 Merge branch 'translations' into develop 2019-11-11 16:34:39 +01:00
J-Jamet
76e9a25b1a Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2019-11-11 16:33:54 +01:00
J-Jamet
1928d0823e Fix small french translations 2019-11-11 14:47:57 +01:00
J-Jamet
c183d22412 Upgrade Biometric library 2019-11-11 14:44:38 +01:00
J-Jamet
b684353721 Upgrade CHANGELOG and Readme.md 2019-11-11 14:19:29 +01:00
J-Jamet
72f0e871c7 Fix close clipboard notification 2019-11-11 14:09:41 +01:00
J-Jamet
9a63962903 Fix clipboard notification with auto generated field 2019-11-11 14:00:30 +01:00
J-Jamet
938de28b49 Minimized hidden text #373 2019-11-10 16:30:22 +01:00
J-Jamet
20fc094d71 Steam OTP on closed and full version 2019-11-10 15:26:52 +01:00
J-Jamet
40180d5883 Merge branch 'feature/TOTP' into develop 2019-11-10 14:33:35 +01:00
J-Jamet
59e5865318 Fix OTP errors 2019-11-10 14:31:21 +01:00
J-Jamet
f63d6bdc1d Fix OTP orientation change listener 2019-11-10 14:10:36 +01:00
J-Jamet
fe33c0ae7d Fix init OTP elements 2019-11-10 13:20:19 +01:00
J-Jamet
ca4ad1c1fd Validate OTP dialog only if no error 2019-11-10 12:19:06 +01:00
J-Jamet
adf5382804 Add min and max values for OTP 2019-11-10 11:25:34 +01:00
J-Jamet
7f5406ac98 OTP errors implementation 2019-11-09 15:19:14 +01:00
J-Jamet
23b21ea154 Fix OTP dialog 2019-11-08 19:36:59 +01:00
Antonio F
49d4d0421a Translated using Weblate (Spanish)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2019-11-08 18:04:10 +01:00
J-Jamet
23859a61bb Build OTP url 2019-11-07 19:28:54 +01:00
J-Jamet
221f81f51e Change ObjectNameResource and add OTP Dialog 2019-11-07 15:18:57 +01:00
J-Jamet
6e7c0d5073 Upgrade NDK version 2019-11-07 12:31:39 +01:00
Rudah Ximenes Alvarenga
e8e3d53685 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2019-11-06 21:04:12 +01:00
J-Jamet
e6d9df2b98 Add OTP auto generate field for Magikeyboard 2019-11-06 13:39:19 +01:00
J-Jamet
477a8f2e38 Update OTP code with AndOTP and kotlinized OtpEntryFields 2019-11-05 19:57:20 +01:00
J-Jamet
5e66697b8b Fix TOTP retrievement and add HOTP fields 2019-11-05 17:30:27 +01:00
J-Jamet
16320abb7d Global OTP variables, add progress bar, remove seconds 2019-11-05 16:04:30 +01:00
J-Jamet
f122c2832c Add OTP and fix TOTP generation 2019-11-05 13:42:51 +01:00
J-Jamet
d84c561f44 Merge branch 'studio315b-totpReadMode' into feature/TOTP 2019-11-04 18:23:17 +01:00
J-Jamet
da49c9c045 Merge branch 'totpReadMode' of git://github.com/studio315b/KeePassDX into studio315b-totpReadMode 2019-11-04 17:52:14 +01:00
J-Jamet
553920e37c Add setting to enable persistent notification 2019-11-03 11:29:28 +01:00
J-Jamet
450d2d113b Fix stop notification when edit entry 2019-11-03 10:55:47 +01:00
WaldiS
744c80e34d Translated using Weblate (Polish)
Currently translated at 99.7% (380 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-11-01 21:03:53 +01:00
J-Jamet
c0f8cca7c6 Fix history copy 2019-11-01 15:43:08 +01:00
J-Jamet
b129f220f7 Move copy button to the top #374 2019-11-01 15:09:41 +01:00
J-Jamet
7a3df02e38 Add explanation for settings 2019-10-30 21:40:53 +01:00
J-Jamet
befd29c396 Remove Magikeyboard explanation 2019-10-30 21:07:07 +01:00
J-Jamet
b8245621ea Remove fingerprint references 2019-10-30 20:19:33 +01:00
J-Jamet
ecda25a743 Fix biometric during orientation change 2019-10-30 19:36:52 +01:00
J-Jamet
d97a85b997 Remove biometric link if change credential 2019-10-30 15:21:50 +01:00
J-Jamet
8c0d7ab9ed Better Action runnable implementation 2019-10-30 14:49:40 +01:00
Allan Nordhøy
f3fa73ea34 Translated using Weblate (Norwegian Bokmål)
Currently translated at 94.5% (360 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2019-10-30 11:03:44 +01:00
Philipp Fischbeck
788734ccad Translated using Weblate (German)
Currently translated at 98.4% (375 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-10-30 11:03:43 +01:00
J-Jamet
e088f4a4ad Fix opening database after register biometric 2019-10-30 10:16:27 +01:00
J-Jamet
86bd018e4e Validate preference dialog with virtual done keyboard button 2019-10-29 11:25:20 +01:00
J-Jamet
283145034d Fix preference number 2019-10-29 10:50:09 +01:00
J-Jamet
163162497e Update libraries 2019-10-29 10:34:02 +01:00
J-Jamet
56911fb58f Refresh number of children after an action 2019-10-29 10:29:06 +01:00
J-Jamet
dae6481aff Update CHANGELOG 2019-10-29 10:16:31 +01:00
J-Jamet
6b2eb5e4f6 Merge branch 'feature/Database_Notification' into develop 2019-10-29 10:13:23 +01:00
J-Jamet
c563787f73 Change notification icons 2019-10-29 10:09:46 +01:00
J-Jamet
2737755b85 Change notification icons 2019-10-29 09:38:01 +01:00
Trygve John
fd9486ca77 Translated using Weblate (Norwegian Bokmål)
Currently translated at 94.5% (360 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2019-10-29 09:03:19 +01:00
J-Jamet
14020ec0b5 Fix clipboard notification timeout 2019-10-28 12:20:22 +01:00
J-Jamet
5a6c466ebd Add notification for opened database and use compat notification manager 2019-10-28 11:50:06 +01:00
WaldiS
76fcd5fe19 Translated using Weblate (Polish)
Currently translated at 99.2% (378 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-10-26 19:53:28 +02:00
J-Jamet
3732ff1ebc Fix clean clipboard after killing app by swap 2019-10-26 08:58:36 +02:00
Aykut ÖZDEMİR
22dd09954b Translated using Weblate (Turkish)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-10-25 13:53:16 +02:00
J-Jamet
ef7387f2f3 Remove entry notifications after killing app (by swap) 2019-10-25 10:08:39 +02:00
J-Jamet
f774298587 Update CHANGELOG 2019-10-24 15:23:52 +02:00
J-Jamet
f8134307f6 Fix long click in paste mode 2019-10-24 13:10:52 +02:00
J-Jamet
fe461f2e7c Fix action error 2019-10-24 12:36:22 +02:00
J-Jamet
023c841747 Better code 2019-10-24 11:49:23 +02:00
J-Jamet
af95c0903a Better node error implementation 2019-10-24 11:29:43 +02:00
J-Jamet
0d756db8aa Beter code 2019-10-24 11:07:58 +02:00
J-Jamet
2c5dcc9b11 Fix back for action selection mode 2019-10-24 10:25:21 +02:00
Éfrit
21c6ea73b2 Translated using Weblate (French)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-10-22 23:53:07 +02:00
C. Rüdinger
51dc302bb0 Translated using Weblate (German)
Currently translated at 97.9% (373 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-10-22 23:53:06 +02:00
J-Jamet
87760ab4f6 Fix save database and finish 2019-10-22 15:02:51 +02:00
J-Jamet
88ebe58a88 Fix action node 2019-10-22 14:46:13 +02:00
villabunterkunt
fb023b81b5 Translated using Weblate (German)
Currently translated at 97.9% (373 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-10-21 21:02:16 +02:00
J-Jamet
2de6bbc6c0 Fix selected color 2019-10-21 17:12:40 +02:00
J-Jamet
4ef436629d Merge branch 'feature/Loading_Database' into develop 2019-10-21 11:09:37 +02:00
Allan Nordhøy
9fd342f1e7 Translated using Weblate (Norwegian Bokmål)
Currently translated at 89.5% (341 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2019-10-21 02:53:03 +02:00
abidin toumi
8988f17765 Translated using Weblate (Arabic)
Currently translated at 71.1% (271 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2019-10-19 10:52:58 +02:00
J-Jamet
9d160db281 Add setting updates for dialog thread 2019-10-18 13:44:28 +02:00
J-Jamet
2e58c2f1b3 Fix duplication during deletion 2019-10-17 20:02:49 +02:00
J-Jamet
d1d2b99e09 Fix autofill selection 2019-10-17 15:17:18 +02:00
J-Jamet
def9744f75 Fix launch group activity when database loaded 2019-10-17 14:54:34 +02:00
J-Jamet
214e2cf109 Better database loading code 2019-10-17 14:07:39 +02:00
J-Jamet
b25180c617 Show update message and fix dialog retrievment 2019-10-17 11:29:30 +02:00
J-Jamet
6a5263df77 Fix biometric recognition error with new loading process 2019-10-17 10:28:24 +02:00
J-Jamet
2982f67717 Fix biometric recognition with new loading process 2019-10-17 10:24:12 +02:00
J-Jamet
b559670dff Fix result security by binder 2019-10-17 09:53:00 +02:00
J-Jamet
891d3142d2 Better code for bind callback 2019-10-16 18:49:15 +02:00
J-Jamet
2637788429 Fix dialog update 2019-10-16 15:31:07 +02:00
J-Jamet
a21de3b892 Fix update group 2019-10-16 11:48:35 +02:00
J-Jamet
e087e19120 Fix update entry 2019-10-16 10:46:56 +02:00
J-Jamet
721d61dda7 Fix update nodes 2019-10-15 18:05:33 +02:00
J-Jamet
e0e7e431cf Best update and nodeId type implementation 2019-10-15 17:02:59 +02:00
J-Jamet
93948e7c61 First commit for async loading 2019-10-15 16:01:50 +02:00
J-Jamet
b150c718a0 Fix edit notes field limited to 4 lines 2019-10-14 10:17:48 +02:00
J-Jamet
a71e4c3902 Add language parameter for issue template 2019-10-14 09:57:06 +02:00
Adolfo Jayme Barrientos
b7dc13d863 Translated using Weblate (Spanish)
Currently translated at 89.8% (342 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2019-10-12 16:52:53 +02:00
J-Jamet
1e3c58e359 Fix clipboard LOCK_DATABASE signal #366 2019-10-11 12:52:43 +02:00
J-Jamet
5f75599e9f Replace notification icons by PNG #364 2019-10-11 11:50:16 +02:00
J-Jamet
b602f9b77d Add icon for paste action 2019-10-11 10:58:21 +02:00
J-Jamet
aa948c1ece Remove null for BiometricUnlockCallback 2019-10-11 10:55:05 +02:00
J-Jamet
e599a51152 Refactor prompt build code 2019-10-11 10:41:45 +02:00
J-Jamet
ee6052f4d1 Update CHANGELOGS 2019-10-11 10:21:04 +02:00
J-Jamet
eba527f477 Add unrecoverable key exception 2019-10-11 10:18:28 +02:00
J-Jamet
09e0d6d3cc Update biometric and room lib 2019-10-11 10:03:44 +02:00
J-Jamet
9aefc984be Merge branch 'feature/Multiple_Node_Action' into develop #275 2019-10-10 19:19:08 +02:00
J-Jamet
2ce3b21f1b Add number of selected action nodes 2019-10-10 19:17:38 +02:00
J-Jamet
4d2f3cb4b1 Remove unused key for orientation change 2019-10-10 19:04:24 +02:00
J-Jamet
e62b46c4c0 Fix open and edit action bar 2019-10-10 18:38:15 +02:00
J-Jamet
6472601170 Add Toolbar action animation 2019-10-10 18:34:05 +02:00
J-Jamet
89dd7bfefb Fix finish node action when exit activity 2019-10-10 17:59:23 +02:00
J-Jamet
fb2ea4c0ed Multiple action node for Move Copy and Delete 2019-10-10 17:53:35 +02:00
J-Jamet
8d84358d48 Refactor code 2019-10-10 12:49:16 +02:00
J-Jamet
1d8661c633 Better node action refresh 2019-10-09 21:19:10 +02:00
J-Jamet
48130eee45 Change node action menu order 2019-10-09 20:23:22 +02:00
J-Jamet
2cf83962fe Merge branch 'develop' into feature/Multiple_Node_Action 2019-10-09 20:20:25 +02:00
J-Jamet
aecf7c0c39 Fix remove node at 2019-10-09 20:20:10 +02:00
J-Jamet
39606e2676 Custom Toolbar action 2019-10-09 20:16:11 +02:00
Ema Panz
6e00fa2d01 Translated using Weblate (Italian)
Currently translated at 95.5% (364 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2019-10-09 15:58:47 +02:00
J-Jamet
f79aa339e9 Selection by Contextual Menu 2019-10-09 15:58:00 +02:00
J-Jamet
f412fce912 Add safeNextText method to XmlPullParser 2019-10-07 15:51:44 +02:00
J-Jamet
cc20b7503c Refactor exceptions 2019-10-07 15:19:13 +02:00
Jérémy JAMET
2573434763 Update Readme.md
update FAQ
2019-10-07 09:33:21 +02:00
Jérémy JAMET
f153c26fef Set theme jekyll-theme-cayman 2019-10-07 09:15:48 +02:00
Ldm Public
125f461cbe Translated using Weblate (French)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-10-06 16:56:46 +02:00
WaldiS
b705b4b712 Translated using Weblate (Polish)
Currently translated at 99.2% (378 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-10-06 16:56:45 +02:00
Retrial
c67b0bb858 Translated using Weblate (Greek)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2019-10-06 16:56:45 +02:00
J-Jamet
ab1fc8c5d5 Remove CONTRIBUTORS file no longer updated, see https://github.com/Kunzisoft/KeePassDX/graphs/contributors 2019-10-06 11:46:35 +02:00
J-Jamet
8477f4ba08 Fix education in PasswordActivity 2019-10-06 11:15:56 +02:00
J-Jamet
e6518ffdc8 Upgrade ISSUE_TEMPLATE 2019-10-06 10:39:30 +02:00
J-Jamet
99917c7f28 Try to prevent XXE #200 2019-10-06 10:25:13 +02:00
J-Jamet
fcc29f67a3 Upgrade CHANGELOGS 2019-10-05 15:46:18 +02:00
J-Jamet
7dd49f050c Highlight expires entries 2019-10-05 15:43:45 +02:00
J-Jamet
5f96de84b0 Manage expires 2019-10-05 15:32:04 +02:00
J-Jamet
54c2f5a61f Fix Minor Accessibility Issues #334 2019-10-05 12:56:09 +02:00
J-Jamet
921c6f88aa Merge branch 'feature/OPEN_DOCUMENT' into develop 2019-10-05 12:43:40 +02:00
J-Jamet
a0cb579df4 Merge branch 'develop' into feature/OPEN_DOCUMENT 2019-10-05 11:47:27 +02:00
J-Jamet
d6a7c34ff3 Update gradle 2019-10-05 11:47:12 +02:00
J-Jamet
bf2e61f149 Merge branch 'develop' into feature/OPEN_DOCUMENT 2019-10-05 11:45:54 +02:00
J-Jamet
eaf5dc5988 Show number of children in toolbar #282 2019-10-05 11:27:34 +02:00
J-Jamet
879ee013db Fix multiple biometric menu #332 2019-10-05 10:12:45 +02:00
J-Jamet
e13d53eae4 Unable default username and custom color to Database V2 2019-10-05 09:22:41 +02:00
J-Jamet
d72c8184c9 Fix databaseV1 settings 2019-10-04 19:00:18 +02:00
Kunzisoft
c4d3c8cbfb Translated using Weblate (French)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-10-04 18:37:57 +02:00
J-Jamet
02a3d85f80 Try to fix "Unable to launch Activity from MagiKeyboard" #348 2019-10-04 16:53:20 +02:00
J-Jamet
19b0722f1f Add KeePass DX version in ISSUE_TEMPLATE 2019-10-04 16:36:20 +02:00
J-Jamet
f14222b192 Merge branch 'develop' into Bug_Feature_Template 2019-10-04 16:22:37 +02:00
J-Jamet
4f4f6d30d9 Change menu biometric order 2019-10-04 16:22:08 +02:00
J-Jamet
fdd329e982 Fix unchecked "Use as default database" doesn't work #354 2019-10-04 13:20:30 +02:00
J-Jamet
55a4d388b3 Fix V1 locked with keyFile and no password #353 2019-10-04 13:15:10 +02:00
J-Jamet
5c6be448ec Upgrade Changelogs 2019-10-04 12:00:22 +02:00
J-Jamet
3e79ddcc21 Merge branch 'feature/Color_Preference' into develop 2019-10-04 11:50:24 +02:00
J-Jamet
5362758424 Disable custom database color 2019-10-04 11:50:11 +02:00
J-Jamet
c10e3df2a7 Enable settings as switch 2019-10-04 11:47:33 +02:00
J-Jamet
166784021a Fix color setting orientation change 2019-10-04 11:44:16 +02:00
Jérémy JAMET
5615c31e08 Update issue templates 2019-10-03 12:04:38 +02:00
J-Jamet
fb60dd5921 Fix Disable color 2019-10-02 19:27:35 +02:00
J-Jamet
ff4c1b779b First code for color preference 2019-10-02 15:38:03 +02:00
J-Jamet
53a7b99567 Fix package for preference 2019-10-01 18:00:41 +02:00
J-Jamet
a57103bafb Add default username and better setter database data implementation 2019-10-01 17:05:46 +02:00
J-Jamet
2540f32dbf Add NDK version 2019-10-01 15:52:46 +02:00
J-Jamet
499ccd6b7c #297 Duplicate UUID 2019-10-01 15:00:35 +02:00
J-Jamet
a4359560b9 Change duplicate UUID dialog message 2019-10-01 14:42:32 +02:00
J-Jamet
149483cc2d Fix duplicate UUID dialog orientation change 2019-10-01 14:33:50 +02:00
J-Jamet
a1d2022492 Fix index for duplicate UUID 2019-10-01 14:15:11 +02:00
J-Jamet
891036c35c Fix database after dialog positive click 2019-10-01 12:35:03 +02:00
J Smith
4e16ba5f56 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2019-10-01 11:56:16 +02:00
abidin toumi
7137a2fadb Translated using Weblate (Arabic)
Currently translated at 71.1% (271 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2019-10-01 11:56:14 +02:00
ButterflyOfFire
9d90d0eaba Translated using Weblate (Arabic)
Currently translated at 71.1% (271 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2019-10-01 11:56:12 +02:00
J-Jamet
94a9942db5 Show duplicate UUID message and fix cancel string 2019-10-01 11:38:46 +02:00
J-Jamet
5f347fe106 Show same UUID entries 2019-09-29 22:26:47 +02:00
J-Jamet
a34a84ae16 Fix refactoring 2019-09-26 20:57:10 +02:00
J-Jamet
40b0982298 Refactor load database 2019-09-26 20:29:33 +02:00
J-Jamet
4100258476 Remove unused import 2019-09-26 16:26:41 +02:00
J-Jamet
5f3f6661b7 Remove URI verification 2019-09-26 16:24:41 +02:00
J-Jamet
75af97e0ae Better code to open document 2019-09-26 16:04:05 +02:00
J-Jamet
58f158c457 Fix java.lang.IllegalStateException for CoordinatorLayout 2019-09-26 14:02:59 +02:00
J-Jamet
ce27eae1f0 Upgrade biometric lib 2019-09-26 13:20:00 +02:00
WaldiS
0aa0b3e993 Translated using Weblate (Polish)
Currently translated at 96.1% (366 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-09-25 20:28:03 +02:00
J-Jamet
1cc5a08236 Better delete implementation 2019-09-25 15:45:12 +02:00
J-Jamet
4c587eeb03 Remove unused open link, and expand view lib. Redo toolbar paste animation 2019-09-25 15:25:58 +02:00
J-Jamet
ab70c2d014 Add settings 2019-09-24 15:42:57 +02:00
J-Jamet
8413160ac5 Rename compression algorithm 2019-09-24 13:10:49 +02:00
J-Jamet
5abc403171 Add compression setting 2019-09-24 12:52:07 +02:00
J-Jamet
9b891013b8 Add database settings 2019-09-24 11:52:01 +02:00
J-Jamet
9413987355 Update CHANGELOG 2019-09-23 18:01:40 +02:00
J-Jamet
f95b514b41 Fix orientation change during entry edit 2019-09-23 17:40:53 +02:00
WaldiS
f6985c8944 Translated using Weblate (Polish)
Currently translated at 96.1% (366 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-09-23 15:28:06 +02:00
zeritti
4388d56c52 Translated using Weblate (Czech)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2019-09-23 15:28:05 +02:00
solokot
a70fe24c97 Translated using Weblate (Russian)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2019-09-23 15:28:02 +02:00
Avgerinos Panagiotis
8e0392753c Translated using Weblate (Greek)
Currently translated at 19.7% (75 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2019-09-23 15:28:01 +02:00
J-Jamet
9c9980bba6 Change TimeOut default to 5 minutes 2019-09-23 11:11:53 +02:00
J-Jamet
2226c15d29 Merge branch 'feature/Entry_History' into develop 2019-09-23 10:30:20 +02:00
J-Jamet
82a859bd9c Better KDF implementation 2019-09-22 20:23:59 +02:00
J-Jamet
83873fab81 Fix custom fields orientation change #337 2019-09-22 18:27:32 +02:00
J-Jamet
31f2be7b91 Hide history preference with database V3 2019-09-22 14:34:52 +02:00
J-Jamet
16458e6646 Add description for max history preferences 2019-09-22 14:12:58 +02:00
J-Jamet
2b9678707d Separate recycle bin preference 2019-09-22 13:54:26 +02:00
J-Jamet
cdbb23d7f1 Separate recycle bin preference 2019-09-22 13:52:30 +02:00
J-Jamet
23fd1b83f4 Better preference implementation 2019-09-22 13:46:10 +02:00
J-Jamet
40b0ebe49b Fix preferences 2019-09-22 13:14:47 +02:00
J-Jamet
7cd8682544 Better Preference implementation 2019-09-20 16:30:05 +02:00
J-Jamet
d0dd478ac8 Add max history preferences 2019-09-19 17:53:32 +02:00
J-Jamet
ffb547c452 Change history string 2019-09-19 15:37:07 +02:00
J-Jamet
bd829f129f Better condition to show history 2019-09-19 14:29:24 +02:00
J-Jamet
5ad3f62de5 Add history after each entry update for DatabaseV4 2019-09-19 14:20:28 +02:00
solokot
b0ec4942bc Translated using Weblate (Russian)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2019-09-19 04:51:14 +02:00
tinect
2cbc9675f6 Translated using Weblate (German)
Currently translated at 97.1% (370 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2019-09-19 04:51:11 +02:00
J-Jamet
116643a45a Merge branch 'develop' into feature/Entry_History 2019-09-18 22:33:06 +02:00
J-Jamet
2f0eb283ed Fix selection mode color 2019-09-18 22:30:29 +02:00
J-Jamet
6d46fccdcd Show history by click 2019-09-18 22:14:50 +02:00
J-Jamet
f5dc94bfec Add date string for PwDate and new list view entry history 2019-09-18 12:57:11 +02:00
solokot
94bdb0e3da Translated using Weblate (Russian)
Currently translated at 99.7% (380 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2019-09-17 15:41:33 +02:00
Ldm Public
65360c2a1e Translated using Weblate (French)
Currently translated at 97.6% (372 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2019-09-16 22:24:14 +02:00
jan madsen
70d30bdbe6 Translated using Weblate (Danish)
Currently translated at 96.6% (368 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2019-09-16 22:24:13 +02:00
Mesut Akcan
66f7e6d1b1 Translated using Weblate (Turkish)
Currently translated at 100.0% (381 of 381 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-09-16 22:24:11 +02:00
J-Jamet
a8ccb67a87 Entry history first code 2019-09-15 17:56:25 +02:00
J-Jamet
66051382f1 Upgrade version 2019-09-15 15:56:54 +02:00
J-Jamet
0fb3028c91 Fix group copy 2019-09-15 10:42:10 +02:00
Hosted Weblate
5e5baa4892 Merge branch 'origin/master' into Weblate. 2019-09-15 10:17:14 +02:00
WaldiS
9d1257ed9d Translated using Weblate (Polish)
Currently translated at 97.6% (368 of 377 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2019-09-15 10:17:08 +02:00
Mesut Akcan
9d7546053d Translated using Weblate (Turkish)
Currently translated at 100.0% (377 of 377 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2019-09-15 10:17:07 +02:00
J-Jamet
a1b692abe5 Update fastlane 2019-09-14 12:47:42 +02:00
J-Jamet
4e06842d0f Fix #331 Crash if "Save keyfile" setting is unchecked 2019-09-14 12:47:04 +02:00
J-Jamet
f04c2ee1da Merge tag '2.5.0.0beta23' into develop
2.5.0.0beta23
2019-09-14 11:31:37 +02:00
somkun
9558fcaf21 Add Read support for TOTP Tokens 2018-09-16 22:11:23 -07:00
998 changed files with 74559 additions and 42429 deletions

41
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,41 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**KeePass Database**
- Created with: [e.g Windows KeePass 2.42]
- Version: [e.g. 2]
- Location: [e.g. Remote file retrieved with GDrive app]
- Size: [e.g. 150Mo]
- Contains attachment: [e.g. Yes]
**KeePassDX (please complete the following information):**
- Version: [e.g. 2.5.0.0beta23]
- Build: [e.g. Free]
- Language: [e.g. French]
**Android (please complete the following information):**
- Device: [e.g. GalaxyS8]
- Version: [e.g. 8.1]
**Additional context**
Add any other context about the problem here.
- Browser for Autofill: [e.g. Chrome version X]

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

7
.gitignore vendored
View File

@@ -38,6 +38,13 @@ proguard/
# Android Studio captures folder
captures/
# Eclipse/VS Code
.project
.settings/*
*/.project
*/.classpath
*/.settings/*
# Intellij
*.iml
.idea/workspace.xml

343
CHANGELOG
View File

@@ -1,4 +1,293 @@
KeepassDX (2.5.0.0beta23)
KeePassDX(2.10.1)
* Fix parcelable with custom data #986
KeePassDX(2.10.0)
* Manage new database format 4.1 #956
* Fix show button consistency #980
* Fix persistent notification #979
KeePassDX(2.9.20)
* Fix search with non-latin chars #971
* Fix action mode with search #972 (rollback ignore accents #945)
* Fix timeout with 0s #974
KeePassDX(2.9.19)
* Fix search slowdown #964
* Fix closing notification after lock request #965
* Better temp advanced unlocking code implementation #965
* Fix OTP token generation #967
KeePassDX(2.9.18)
* Move groups #658
* Improve autofill recognition #960
* Remove diacritical marks in search string #945
* Fix search in references #962
* Fix themes in Libre version
KeePassDX(2.9.17)
* Import / Export app properties #839
* Force twofish padding compatibility #955
* Better timeout preference #579
KeePassDX(2.9.16)
* Fix small bugs #948
KeePassDX(2.9.15)
* Fix themes #935 #926
* Decrease default clipboard time #934
* Better opening performance #929 #933
* Fix memory usage setting #941
KeePassDX(2.9.14)
* Add custom icons #96
* Dark Themes #532 #714
* Fix binary deduplication #715
* Fix IconId #901
* Resize image stream dynamically to prevent slowdown #919
* Small changes #795 #900 #903 #909 #914
KeePassDX(2.9.13)
* Binary image viewer #473 #749
* Fix TOTP plugin settings #878
* Allow Emoji #796
* Scroll and better UI in entry edition screen #876
* Better UI #876
* Fix themes and add Purple Dark #889
* Allow OTP with many padding #585
* Add notes in groups #734
KeePassDX(2.9.12)
* Fix OTP token type #863
* Fix auto open biometric prompt #862
* Fix back appearance setting #865
* Fix orientation change in settings #872
* Change memory unit to MiB #851
* Small changes #642
KeePassDX(2.9.11)
* Add Keyfile XML version 2 (fix hex) #844
* Fix hex Keyfile #861
KeePassDX(2.9.10)
* Try to fix autofill #852
* Fix database change dialog displayed too often #853
KeePassDX(2.9.9)
* Detect file changes and reload database #794
* Inline suggestions autofill with compatible keyboard (Android R) #827
* Add Keyfile XML version 2 #844
* Fix binaries of 64 bytes #835
* Special search in title fields #830
* Priority to OTP button in notifications #845
* Fix OTP generation for long secret key #848
* Fix small bugs #849
KeePassDX(2.9.8)
* Fix specific attachments with kdbx3.1 databases #828
* Fix small bugs
KeePassDX(2.9.7)
* Remove write permission since Android 10 #823
* Fix small bugs
KeePassDX(2.9.6)
* Fix KeyFile bug #820
KeePassDX(2.9.5)
* Unlock database by device credentials (PIN/Password/Pattern) with Android M+ #102 #152 #811
* Prevent auto switch back to previous keyboard if otp field exists #814
* Fix timeout reset #817
KeePassDX(2.9.4)
* Fix small bugs #812
* Argon2ID implementation #791
KeePassDX(2.9.3)
* Unlock database by device credentials (PIN/Password/Pattern) #779 #102
* Advanced unlock with timeout #102 #437 #566
* Remove default database parameter when the file is no longer accessible #803
* Move OTP button to the first view level in Magikeyboard #587
* Tooltips for Magikeyboard #586
* Fix small bugs #805
KeePassDX(2.9.2)
* Managing OTP links from QR applications #556
* Prevent manual creation of existing field name #718
* Harmonization of field names #789
* Different channels for each type of notification #688
* Fix OTP #780 #781
* Fix same save shared info #783
* Fix switch back to previous keyboard #782
* Fix read only #792
* Better UI #719 #534 #617 #793
KeePassDX(2.9.1)
* Copy password from generator #697
* Fix Magikeyboard not fully visible #772
* Fix change font size #770
* Fix crash #774
* Small fixes #771
KeePassDX(2.9)
* Upgrade to Android API 30 #723
* Save new credentials with Autofill #524
* Setting to close database after Autofill selection #755
* Setting to switch keyboard when database is locked #625
* Fix biometric issues #724 #740 #731
* Fix autofill #725 #551
* Fix subdomain search #728
* Fix backup search #759
* Small fixes and translations #732 #736 #737 #738 #742 #767
KeePassDX(2.8.7)
* Downgrade to Android API 29 (crash on startup with API 30 on some devices)
Sorry for the inconvenience
KeePassDX(2.8.6)
* Fix Autofill recognition #712
* Keep value after renaming custom field #709
* Prevent random binary bug #713
* Fix dialog background #717
* Better domain recognition for autofill #702
* Write custom data #651
* Fix autolink #720
KeePassDX(2.8.5)
* Fix Base 64 #708
KeePassDX(2.8.4)
* Fix incomplete attachment deletion #684
* Fix opening database v1 without backup folder #692
* Fix ANR during first entry education #685
* Entry edition as fragment and manual views to fix focus #686
* Fix opening database with corrupted attachment #691
* Manage empty keyfile #679
KeePassDX(2.8.3)
* Upload attachments
* Visibility button for each hidden field
* Fix read header file
* Fix deletion in KDB database
* Fix minor issues
KeePassDX(2.8.2)
* Fix themes / new UI
* Fix multiples notifications
* Fix entry in Magikeyboard memory
* Fix biometric view visibility
* Fix fields order
* Upgrade code with ViewModel and LiveData
KeePassDX(2.8.1)
* Capture exceptions in coroutines
KeePassDX(2.8)
* Fix TOTP period (> 60s)
* Fix searching in recycle bin
* Settings to back to the previous keyboard during database credentials and after form filling
* Improve action tasks
* Improve recognition to reset app timeout
* Fix minor issues
KeePassDX(2.7)
* Add blocklists for autofill
* Add autofill compatibility mode (usefull for Browser not compatible)
* Upgrade autofill recognition algorithm
* Setting to search through web subdomains
* Refactoring selection mode
KeePassDX(2.6)
* Share a web domain to automatically search for an entry
* Default group icon for a new entry
* Better autofill recognition
* Fix entry not visually deleted in search
* Fix hanged loading dialog
* Fix auto open biometric prompt if comes from background
* Minor fixes
KeePassDX(2.5)
* First stable version of KeePassDX
* Fork completely rewritten from the KeePassDroid project
* Fix small issues from the last Release Candidate
KeePassDX(2.5RC2)
* Replacement of Spongy Castle by Bouncy Castle
* Update Autofill compatibility
* Fix Magikeyboard "Go" action
* Fix KeeWeb database opening
* Fix default username
* Fix themes
* Fix small issues
KeePassDX(2.5RC1)
* Add write permission to keep compatibility with old file managers
* Fix autofill for apps
* Auto search for autofill
* New keyfile input
* Icon to hide keyfile input
* New lock button
* Setting to hide lock button in user interface
* Clickable links in notes
* Fix autofill for key-value pairs
KeePassDX(2.5beta30)
* Fix Lock after screen off (wait 1.5 seconds)
* Upgrade autofill algorithm
* Fix ANR during file verifications
KeePassDX(2.5beta29)
* Upgrade autofill algorithm
* Delete registered KeyFile after save new credentials
* Fix title and username entry view refresh after an update
* Fix database lock request (open notification always active)
* Allow empty title in entries
* Add expiration datetime
KeePassDX(2.5beta28)
* Fix read only database
* Upgrade to Android SDK 29
KeePassDX (2.5beta27)
* New setting to hide broken links
* Show URL when title is empty
* Setting to open search field at database opening
* Fix settings for database locations
* Fix error message when database file not writable
* Fix appearance refresh settings
* Sort optimization
KeePassDX (2.5.0.0beta26)
* Download attachments
* Change file size string format
* Prevent screenshot for all screen
* Auto performed "Go" key in Magikeyboard
* Restore and delete entry history
* Setting to hide expired entries
* New Black theme
* Fix crash when clearing clipboard
* Fix attachments compressions
* Fix dates
* Fix UUID message for Database v1
KeePassDX (2.5.0.0beta25)
* Setting for Recycle Bin
* Fix Recycle bin issues
* Fix TOTP
* Fix infinite save
* Fix update group
* Fix OOM
KeePassDX (2.5.0.0beta24)
* Add OTP (HOTP / TOTP)
* Add settings (Color, Security, Master Key)
* Show history of each entry
* Auto repair database for nodes with same UUID
* Management of expired nodes
* Multi-selection for actions (Cut - Copy - Delete)
* Open/Save database as service / Add persistent notification
* Fix settings / edit group / small bugs
KeePassDX (2.5.0.0beta23)
* New, more secure database creation workflow
* Recognize more database files
* Add alias for history files (WARNING: history is erased)
@@ -7,14 +296,14 @@ KeepassDX (2.5.0.0beta23)
* Fix OOM with KeyFile
* Fix small issues
KeepassDX (2.5.0.0beta22)
KeePassDX (2.5.0.0beta22)
* Rebuild code for actions
* Add UUID as entry view
* Fix bug with natural order
* Fix number of entries in databaseV1
* New entry views
KeepassDX (2.5.0.0beta21)
KeePassDX (2.5.0.0beta21)
* Fix nested groups no longer visible in V1 databases
* Improved data import algorithm for V1 databases
* Add natural database sort
@@ -22,10 +311,10 @@ KeepassDX (2.5.0.0beta21)
* Fix button disabled with only KeyFile
* Show the number of entries in a group
KeepassDX (2.5.0.0beta20)
KeePassDX (2.5.0.0beta20)
* Fix a major bug that displays an entry history
KeepassDX (2.5.0.0beta19)
KeePassDX (2.5.0.0beta19)
* Add lock button always visible
* New connection workflow
* Code refactored in Kotlin
@@ -36,7 +325,7 @@ KeepassDX (2.5.0.0beta19)
* Fix memory when load database
* Fix small bugs
KeepassDX (2.5.0.0beta18)
KeePassDX (2.5.0.0beta18)
* New recent databases views
* New information dialog
* Custom fields for the Magikeyboard
@@ -45,10 +334,10 @@ KeepassDX (2.5.0.0beta18)
* Fix memory when opening the database
* Memory management for attachments
KeepassDX (2.5.0.0beta17)
KeePassDX (2.5.0.0beta17)
* Fix font and search
KeepassDX (2.5.0.0beta16)
KeePassDX (2.5.0.0beta16)
* New search in a single fragment
* Search suggestions
* Added the display of usernames
@@ -56,20 +345,20 @@ KeepassDX (2.5.0.0beta16)
* Fix read-only mode
* Fix parcelable / toolbar / back
KeepassDX (2.5.0.0beta15)
KeePassDX (2.5.0.0beta15)
* Read only mode
* Best group recovery for the navigation fragment
* Fix copies in notifications
* Fix orientation
* Added translations
KeepassDX (2.5.0.0beta14)
KeePassDX (2.5.0.0beta14)
* Optimize all the memory with parcelables / fix search
KeepassDX (2.5.0.0beta13)
KeePassDX (2.5.0.0beta13)
* Fix memory issue with parcelable (crash in beta12 version)
KeepassDX (2.5.0.0beta12)
KeePassDX (2.5.0.0beta12)
* Added the Magikeyboard to fill the forms (settings still in development)
* Added move and copy for groups and entries
* New navigation in a single screen / new animations between activities
@@ -82,10 +371,10 @@ KeepassDX (2.5.0.0beta12)
* Fix the fingerprint recognition (WARNING : The keystore is reinit, you must delete the old keys)
* Fix small bugs
KeepassDX (2.5.0.0beta11)
KeePassDX (2.5.0.0beta11)
* Fix crash in beta10 version
KeepassDX (2.5.0.0beta10)
KeePassDX (2.5.0.0beta10)
* Dynamically change Algorithm and Key Derivation Function in settings
* Upgrade translations
* New red volcano theme, fix classic dark theme
@@ -93,7 +382,7 @@ KeepassDX (2.5.0.0beta10)
* Update fingerprint state with checkbox
* Fix bugs
KeepassDX (2.5.0.0beta9)
KeePassDX (2.5.0.0beta9)
* Education Screens to learn how to use the app
* New designs
* New custom font for character visibility
@@ -102,9 +391,9 @@ KeepassDX (2.5.0.0beta9)
* Change setting organisation
* Pro version
KeepassDX (2.5.0.0beta8)
KeePassDX (2.5.0.0beta8)
* Hide custom entries protected
* Best management of field references (https://keepass.info/help/base/fieldrefs.html)
* Best management of field references (https://KeePass.info/help/base/fieldrefs.html)
* Change database / default settings
* Add Autofill for search
* Add sorting by last access and by creation time
@@ -112,7 +401,7 @@ KeepassDX (2.5.0.0beta8)
* Refactor old code
* Fix bugs
KeepassDX (2.5.0.0beta7)
KeePassDX (2.5.0.0beta7)
* Rebuild Notifications
* Change links to https
* Add extended Ascii (ñæËÌÂÝÜ...)
@@ -121,10 +410,10 @@ KeepassDX (2.5.0.0beta7)
* Add setting to prevent the password copy
* Fix bugs
KeepassDX (2.5.0.0beta6)
KeePassDX (2.5.0.0beta6)
* Fix crash
KeepassDX (2.5.0.0beta5)
KeePassDX (2.5.0.0beta5)
* Autofill (Android O)
* Deletion for group
* New sorts with (Asc/Dsc, Groups before or after)
@@ -145,7 +434,7 @@ KeepassDX (2.5.0.0beta5)
* Fix many small bugs
* Add recycle bin setting (not yet accessible)
KeepassDX (2.5.0.0beta4)
KeePassDX (2.5.0.0beta4)
* Show only file name
* Setting for full path
* Add information for each database file
@@ -154,7 +443,7 @@ KeepassDX (2.5.0.0beta4)
* Delete view assignment for fingerprint opening
* Merge KeePassDroid 2.2.1
KeepassDX (2.5.0.0beta3)
KeePassDX (2.5.0.0beta3)
* New database workflow with new screens and folder selection
* Settings for default password generation
* Fingerprint dialog for explanations
@@ -165,17 +454,17 @@ KeepassDX (2.5.0.0beta3)
* Merge KeePassDroid 2.2.0.9
* Add corruption fix mode
KeepassDX (2.5.0.0beta2)
KeePassDX (2.5.0.0beta2)
* Remove libs for F-Droid
KeepassDX (2.5.0.0beta1)
* Fork KeepassDroid
KeePassDX (2.5.0.0beta1)
* Fork KeePassDroid
* Add Material Design
* Add Light and Night theme
* Min API is 14
* Solve bug for fingerprint
* Update French translation
* Change donation (see KeepassDroid to contribute on both projects)
* Change donation (see KeePassDroid to contribute on both projects)
KeePassDroid (2.2.1)
* Fix kdbx4 date corruption
@@ -436,7 +725,7 @@ KeePassDroid (1.9.10)
KeePassDroid (1.9.9)
* Go back to explicitly storing blank fields in the database
(works around bug in keepassx)
(works around bug in KeePassx)
* Add support for native code on MIPS architectures
* Adding Vibrate permission. On some devices notifications fail
without the vibrate permission.

View File

@@ -1,45 +0,0 @@
Original author:
Brian Pellin
Achim Weimert
Johan Berts - search patches
Mike Mohr - Better native code for aes and sha
Tobias Selig - icon support
Tolga Onbay, Dirk Bergstrom - password generator
Space Cowboy - holo theme
josefwells
Nicholas FitzRoy-Dale - auto launch intents
yulin2 - responsiveness improvements
Tadashi Saito
vhschlenker
bumper314 - Samsung multiwindow support
Hans Cappelle - fingerprint sensor integration
Jeremy Jamet - Keepass DX Material Design - Patches
Translations:
Diego Pierotto - Italian
Laurent, Norman Obry, Nam, Bruno Parmentier, Credomo - French
Maciej Bieniek, cod3r - Polish
Максим Сёмочкин, i.nedoboy, filimonic, bboa - Russian
MaWi, rvs2008, meviox, MaDill, EdlerProgrammierer, Jan Thomas - German
yslandro - Norwegian Nynorsk
王科峰 - Chinese
Typhoon - Slovak
Masahiro Inamura - Japanese
Matsuu Takuto - Japanese
Carlos Schlyter - Portugese (Brazil)
YSmhXQDd6Z - Portugese (Portugal)
andriykopanytsia - Ukranian
intel, Zoltán Antal - Hungarian
H Vanek - Czech
jipanos - Spanish
Erik Fdevriendt, Erik Jan Meijer - Dutch
Frederik Svarre - Danish
Oriol Garrote - Catalan
Mika Takala - Finnish
Niclas Burgren - Swedish
Raimonds - Latvian
dgarciabad - Basque
Arthur Zamarin - Hebrew
RaptorTFX - Greek
zygimantus - Lithuanian

1015
LICENSE

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
Terms of Service
This is the terms of service for the Android Backup Service.
1. Your relationship with Google
1.1 Your use of the Android Backup Service (referred to as the "Service" in this document) is subject to the terms of a legal agreement between you and Google. "Google" means Google LLC, whose principal place of business is at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. This document explains how the agreement is made up, and sets out some of the terms of that agreement.
1.2 Unless otherwise agreed in writing with Google, your agreement with Google will always include, at a minimum, the terms and conditions set out in this document. These are referred to below as the "Terms".
1.3 The Terms form a legally binding agreement between you and Google in relation to your use of the Service. It is important that you take the time to read them carefully.
2. Accepting the Terms
2.1 In order to use the Service, you must first agree to the Terms. You may not use the Service if you do not accept the Terms.
2.2 You can accept the Terms by clicking to accept or agree to the Terms, where this option is made available to you by Google.
2.3 You may not use the Service and may not accept the Terms if you are not of legal age to form a binding contract with Google.
2.4 You represent that you have full power, capacity and authority to accept these Terms. If you are accepting on behalf of your employer or another entity, you represent that you have full legal authority to bind your employer or such entity to these Terms. If you don't have the legal authority to bind, please ensure that an authorized person from your entity consents to and accepts these Terms.
3. Provision of the Service by Google
3.1 Google has subsidiaries and affiliated legal entities around the world ("Subsidiaries and Affiliates"). Sometimes, these companies will be providing the Service to you on behalf of Google itself. You acknowledge and agree that Subsidiaries and Affiliates will be entitled to provide the Service to you.
3.2 Google is constantly innovating in order to provide the best possible experience for its users. You acknowledge and agree that the form and nature of the Service which Google provides may change from time to time without prior notice to you.
3.3 As part of this continuing innovation, you acknowledge and agree that Google may stop (permanently or temporarily) providing the Service (or any features within the Service) to you or to users generally at Google's sole discretion, without prior notice to you. You may stop using the Service at any time. You do not need to specifically inform Google when you stop using the Service.
3.4 You acknowledge and agree that if Google disables your Backup Service Key, you and the Android application(s) you developed ("Application(s)") may be prevented from accessing the Service and any content that is stored with the Service.
3.5 You acknowledge and agree that Google may set a fixed upper limit on the number of backup transmissions you may send or receive through the Service or on the amount of storage space used for the provision of the Service at any time, at Google's discretion. You agree to abide by any such fixed upper limits.
4. Use of the Service by you
4.1 In order to access the Service, you must have a unique application identifier ("Package Name") for your Application as described in the documentation for the Service.
4.2 After supplying Google with the Package Name and accepting the Terms, you will be issued an alphanumeric key ("Backup Service Key") assigned to you by Google that is uniquely associated with your Application. Your Application must include this Backup Service Key as described in the documentation for the Service.
4.3 There is currently no limit to the number of Backup Service Keys you may obtain in this manner provided that you use a different Package Name for each Backup Service Key you obtain. You agree that each Backup Service Key is only valid for Applications with the corresponding Package Name. You agree that Google may, in its sole discretion, impose a limit on the number of Backup Service Keys that may be obtained in the future. You agree that your continued use of any of the Backup Service Keys assigned by Google, or distribution of any Applications using such Backup Service Keys, constitutes your continued agreement to these Terms.
4.4 You agree to use the Service only for purposes that are permitted by (a) the Terms and (b) any applicable law, regulation, third-party terms of service, or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
4.5 You agree not to access (or attempt to access) any of the Service by any means other than through the interfaces, methods, and APIs that are provided by Google, unless you have been specifically allowed to do so in a separate agreement with Google.
4.6 You agree that you will not engage in any activity that interferes with or disrupts the Service (or the servers and networks which are connected to the Service), or the servers or networks of any third-party.
4.7 You agree that your use of the Service will be in compliance with any documentation guidelines provided by Google and that failure to comply with the documentation guidelines may result in the disabling of the Backup Service Key(s) for your Application(s).
4.8 Unless you have been specifically permitted to do so in a separate agreement with Google, you agree that you will not reproduce, duplicate, copy, sell, trade or resell (a) use of the Service, or (b) access to the Service.
4.9 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) your and your Application's use of the Service, any breach of your obligations under the Terms, and for the consequences (including any loss or damage which Google may suffer) of any such breach.
4.10 You agree that in your use of the Service, you and your Applications will protect the privacy and legal rights of users. You must provide legally adequate privacy notice and protection for users whose data your Applications back up to the Service. Further, your Application may only use that information for the limited purpose of backing up the data to the Service unless the user has given you permission for further use. If the user has not given you permission to back up information to the Service, you may not transmit such information to the Service.
4.11 You agree that you and your Applications will not transmit or store sensitive user information, such as user names, passwords, or credit card numbers, through the Service.
5. Security
5.1 You agree and understand that you are responsible for maintaining the security associated with any information you provide to access the Service as well as of the Backup Service Key(s) assigned to you by Google. You agree that only you are authorized to use the Backup Service Key(s) assigned to you.
5.2 Accordingly, you agree that you will be solely responsible to Google for all activities that occur in connection with your access to the Service, as well as the Backup Service Key.
5.3 If you become aware of any unauthorized use of your Backup Service Key(s) you agree to notify Google immediately.
6. Privacy and your personal information
6.1 For information about Google's data protection practices, please read Google's privacy policy at http://www.google.com/privacy.html. This policy explains how Google treats your personal information when you use the Service.
6.2 You agree to the use of your data in accordance with Google's privacy policies.
7. Content in the Service
7.1 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any Content that you or your Applications transmit or store through the Service and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so. You agree that you are solely responsible for (A) any Content that is transmitted through the Service by your Applications, and (B) any Content that Devices retrieve from the Service by virtue of your Applications. For purposes of the Terms, "Content" means information such as data, messages, settings information, written text, computer software, music, audio files or other sounds, photographs, videos or other images. "Device(s)" means device(s) powered by the Android operating system.
7.2 You agree that you will not transmit any Content through the Service that is copyrighted, protected by trade secret or otherwise subject to third party proprietary rights, including patent, privacy and publicity rights, unless you are the owner of such rights or have permission from their rightful owner to transmit the Content through the Service.
8. Proprietary rights
8.1 You acknowledge and agree that Google (or Google's licensors) own all legal right, title and interest in and to the Service, including any intellectual property rights which subsist in the Service (whether those rights happen to be registered or not, and wherever in the world those rights may exist).
8.2 Unless you have agreed otherwise in writing with Google, nothing in the Terms gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, and other distinctive brand features.
8.3 If you have been given an explicit right to use any of these brand features in a separate written agreement with Google, then you agree that your use of such features shall be in compliance with that agreement, any applicable provisions of the Terms, and Google's brand feature use guidelines as updated from time to time. These guidelines can be viewed online at http://www.google.com/permissions/ guidelines.html (or such other URL as Google may provide for this purpose from time to time).
8.4 You agree that you shall not remove, obscure, or alter any proprietary rights notices (including copyright, trade mark notices) which may be affixed to or contained within the Service.
9. License from Google
9.1 Subject to terms and conditions of these Terms, Google gives you a personal, worldwide, royalty-free, non-assignable and non-exclusive license to use the Service as provided to you by Google. This license is for the sole purpose of enabling you to use and enjoy the benefit of the Service as provided by Google, in the manner permitted by the Terms.
9.2 You may not (and you may not permit anyone else to) copy, modify, create a derivative work of, reverse engineer, decompile or otherwise attempt to extract the source code from the Service or any part thereof, unless this is expressly permitted or required by law, or unless you have been specifically told that you may do so by Google, in writing.
9.3 Unless Google has given you specific written permission to do so, you may not assign (or grant a sub-license of) your rights to use the Service, grant a security interest in or over your rights to use the Service, or otherwise transfer any part of your rights to use the Service.
10. Your code
10.1 Google claims no ownership or control over any source code written by you to be used with the Service. You retain copyright and any other rights you already hold in this code, and you are responsible for protecting those rights, as appropriate.
11. Ending your relationship with Google
11.1 The Terms will continue to apply until terminated by either you or Google as set out below.
11.2 You may terminate your legal agreement with Google by discontinuing your use of the Service at any time.
11.3 Google may, at any time, terminate its legal agreement with you if:
(A) you have breached any provision of the Terms (or have acted in manner which clearly shows that you do not intend to, or are unable to comply with the provisions of the Terms); or
(B) Google is required to do so by law (for example, where the provision of the Service to you is, or becomes, unlawful); or
(C) Google is transitioning to no longer providing the Service; or
(D) your Application fails to meet the documentation guidelines provided by Google.
11.4 Nothing in this Section shall affect Google's rights regarding provision of the Service under Section 3 of the Terms.
11.5 When these Terms come to an end, all of the legal rights, obligations and liabilities that you and Google have benefited from, been subject to (or which have accrued over time whilst the Terms have been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the provisions of Sections 12, 13 and Paragraph 16 shall continue to apply to such rights, obligations and liabilities indefinitely.
12. EXCLUSION OF WARRANTIES
12.1 NOTHING IN THESE TERMS, INCLUDING SECTIONS 12 AND 13, SHALL EXCLUDE OR LIMIT GOOGLE'S WARRANTY OR LIABILITY FOR LOSSES WHICH MAY NOT BE LAWFULLY EXCLUDED OR LIMITED BY APPLICABLE LAW. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR CONDITIONS OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR LOSS OR DAMAGE CAUSED BY NEGLIGENCE, BREACH OF CONTRACT OR BREACH OF IMPLIED TERMS, OR INCIDENTAL OR CONSEQUENTIAL DAMAGES. ACCORDINGLY, ONLY THE LIMITATIONS WHICH ARE LAWFUL IN YOUR JURISDICTION WILL APPLY TO YOU AND OUR LIABILITY WILL BE LIMITED TO THE MAXIMUM EXTENT PERMITTED BY LAW.
12.2 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SERVICE IS AT YOUR SOLE RISK AND THAT THE SERVICE AND CONTENT ARE PROVIDED "AS IS" AND "AS AVAILABLE".
12.3 IN PARTICULAR, GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS DO NOT REPRESENT OR WARRANT TO YOU THAT:
(A) YOUR USE OF THE SERVICE WILL MEET YOUR REQUIREMENTS,
(B) YOUR USE OF THE SERVICE WILL BE UNINTERRUPTED, TIMELY, SECURE OR FREE FROM ERROR, AND
(C) THAT DEFECTS IN THE OPERATION OR FUNCTIONALITY OF ANY SOFTWARE PROVIDED TO YOU AS PART OF THE SERVICE WILL BE CORRECTED.
12.4 NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM GOOGLE OR THROUGH OR FROM THE SERVICE SHALL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN THE TERMS.
12.5 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
13. LIMITATION OF LIABILITY
13.1 SUBJECT TO OVERALL PROVISION IN PARAGRAPH 12.1 ABOVE, YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU FOR:
(A) ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL CONSEQUENTIAL OR EXEMPLARY DAMAGES WHICH MAY BE INCURRED BY YOU, HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY. THIS SHALL INCLUDE, BUT NOT BE LIMITED TO, ANY LOSS OF PROFIT (WHETHER INCURRED DIRECTLY OR INDIRECTLY), ANY LOSS OF GOODWILL OR BUSINESS REPUTATION, ANY LOSS OF DATA SUFFERED, COST OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICE, OR OTHER INTANGIBLE LOSS;
(B) ANY LOSS OR DAMAGE WHICH MAY BE INCURRED BY YOU, INCLUDING BUT NOT LIMITED TO LOSS OR DAMAGE AS A RESULT OF:
(I) ANY CHANGES WHICH GOOGLE MAY MAKE TO THE SERVICE, OR FOR ANY PERMANENT OR TEMPORARY CESSATION IN THE PROVISION OF THE SERVICE (OR ANY FEATURES WITHIN THE SERVICE);
(II) THE DELETION OF, CORRUPTION OF, OR FAILURE TO STORE, ANY CONTENT AND OTHER COMMUNICATIONS DATA MAINTAINED OR TRANSMITTED BY OR THROUGH YOUR USE OF THE SERVICE;
(III) YOUR FAILURE TO PROVIDE GOOGLE WITH ACCURATE ACCOUNT INFORMATION; OR
(IV) YOUR FAILURE TO KEEP YOUR PASSWORD OR ACCOUNT DETAILS SECURE AND CONFIDENTIAL.
13.2 THE LIMITATIONS ON GOOGLE'S LIABILITY TO YOU IN PARAGRAPH 13.1 ABOVE SHALL APPLY WHETHER OR NOT GOOGLE HAS BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
14. Indemnification
14.1 You agree to hold harmless and indemnify Google, and its subsidiaries, affiliates, officers, agents, employees, or licensors from and against any third party claim arising from or in any way related to (a) your breach of the Terms, (b) your use of the Service, or (c) your violation of applicable laws, rules or regulations in connection with the Service, including any liability or expense arising from all claims, losses, damages (actual and consequential), suits, judgments, litigation costs and attorneys' fees, of every kind and nature. In such a case, Google will provide you with written notice of such claim, suit or action.
15. Changes to the Terms
15.1 Due to things like changes to the law or changes to functionality offered through the Service, Google may need to change these Terms from time to time. You should look at the Terms regularly. We'll post notice of the modified Terms within, or through, the Service. Once the modified Terms are posted, the changes will become effective immediately, and you are deemed to have accepted the modified Terms if you continue to use the Service. If you do not agree to the modified Terms for the Service, please stop using the Service.
16. General legal terms
16.1 The Terms constitute the whole legal agreement between you and Google and govern your use of the Service (but excluding any service which Google may provide to you under a separate written agreement), and completely replace any prior agreements between you and Google in relation to the Service.
16.2 You agree that Google may provide you with notices, including those regarding changes to the Terms, by email, regular mail, or postings on the Service.
16.3 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the Terms (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
16.4 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of these Terms is invalid, then that provision will be removed from the Terms without affecting the rest of the Terms. The remaining provisions of the Terms will continue to be valid and enforceable.
16.5 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the Terms and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the Terms which confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the Terms.
16.6 The Terms, and your relationship with Google under the Terms, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the Terms. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.

202
LICENSES/LICENSE_APACHE Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,7 @@
Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,111 @@
Files ic00.png to ic61.png under res/drawable, res/drawable-hdpi and res/drawable-ldpi
TITLE: NUVOLA ICON THEME for KDE 3.x
AUTHOR: David Vignoni | ICON KING
SITE: http://www.icon-king.com
MAILING LIST: http://mail.icon-king.com/mailman/listinfo/nuvola_icon-king.com
Copyright (c) 2003-2004 David Vignoni.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library (see the the license.txt file); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#######**** NOTE THIS ADD-ON ****#######
The GNU Lesser General Public License or LGPL is written for software libraries
in the first place. The LGPL has to be considered valid for this artwork
library too.
Nuvola icon theme for KDE 3.x is a special kind of software library, it is an
artwork library, it's elements can be used in a Graphical User Interface, or
GUI.
Source code, for this library means:
- raster png image* .
The LGPL in some sections obliges you to make the files carry
notices. With images this is in some cases impossible or hardly usefull.
With this library a notice is placed at a prominent place in the directory
containing the elements. You may follow this practice.
The exception in section 6 of the GNU Lesser General Public License covers
the use of elements of this art library in a GUI.
dave [at] icon-king.com
Date: 15 october 2004
Version: 1.0
DESCRIPTION:
Icon theme for KDE 3.x.
Icons where designed using Adobe Illustrator, and then exported to PNG format.
Icons shadows and minor corrections were done using Adobe Photoshop.
Kiconedit was used to correct some 16x16 and 22x22 icons.
LICENSE
Released under GNU Lesser General Public License (LGPL)
Look at the license.txt file.
CONTACT
David Vignoni
e-mail : david [at] icon-king.com
ICQ : 117761009
http: http://www.icon-king.com
---
Files ic62.png under res/drawable, res/drawable-hdpi and res/drawable-ldpi
Based on http://de.wikipedia.org/w/index.php?title=Datei:Tux.svg&filetimestamp=20090927073505
The copyright holder of this file allows anyone to use it for any purpose,
provided that the copyright holders Larry Ewing, Simon Budig and
Anja Gerwinski are mentioned.
---
Files ic63.png under res/drawable, res/drawable-hdpi and res/drawable-ldpi
Based on http://en.wikipedia.org/wiki/File:ASF-logo.svg
Apache logo
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may
obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
---
Files ic64.png under res/drawable, res/drawable-hdpi and res/drawable-ldpi
Created by Jeremy JAMET and licensed under the terms of the GPLv3.
---
Files ic65.png, ic67.png and ic68.png under res/drawable, res/drawable-hdpi and res/drawable-ldpi
Created by Tobias Selig and licensed under the terms of the GPLv2 or GPLv3.
---
File ic66.png under under res/drawable, res/drawable-hdpi and res/drawable-ldpi
Based on http://commons.wikimedia.org/wiki/File:Dollar_symbol_gold.svg
Author: Rugby471
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Free Documentation License, Version 1.2 or any later
version published by the Free Software Foundation; with no Invariant Sections,
no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is
included in the section entitled "GNU Free Documentation License".
---

View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

91
README.md Normal file
View File

@@ -0,0 +1,91 @@
# Android KeePassDX
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/icon.png"> KeePassDX is a **multi-format KeePass manager for Android devices**. The app allows creating keys and passwords in a secure way by integrating with the Android design standards.
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/screen.jpg" width="220">
### Features
- Create database files / entries and groups.
- Support for **.kdb** and **.kdbx** files (version 1 to 4) with AES - Twofish - ChaCha20 - Argon2 algorithm.
- **Compatible** with the majority of alternative programs (KeePass, KeePassX, KeePassXC, …).
- Allows opening and **copying URI / URL fields quickly**.
- **Biometric recognition** for fast unlocking *(fingerprint / face unlock / …)*.
- **One-Time Password** management *(HOTP / TOTP)* for Two-factor authentication (2FA).
- Material design with **themes**.
- **Auto-Fill** and Integration.
- Field filling **keyboard**.
- **History** of each entry.
- Precise management of **settings**.
- Code written in **native languages** *(Kotlin / Java / JNI / C)*.
KeePassDX is **open source** and **ad-free**.
## What is KeePassDX?
An alternative to remembering an endless list of passwords manually. This is made more difficult by **using different passwords for each account**. If you use one password everywhere and security fails only one of those places, it grants access to your e-mail account, website, etc, and you may not know about it or notice, before bad things happen.
KeePassDX is a **password manager for Android**, which helps you **manage your passwords in a secure way**. You can put all your passwords in one database, locked with a **master key** and/or a **keyfile**. You **only have to remember one single master password and/or select the keyfile** to unlock the whole database. The databases are encrypted using the best and **most secure encryption algorithms** currently known.
## Small print?
KeePassDX is under **open source GPL3 license**, meaning you can use, study, change and share it at will. Copyleft ensures it stays that way.
From the full source, anyone can build, fork, and check whether for example the encryption algorithms are implemented correctly.
There is **no advertising**.
Do not worry, **the main features remain completely free**.
Optional visual styles are accessible after a contribution (and a congratulatory message (Ո‿Ո) ) or the purchase of an extended version to encourage contribution to the work of open source projects!
*If you contribute to the project and do not have access to the styles, do not hesitate to contact the author at [contact@kunzisoft.com](contact@kunzisoft.com).*
## Contributions
* Add features by making a **[pull request](https://help.github.com/articles/about-pull-requests/)**.
* Help to **[translate](https://hosted.weblate.org/projects/keepass-dx/strings/)** KeePassDX to your language (on [Weblate](https://hosted.weblate.org/projects/keepass-dx/) or by sending a [pull request](https://help.github.com/articles/about-pull-requests/)).
* **[Donate](https://www.kunzisoft.com/donation)** 人◕ ‿‿ ◕人Y for a better service and a quick development of your features.
* Buy the **[Pro version](https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro)** of KeePassDX.
## Download
*[F-Droid](https://f-droid.org/en/packages/com.kunzisoft.keepass.libre/) is the recommended way of installing, a libre software project that verifies that all the libraries and app code is libre software.*
[<img src="https://f-droid.org/badge/get-it-on.png"
alt="Get it on F-Droid"
height="80">](https://f-droid.org/en/packages/com.kunzisoft.keepass.libre/)
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.free)
## Frequently Asked Questions
Other questions? You can read the [FAQ](https://github.com/Kunzisoft/KeePassDX/wiki/FAQ)
## Other devices
- [KeePass](https://keepass.info/) (https://keepass.info/) is the original and official project for the desktop, with technical documentation for standardized database files. It is updated regularly with active maintenance (written in C#).
- [KeePassXC](https://keepassxc.org/) (https://keepassxc.org/) is an alternative integration of KeePass written in C++.
- [KeeWeb](https://keeweb.info/) (https://keeweb.info/) is a web version that is also compatible with KeePass files.
## License
Copyright © 2020 Jeremy Jamet / [Kunzisoft](https://www.kunzisoft.com).
This file is part of KeePassDX.
[KeePassDX](https://www.keepassdx.com) 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/>.
*This project is a fork of [KeePassDroid](https://github.com/bpellin/keepassdroid) by bpellin.*

View File

@@ -1,84 +0,0 @@
# Android Keepass DX
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/icon.png"> Keepass DX is a **multi-format KeePass manager for Android devices**. The application allows to create keys and passwords in a secure way by integrating with the Android design standards.
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/screen.jpg" width="220">
### Features
* Create database files / entries and groups
* Support for **.kdb** and **.kdbx** files (version 1 to 4) with AES - Twofish - ChaCha20 - Argon2 algorithm
* **Compatible** with the majority of alternative programs (KeePass, KeePassX, KeePass XC...)
* Allows **fast copy** of fields and opening of URI / URL
* **Fingerprint** for fast unlocking
* Material design with **themes**
* **AutoFill** and Integration
* Field filling **keyboard**
* Precise management of **settings**
* Code written in **native language** *(Kotlin / Java / JNI / C)*
Keepass DX is **open source** and **ad-free**.
## What is KeePass DX?
Today you need to remember many passwords. You need a password for your e-mail account, your website's FTP password, online passwords (like website member account), etc. etc. etc. The list is endless. Also, you **should use different passwords for each account**. Because if you use only one password everywhere and someone gets this password you have a problem... A serious problem. The thief would have access to your e-mail account, website, etc. Unimaginable.
KeePass DX is a **free open source password manager for Android**, which helps you to **manage your passwords in a secure way**. You can put all your passwords in one database, which is locked with one **master key** or a **key file**. So you **only have to remember one single master password or select the key file** to unlock the whole database. The databases are encrypted using the best and **most secure encryption algorithms** currently known.
## Is it really free?
Yes, KeePass DX is under **free license (OSI certified)** and **without advertising**. You can have a look at its full source and check whether the encryption algorithms are implemented correctly.
*Note : If you access the application from a store, visual features may not be available to incentivize the contribution to the work of open source projects. These optional visuals are accessible after a donation (and a small congratulation message :) or the purchase of an extended version, but do not worry, the main features remain completely free. If you contribute to the project and you do not have access to the themes, do not hesitate to contact me at [contact@kunzisoft.com](contact@kunzisoft.com), I will give you the procedure.*
## Contributions
You can contribute in different ways to help us on our work.
* Add features by a **[pull request](https://help.github.com/articles/about-pull-requests/)**.
* Help to **[translate](https://hosted.weblate.org/projects/keepass-dx/strings/)** into your language (By using [Weblate](https://hosted.weblate.org/projects/keepass-dx/) or with a manual [pull request](https://help.github.com/articles/about-pull-requests/))
* **[Donate](https://www.kunzisoft.com/donation)** 人◕ ‿‿ ◕人Y for a better service and a quick development of your features.
* Buy the **[Pro version](https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro)** of KeePass DX
## Download
*We recommend the installation from [F-Droid](https://f-droid.org/en/packages/com.kunzisoft.keepass.libre/) which verifies that all libraries and application code are open source.*
[<img src="https://f-droid.org/badge/get-it-on.png"
alt="Get it on F-Droid"
height="80">](https://f-droid.org/en/packages/com.kunzisoft.keepass.libre/)
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.free)
## F.A.Q.
Other questions? You can read the [F.A.Q.](https://www.keepassdx.com/FAQ)
## Other devices
- [KeePass XC](https://keepassxc.org/) (https://keepassxc.org/) works with **GNU/Linux**, **Mac** and **Windows**, is updated regularly and under the terms of the GNU General Public License. This is the recommended version for computers.
- [KeePass](https://keepass.info/) (https://keepass.info/) is the historical project, with good technical documentation for standardized database files but only running on **Windows**.
## License
Copyright (c) 2019 Jeremy Jamet / [Kunzisoft](https://www.kunzisoft.com).
This file is part of KeePass DX.
[KeePass DX](https://www.keepassdx.com) 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.
KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*This project is a fork of [KeepassDroid](https://github.com/bpellin/keepassdroid) by bpellin.*

View File

@@ -1,33 +1,34 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
compileSdkVersion 30
buildToolsVersion "30.0.3"
ndkVersion "21.4.7075529"
defaultConfig {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 28
versionCode = 23
versionName = "2.5.0.0beta23"
minSdkVersion 15
targetSdkVersion 30
versionCode = 78
versionName = "2.10.1"
multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests"
testInstrumentationRunner = "android.test.InstrumentationTestRunner"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String[]", "ICON_PACKS", "{\"classic\",\"material\"}"
}
manifestPlaceholders = [ googleAndroidBackupAPIKey:"unused" ]
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt"
kapt {
arguments {
arg("room.incremental", "true")
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
}
buildTypes {
release {
minifyEnabled = false
@@ -35,35 +36,46 @@ android {
}
}
dexOptions {
}
flavorDimensions "tier"
flavorDimensions "version"
productFlavors {
libre {
dimension "version"
applicationIdSuffix = ".libre"
buildConfigField "String", "BUILD_VERSION", "\"libre\""
buildConfigField "boolean", "FULL_VERSION", "true"
buildConfigField "boolean", "CLOSED_STORE", "false"
buildConfigField "String[]", "STYLES_DISABLED", "{\"KeepassDXStyle_Dark\",\"KeepassDXStyle_Red\",\"KeepassDXStyle_Purple\"}"
buildConfigField "String[]", "STYLES_DISABLED",
"{\"KeepassDXStyle_Red\"," +
"\"KeepassDXStyle_Red_Night\"," +
"\"KeepassDXStyle_Purple\"," +
"\"KeepassDXStyle_Purple_Dark\"}"
buildConfigField "String[]", "ICON_PACKS_DISABLED", "{}"
}
pro {
dimension "version"
applicationIdSuffix = ".pro"
buildConfigField "String", "BUILD_VERSION", "\"pro\""
buildConfigField "boolean", "FULL_VERSION", "true"
buildConfigField "boolean", "CLOSED_STORE", "true"
buildConfigField "String[]", "STYLES_DISABLED", "{}"
buildConfigField "String[]", "ICON_PACKS_DISABLED", "{}"
manifestPlaceholders = [ googleAndroidBackupAPIKey:"AEdPqrEAAAAIZiXvrQCzSV9LNI6-p7cjTKENZLHIrz_zaqZuQQ" ]
}
free {
dimension "version"
applicationIdSuffix = ".free"
buildConfigField "String", "BUILD_VERSION", "\"free\""
buildConfigField "boolean", "FULL_VERSION", "false"
buildConfigField "boolean", "CLOSED_STORE", "true"
buildConfigField "String[]", "STYLES_DISABLED", "{\"KeepassDXStyle_Dark\",\"KeepassDXStyle_Blue\",\"KeepassDXStyle_Red\",\"KeepassDXStyle_Purple\"}"
buildConfigField "String[]", "STYLES_DISABLED",
"{\"KeepassDXStyle_Blue\"," +
"\"KeepassDXStyle_Blue_Night\"," +
"\"KeepassDXStyle_Red\"," +
"\"KeepassDXStyle_Red_Night\"," +
"\"KeepassDXStyle_Purple\"," +
"\"KeepassDXStyle_Purple_Dark\"}"
buildConfigField "String[]", "ICON_PACKS_DISABLED", "{}"
manifestPlaceholders = [ googleAndroidBackupAPIKey:"AEdPqrEAAAAIbRfbV8fHLItXo8OcHwrO0sSNblqhPwkc0DPTqg" ]
}
}
@@ -73,42 +85,57 @@ android {
free.res.srcDir 'src/free/res'
}
testOptions {
unitTests.includeAndroidResources = true
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
def spongycastleVersion = "1.58.0.0"
def room_version = "2.1.0"
def room_version = "2.2.6"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.biometric:biometric:1.0.0-beta01'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.biometric:biometric:1.1.0'
// Lifecycle - LiveData - ViewModel - Coroutines
implementation "androidx.core:core-ktx:1.3.2"
implementation 'androidx.fragment:fragment-ktx:1.2.5'
// WARNING: Don't upgrade because slowdown https://github.com/Kunzisoft/KeePassDX/issues/923
implementation 'com.google.android.material:material:1.1.0'
// Database
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "com.madgag.spongycastle:core:$spongycastleVersion"
implementation "com.madgag.spongycastle:prov:$spongycastleVersion"
// Expandable view
implementation 'net.cachapa.expandablelayout:expandablelayout:2.9.2'
// Autofill
implementation "androidx.autofill:autofill:1.1.0"
// Time
implementation 'joda-time:joda-time:2.9.9'
implementation 'joda-time:joda-time:2.10.6'
// Color
implementation 'com.github.Kunzisoft:AndroidClearChroma:2.4'
// Education
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.12.0'
// Apache Commons Collections
implementation 'commons-collections:commons-collections:3.2.1'
implementation 'org.apache.commons:commons-io:1.3.2'
// Base64
implementation 'biz.source_code:base64coder:2010-12-19'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0'
// Apache Commons
implementation 'commons-io:commons-io:2.8.0'
implementation 'commons-codec:commons-codec:1.15'
// Encrypt lib
implementation project(path: ':crypto')
// Icon pack
implementation project(path: ':icon-pack-classic')
implementation project(path: ':icon-pack-material')
// Tests
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

@@ -0,0 +1,133 @@
Basic Latin
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
Latin-1 Supplement
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
Latin Extended-A
Ā ā Ă ă Ą ą Ć ć Ĉ ĉ Ċ ċ Č č Ď ď Đ đ Ē ē Ĕ ĕ Ė ė Ę ę Ě ě Ĝ ĝ Ğ ğ Ġ ġ Ģ ģ Ĥ ĥ Ħ ħ Ĩ ĩ Ī ī Ĭ ĭ Į į İ ı IJ ij Ĵ ĵ Ķ ķ ĸ Ĺ ĺ Ļ ļ Ľ ľ Ŀ ŀ Ł ł Ń ń Ņ ņ Ň ň ʼn Ŋ ŋ Ō ō Ŏ ŏ Ő ő Œ œ Ŕ ŕ Ŗ ŗ Ř ř Ś ś Ŝ ŝ Ş ş Š š Ţ ţ Ť ť Ŧ ŧ Ũ ũ Ū ū Ŭ ŭ Ů ů Ű ű Ų ų Ŵ ŵ Ŷ ŷ Ÿ Ź ź Ż ż Ž ž ſ
Latin Extended-B
ƀ Ɓ Ƃ ƃ Ƅ ƅ Ɔ Ƈ ƈ Ɖ Ɗ Ƌ ƌ ƍ Ǝ Ə Ɛ Ƒ ƒ Ɠ Ɣ ƕ Ɩ Ɨ Ƙ ƙ ƚ ƛ Ɯ Ɲ ƞ Ɵ Ơ ơ Ƣ ƣ Ƥ ƥ Ʀ Ƨ ƨ Ʃ ƪ ƫ Ƭ ƭ Ʈ Ư ư Ʊ Ʋ Ƴ ƴ Ƶ ƶ Ʒ Ƹ ƹ ƺ ƻ Ƽ ƽ ƾ ƿ ǀ ǁ ǂ ǃ DŽ Dž dž LJ Lj lj NJ Nj nj Ǎ ǎ Ǐ ǐ Ǒ ǒ Ǔ ǔ Ǖ ǖ Ǘ ǘ Ǚ ǚ Ǜ ǜ ǝ Ǟ ǟ Ǡ ǡ Ǣ ǣ Ǥ ǥ Ǧ ǧ Ǩ ǩ Ǫ ǫ Ǭ ǭ Ǯ ǯ ǰ DZ Dz dz Ǵ ǵ Ǻ ǻ Ǽ ǽ Ǿ ǿ Ȁ ȁ Ȃ ȃ ...
IPA Extensions
ɐ ɑ ɒ ɓ ɔ ɕ ɖ ɗ ɘ ə ɚ ɛ ɜ ɝ ɞ ɟ ɠ ɡ ɢ ɣ ɤ ɥ ɦ ɧ ɨ ɩ ɪ ɫ ɬ ɭ ɮ ɯ ɰ ɱ ɲ ɳ ɴ ɵ ɶ ɷ ɸ ɹ ɺ ɻ ɼ ɽ ɾ ɿ ʀ ʁ ʂ ʃ ʄ ʅ ʆ ʇ ʈ ʉ ʊ ʋ ʌ ʍ ʎ ʏ ʐ ʑ ʒ ʓ ʔ ʕ ʖ ʗ ʘ ʙ ʚ ʛ ʜ ʝ ʞ ʟ ʠ ʡ ʢ ʣ ʤ ʥ ʦ ʧ ʨ
Spacing Modifier Letters
ʰ ʱ ʲ ʳ ʴ ʵ ʶ ʷ ʸ ʹ ʺ ʻ ʼ ʽ ʾ ʿ ˀ ˁ ˂ ˃ ˄ ˅ ˆ ˇ ˈ ˉ ˊ ˋ ˌ ˍ ˎ ˏ ː ˑ ˒ ˓ ˔ ˕ ˖ ˗ ˘ ˙ ˚ ˛ ˜ ˝ ˞ ˠ ˡ ˢ ˣ ˤ ˥ ˦ ˧ ˨ ˩
Combining Diacritical Marks
̀ ́ ̂ ̃ ̄ ̅ ̆ ̇ ̈ ̉ ̊ ̋ ̌ ̍ ̎ ̏ ̐ ̑ ̒ ̓ ̔ ̕ ̖ ̗ ̘ ̙ ̚ ̛ ̜ ̝ ̞ ̟ ̠ ̡ ̢ ̣ ̤ ̥ ̦ ̧ ̨ ̩ ̪ ̫ ̬ ̭ ̮ ̯ ̰ ̱ ̲ ̳ ̴ ̵ ̶ ̷ ̸ ̹ ̺ ̻ ̼ ̽ ̾ ̿ ̀ ́ ͂ ̓ ̈́ ͅ ͠ ͡
Greek
ʹ ͵ ͺ ; ΄ ΅ Ά · Έ Ή Ί Ό Ύ Ώ ΐ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ Φ Χ Ψ Ω Ϊ Ϋ ά έ ή ί ΰ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω ϊ ϋ ό ύ ώ ϐ ϑ ϒ ϓ ϔ ϕ ϖ Ϛ Ϝ Ϟ Ϡ Ϣ ϣ Ϥ ϥ Ϧ ϧ Ϩ ϩ Ϫ ϫ Ϭ ϭ Ϯ ϯ ϰ ϱ ϲ ϳ
Cyrillic
Ё Ђ Ѓ Є Ѕ І Ї Ј Љ Њ Ћ Ќ Ў Џ А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я ё ђ ѓ є ѕ і ї ј љ њ ћ ќ ў џ Ѡ ѡ Ѣ ѣ Ѥ ѥ Ѧ ѧ Ѩ ѩ Ѫ ѫ Ѭ ѭ Ѯ ѯ Ѱ ѱ Ѳ ѳ Ѵ ѵ Ѷ ѷ Ѹ ѹ Ѻ ѻ Ѽ ѽ Ѿ ѿ Ҁ ҁ ҂ ҃ ...
Armenian
Ա Բ Գ Դ Ե Զ Է Ը Թ Ժ Ի Լ Խ Ծ Կ Հ Ձ Ղ Ճ Մ Յ Ն Շ Ո Չ Պ Ջ Ռ Ս Վ Տ Ր Ց Ւ Փ Ք Օ Ֆ ՙ ՚ ՛ ՜ ՝ ՞ ՟ ա բ գ դ ե զ է ը թ ժ ի լ խ ծ կ հ ձ ղ ճ մ յ ն շ ո չ պ ջ ռ ս վ տ ր ց ւ փ ք օ ֆ և ։
Hebrew
֑ ֒ ֓ ֔ ֕ ֖ ֗ ֘ ֙ ֚ ֛ ֜ ֝ ֞ ֟ ֠ ֡ ֣ ֤ ֥ ֦ ֧ ֨ ֩ ֪ ֫ ֬ ֭ ֮ ֯ ְ ֱ ֲ ֳ ִ ֵ ֶ ַ ָ ֹ ֻ ּ ֽ ־ ֿ ׀ ׁ ׂ ׃ ׄ א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת װ ױ ײ ׳ ״
Arabic
، ؛ ؟ ء آ أ ؤ إ ئ ا ب ة ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ـ ف ق ك ل م ن ه و ى ي ً ٌ ٍ َ ُ ِ ّ ْ ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٪ ٫ ٬ ٭ ٰ ٱ ٲ ٳ ٴ ٵ ٶ ٷ ٸ ٹ ٺ ٻ ټ ٽ پ ٿ ڀ ځ ڂ ڃ ڄ څ چ ڇ ڈ ډ ڊ ڋ ڌ ڍ ڎ ڏ ڐ ڑ ڒ ړ ڔ ڕ ږ ڗ ژ ڙ ښ ڛ ڜ ڝ ڞ ڟ ڠ ڡ ڢ ڣ ڤ ڥ ڦ ڧ ڨ ک ڪ ګ ڬ ڭ ڮ گ ڰ ڱ ...
Devanagari
ँ ं अ आ इ ई उ ऊ ऋ ऌ ऍ ऎ ए ऐ ऑ ऒ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न ऩ प फ ब भ म य र ऱ ल ळ ऴ व श ष स ह ़ ऽ ा ि ी ु ू ृ ॄ ॅ ॆ े ै ॉ ॊ ो ौ ् ॐ ॑ ॒ ॓ ॔ क़ ख़ ग़ ज़ ड़ ढ़ फ़ य़ ॠ ॡ ॢ ॣ । ॥ १ २ ३ ४ ५ ६ ७ ८ ९ ॰
Bengali
ঁ ং ঃ অ আ ই ঈ উ ঊ ঋ ঌ এ ঐ ও ঔ ক খ গ ঘ ঙ চ ছ জ ঝ ঞ ট ঠ ড ঢ ণ ত থ দ ধ ন প ফ ব ভ ম য র ল শ ষ স হ ় া ি ী ু ূ ৃ ৄ ে ৈ ো ৌ ্ ৗ ড় ঢ় য় ৠ ৡ ৢ ৣ ১ ২ ৩ ৫ ৬ ৮ ৯ ৰ ৱ ৲ ৳ ৴ ৵ ৶ ৷ ৸ ৹ ৺
Gurmukhi
ਂ ਅ ਆ ਇ ਈ ਉ ਊ ਏ ਐ ਓ ਔ ਕ ਖ ਗ ਘ ਙ ਚ ਛ ਜ ਝ ਞ ਟ ਠ ਡ ਢ ਣ ਤ ਥ ਦ ਧ ਨ ਪ ਫ ਬ ਭ ਮ ਯ ਰ ਲ ਲ਼ ਵ ਸ਼ ਸ ਹ ਼ ਾ ਿ ੀ ੁ ੂ ੇ ੈ ੋ ੌ ੍ ਖ਼ ਗ਼ ਜ਼ ੜ ਫ਼ ੨ ੩ ੫ ੬ ੭ ੮ ੯ ੰ ੱ ੲ ੳ ੴ
Gujarati
ઁ ં અ આ ઇ ઈ ઉ ઊ ઋ ઍ એ ઐ ઑ ઓ ઔ ક ખ ગ ઘ ઙ ચ છ જ ઝ ઞ ટ ઠ ડ ઢ ણ ત થ દ ધ ન પ ફ બ ભ મ ય ર લ ળ વ શ ષ સ હ ઼ ઽ ા િ ી ુ ૂ ૃ ૄ ૅ ે ૈ ૉ ો ૌ ્ ૐ ૠ ૧ ૨ ૩ ૪ ૫ ૬ ૭ ૮ ૯
Oriya
ଁ ଂ ଅ ଆ ଇ ଈ ଉ ଊ ଋ ଌ ଏ ଐ ଓ ଔ କ ଖ ଗ ଘ ଙ ଚ ଛ ଜ ଝ ଞ ଟ ଡ ଢ ଣ ତ ଥ ଦ ଧ ନ ପ ଫ ବ ଭ ମ ଯ ର ଲ ଳ ଶ ଷ ସ ହ ଼ ଽ ା ି ୀ ୁ ୂ ୃ େ ୈ ୋ ୌ ୍ ୖ ୗ ଡ଼ ଢ଼ ୟ ୠ ୡ ୩ ୪ ୫ ୬ ୭ ୮ ୯ ୰
Tamil
ஂ ஃ அ ஆ இ ஈ உ ஊ எ ஏ ஐ ஒ ஓ ஔ க ங ச ஜ ஞ ட ண த ந ன ப ம ய ர ற ல ள ழ வ ஷ ஸ ஹ ா ி ீ ு ூ ெ ே ை ொ ோ ௌ ் ௗ ௧ ௨ ௩ ௪ ௫ ௬ ௭ ௮ ௯ ௰ ௱ ௲
Telugu
ః అ ఆ ఇ ఈ ఉ ఊ ఋ ఌ ఎ ఏ ఐ ఒ ఓ ఔ క ఖ గ ఘ ఙ చ ఛ జ ఝ ఞ ట ఠ డ ఢ ణ త థ ద ధ న ప ఫ బ భ మ య ర ఱ ల ళ వ శ ష స హ ా ి ీ ు ూ ృ ౄ ె ే ై ొ ో ౌ ్ ౕ ౖ ౠ ౡ ౧ ౨ ౩ ౪ ౫ ౬ ౭ ౮ ౯
Kannada
ಃ ಅ ಆ ಇ ಈ ಉ ಊ ಋ ಌ ಎ ಏ ಐ ಒ ಓ ಔ ಕ ಖ ಗ ಘ ಙ ಚ ಛ ಜ ಝ ಞ ಟ ಠ ಡ ಢ ಣ ತ ಥ ದ ಧ ನ ಪ ಫ ಬ ಭ ಮ ಯ ರ ಱ ಲ ಳ ವ ಶ ಷ ಸ ಹ ಾ ಿ ೀ ು ೂ ೃ ೄ ೆ ೇ ೈ ೊ ೋ ೌ ್ ೕ ೖ ೞ ೠ ೡ ೧ ೨ ೩ ೪ ೫ ೬ ೭ ೮ ೯
Malayalam
ഃ അ ആ ഇ ഈ ഉ ഊ ഋ ഌ എ ഏ ഐ ഒ ഓ ഔ ക ഖ ഗ ഘ ങ ച ഛ ജ ഝ ഞ ട ഡ ഢ ണ ത ഥ ദ ധ ന പ ഫ ബ ഭ മ യ ര റ ല ള ഴ വ ശ ഷ സ ഹ ാ ി ീ ു ൂ ൃ െ േ ൈ ൊ ോ ൌ ് ൗ ൠ ൡ ൧ ൨ ൩ ൪ ൫ ൬ ൮ ൯
Thai
ก ข ฃ ค ฅ ฆ ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น บ ป ผ ฝ พ ฟ ภ ม ย ร ฤ ล ฦ ว ศ ษ ส ห ฬ อ ฮ ฯ ะ ั า ำ ิ ี ึ ื ุ ู ฺ ฿ เ แ โ ใ ไ ๅ ๆ ็ ่ ้ ๊ ๋ ์ ํ ๎ ๏ ๑ ๒ ๓ ๔ ๕ ๖ ๗ ๘ ๙ ๚ ๛
Lao
ກ ຂ ຄ ງ ຈ ຊ ຍ ດ ຕ ຖ ທ ນ ບ ປ ຜ ຝ ພ ຟ ມ ຢ ຣ ລ ວ ສ ຫ ອ ຮ ຯ ະ ັ າ ຳ ິ ີ ຶ ື ຸ ູ ົ ຼ ຽ ເ ແ ໂ ໃ ໄ ໆ ່ ້ ໊ ໋ ໌ ໍ ໑ ໒ ໓ ໔ ໕ ໖ ໗ ໘ ໙ ໜ ໝ
Tibetan
ༀ ༁ ༂ ༃ ༄ ༅ ༆ ༇ ༈ ༉ ༊ ་ ༌ ། ༎ ༏ ༐ ༑ ༒ ༓ ༔ ༕ ༖ ༗ ༘ ༙ ༚ ༛ ༜ ༝ ༞ ༟ ༠ ༡ ༢ ༣ ༤ ༥ ༦ ༧ ༨ ༩ ༪ ༫ ༬ ༭ ༮ ༯ ༰ ༱ ༲ ༳ ༴ ༵ ༶ ༷ ༸ ༹ ༺ ༻ ༼ ༽ ༾ ༿ ཀ ཁ ག གྷ ང ཅ ཆ ཇ ཉ ཊ ཋ ཌ ཌྷ ཎ ཏ ཐ ད དྷ ན པ ཕ བ བྷ མ ཙ ཚ ཛ ཛྷ ཝ ཞ ཟ འ ཡ ར ལ ཤ ཥ ས ཧ ཨ ཀྵ ཱ ི ཱི ུ ཱུ ྲྀ ཷ ླྀ ཹ ེ ཻ ོ ཽ ཾ ཿ ྀ ཱྀ ྂ ྃ ྄ ྅ ྆ ྇ ...
Georgian
Ⴀ Ⴁ Ⴂ Ⴃ Ⴄ Ⴅ Ⴆ Ⴇ Ⴈ Ⴉ Ⴊ Ⴋ Ⴌ Ⴍ Ⴎ Ⴏ Ⴐ Ⴑ Ⴒ Ⴓ Ⴔ Ⴕ Ⴖ Ⴗ Ⴘ Ⴙ Ⴚ Ⴛ Ⴜ Ⴝ Ⴞ Ⴟ Ⴠ Ⴡ Ⴢ Ⴣ Ⴤ Ⴥ ა ბ გ დ ე ვ ზ თ ი კ ლ მ ნ ო პ ჟ რ ს ტ უ ფ ქ ღ შ ჩ ც ძ წ ჭ ხ ჯ ჰ ჱ ჲ ჳ ჴ ჵ ჶ ჻
Hangul Jamo
ᄀ ᄁ ᄂ ᄃ ᄄ ᄅ ᄆ ᄇ ᄈ ᄉ ᄊ ᄋ ᄌ ᄍ ᄎ ᄏ ᄐ ᄑ ᄒ ᄓ ᄔ ᄕ ᄖ ᄗ ᄘ ᄙ ᄚ ᄛ ᄜ ᄝ ᄞ ᄟ ᄠ ᄡ ᄢ ᄣ ᄤ ᄥ ᄦ ᄧ ᄨ ᄩ ᄪ ᄫ ᄬ ᄭ ᄮ ᄯ ᄰ ᄱ ᄲ ᄳ ᄴ ᄵ ᄶ ᄷ ᄸ ᄹ ᄺ ᄻ ᄼ ᄽ ᄾ ᄿ ᅀ ᅁ ᅂ ᅃ ᅄ ᅅ ᅆ ᅇ ᅈ ᅉ ᅊ ᅋ ᅌ ᅍ ᅎ ᅏ ᅐ ᅑ ᅒ ᅓ ᅔ ᅕ ᅖ ᅗ ᅘ ᅙ ᅡ ᅢ ᅣ ᅤ ᅥ ᅦ ᅧ ᅨ ᅩ ᅪ ᅫ ᅬ ᅭ ᅮ ᅯ ᅰ ᅱ ᅲ ᅳ ᅴ ᅵ ᅶ ᅷ ᅸ ᅹ ᅺ ᅻ ᅼ ᅽ ᅾ ᅿ ᆀ ᆁ ᆂ ᆃ ᆄ ...
Latin Extended Additional
Ḁ ḁ Ḃ ḃ Ḅ ḅ Ḇ ḇ Ḉ ḉ Ḋ ḋ Ḍ ḍ Ḏ ḏ Ḑ ḑ Ḓ ḓ Ḕ ḕ Ḗ ḗ Ḙ ḙ Ḛ ḛ Ḝ ḝ Ḟ ḟ Ḡ ḡ Ḣ ḣ Ḥ ḥ Ḧ ḧ Ḩ ḩ Ḫ ḫ Ḭ ḭ Ḯ ḯ Ḱ ḱ Ḳ ḳ Ḵ ḵ Ḷ ḷ Ḹ ḹ Ḻ ḻ Ḽ ḽ Ḿ ḿ Ṁ ṁ Ṃ ṃ Ṅ ṅ Ṇ ṇ Ṉ ṉ Ṋ ṋ Ṍ ṍ Ṏ ṏ Ṑ ṑ Ṓ ṓ Ṕ ṕ Ṗ ṗ Ṙ ṙ Ṛ ṛ Ṝ ṝ Ṟ ṟ Ṡ ṡ Ṣ ṣ Ṥ ṥ Ṧ ṧ Ṩ ṩ Ṫ ṫ Ṭ ṭ Ṯ ṯ Ṱ ṱ Ṳ ṳ Ṵ ṵ Ṷ ṷ Ṹ ṹ Ṻ ṻ Ṽ ṽ Ṿ ṿ ...
Greek Extended
ἀ ἁ ἂ ἃ ἄ ἅ ἆ ἇ Ἀ Ἁ Ἂ Ἃ Ἄ Ἅ Ἆ Ἇ ἐ ἑ ἒ ἓ ἔ ἕ Ἐ Ἑ Ἒ Ἓ Ἔ Ἕ ἠ ἡ ἢ ἣ ἤ ἥ ἦ ἧ Ἠ Ἡ Ἢ Ἣ Ἤ Ἥ Ἦ Ἧ ἰ ἱ ἲ ἳ ἴ ἵ ἶ ἷ Ἰ Ἱ Ἲ Ἳ Ἴ Ἵ Ἶ Ἷ ὀ ὁ ὂ ὃ ὄ ὅ Ὀ Ὁ Ὂ Ὃ Ὄ Ὅ ὐ ὑ ὒ ὓ ὔ ὕ ὖ ὗ Ὑ Ὓ Ὕ Ὗ ὠ ὡ ὢ ὣ ὤ ὥ ὦ ὧ Ὠ Ὡ Ὢ Ὣ Ὤ Ὥ Ὦ Ὧ ὰ ά ὲ έ ὴ ή ὶ ί ὸ ό ὺ ύ ὼ ώ ᾀ ᾁ ᾂ ᾃ ᾄ ᾅ ᾆ ᾇ ᾈ ᾉ ᾊ ᾋ ᾌ ᾍ ...
General Punctuation
  — ― ‖ ‗ “ ” „ ‟ † ‡ • ‣ ‥ … ‧ ‰ ‱ ″ ‴ ‶ ‷ ‸ ※ ‼ ‽ ‾ ‿ ⁀ ⁅ ⁆
Superscripts and Subscripts
⁰ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎
Currency Symbols
₠ ₡ ₢ ₣ ₤ ₥ ₦ ₧ ₨ ₩ ₪ ₫
Combining Marks for Symbols
⃐ ⃑ ⃒ ⃓ ⃔ ⃕ ⃖ ⃗ ⃘ ⃙ ⃚ ⃛ ⃜ ⃝ ⃞ ⃟ ⃠ ⃡
Letterlike Symbols
℀ ℁ ℃ ℄ ℅ ℆ ℇ ℈ ℉ № ℗ ℘ ℞ ℟ ℠ ℡ ™ ℣ ℥ Ω ℧ ℵ ℶ ℷ ℸ
Number Forms
⅓ ⅔ ⅕ ⅖ ⅗ ⅘ ⅙ ⅚ ⅛ ⅜ ⅝ ⅞ ⅟ Ⅱ Ⅲ Ⅳ Ⅵ Ⅶ Ⅷ Ⅸ Ⅺ Ⅻ ⅱ ⅲ ⅳ ⅵ ⅶ ⅷ ⅸ ⅺ ⅻ ⅿ ↀ ↁ ↂ
Arrows
← ↑ → ↓ ↔ ↕ ↖ ↗ ↘ ↙ ↚ ↛ ↜ ↝ ↞ ↟ ↠ ↡ ↢ ↣ ↤ ↥ ↦ ↧ ↨ ↩ ↪ ↫ ↬ ↭ ↮ ↯ ↰ ↱ ↲ ↳ ↴ ↵ ↶ ↷ ↸ ↹ ↺ ↻ ↼ ↽ ↾ ↿ ⇀ ⇁ ⇂ ⇃ ⇄ ⇅ ⇆ ⇇ ⇈ ⇉ ⇊ ⇋ ⇌ ⇍ ⇎ ⇏ ⇐ ⇑ ⇒ ⇓ ⇔ ⇕ ⇖ ⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟ ⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪
Mathematical Operators
∀ ∁ ∂ ∃ ∄ ∅ ∆ ∇ ∈ ∉ ∊ ∋ ∌ ∍ ∎ ∏ ∐ ∑ ∓ ∔ ∘ ∙ √ ∛ ∜ ∝ ∞ ∟ ∠ ∡ ∢ ∤ ∥ ∦ ∧ ∫ ∬ ∭ ∮ ∯ ∰ ∱ ∲ ∳ ∴ ∵ ∷ ∸ ∹ ∺ ∻ ∽ ∾ ∿ ≀ ≁ ≂ ≃ ≄ ≅ ≆ ≇ ≈ ≉ ≊ ≋ ≌ ≍ ≎ ≏ ≐ ≑ ≒ ≓ ≔ ≕ ≖ ≗ ≘ ≙ ≚ ≛ ≜ ≝ ≞ ≟ ≠ ≡ ≢ ≣ ≤ ≥ ≦ ≧ ≨ ≩ ≪ ≫ ≬ ≭ ≮ ≯ ≰ ≱ ≲ ≳ ≴ ≵ ≶ ≷ ≸ ≹ ≺ ≻ ≼ ≽ ≾ ≿ ...
Miscellaneous Technical
⌀ ⌂ ⌃ ⌄ ⌅ ⌆ ⌇ ⌈ ⌉ ⌊ ⌋ ⌌ ⌍ ⌎ ⌏ ⌐ ⌑ ⌒ ⌓ ⌔ ⌕ ⌖ ⌗ ⌘ ⌙ ⌚ ⌛ ⌜ ⌝ ⌞ ⌟ ⌠ ⌡ ⌢ ⌣ ⌤ ⌥ ⌦ ⌧ ⌨ 〈 〉 ⌫ ⌬ ⌭ ⌮ ⌯ ⌰ ⌱ ⌲ ⌳ ⌴ ⌵ ⌶ ⌷ ⌸ ⌹ ⌺ ⌻ ⌼ ⌽ ⌾ ⌿ ⍀ ⍁ ⍂ ⍃ ⍄ ⍅ ⍆ ⍇ ⍈ ⍉ ⍊ ⍋ ⍌ ⍍ ⍎ ⍏ ⍐ ⍑ ⍒ ⍓ ⍔ ⍕ ⍖ ⍗ ⍘ ⍙ ⍚ ⍛ ⍜ ⍝ ⍞ ⍟ ⍠ ⍡ ⍢ ⍣ ⍤ ⍥ ⍦ ⍧ ⍨ ⍩ ⍪ ⍫ ⍬ ⍭ ⍮ ⍯ ⍰ ⍱ ⍲ ⍵ ⍶ ⍷ ⍸ ⍹
Control Pictures
␀ ␁ ␂ ␃ ␄ ␅ ␆ ␇ ␈ ␉ ␊ ␋ ␌ ␍ ␎ ␏ ␐ ␑ ␒ ␓ ␔ ␕ ␖ ␗ ␘ ␙ ␚ ␛ ␜ ␝ ␞ ␟ ␠ ␡ ␢ ␣ ␤
Optical Character Recognition
⑀ ⑁ ⑂ ⑃ ⑄ ⑅ ⑆ ⑇ ⑈ ⑉ ⑊
Enclosed Alphanumerics
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ...
Box Drawing
─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏ ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟ ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯ ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿ ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏ ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟ ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯ ╰ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿
Block Elements
▀ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▉ ▊ ▋ ▌ ▍ ▎ ▏ ▐ ░ ▒ ▓ ▔ ▕
Geometric Shapes
■ □ ▢ ▣ ▤ ▥ ▦ ▧ ▨ ▩ ▪ ▫ ▬ ▭ ▮ ▯ ▰ ▱ ▲ △ ▴ ▵ ▶ ▷ ▸ ▹ ► ▻ ▼ ▽ ▾ ▿ ◀ ◁ ◂ ◃ ◄ ◅ ◆ ◇ ◈ ◉ ◊ ○ ◌ ◍ ◎ ● ◐ ◑ ◒ ◓ ◔ ◕ ◖ ◗ ◘ ◙ ◚ ◛ ◜ ◝ ◞ ◟ ◠ ◡ ◢ ◣ ◤ ◥ ◦ ◧ ◨ ◩ ◪ ◫ ◬ ◭ ◮ ◯
Miscellaneous Symbols
☀ ☁ ☂ ☃ ☄ ★ ☆ ☇ ☈ ☉ ☊ ☋ ☌ ☍ ☎ ☏ ☐ ☑ ☒ ☓ ☚ ☛ ☜ ☝ ☞ ☟ ☠ ☡ ☢ ☣ ☤ ☥ ☦ ☧ ☨ ☩ ☪ ☫ ☬ ☭ ☮ ☯ ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ ☸ ☹ ☺ ☻ ☼ ☽ ☾ ☿ ♀ ♁ ♂ ♃ ♄ ♅ ♆ ♇ ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ ♔ ♕ ♖ ♗ ♘ ♙ ♚ ♛ ♜ ♝ ♞ ♟ ♠ ♡ ♢ ♣ ♤ ♥ ♦ ♧ ♨ ♩ ♪ ♫ ♬ ♭ ♮ ♯
Dingbats
✁ ✂ ✃ ✄ ✆ ✇ ✈ ✉ ✌ ✍ ✎ ✏ ✐ ✑ ✒ ✓ ✔ ✕ ✖ ✗ ✘ ✙ ✚ ✛ ✜ ✝ ✞ ✟ ✠ ✡ ✢ ✣ ✤ ✥ ✦ ✧ ✩ ✪ ✫ ✬ ✭ ✮ ✯ ✰ ✱ ✲ ✳ ✴ ✵ ✶ ✷ ✸ ✹ ✺ ✻ ✼ ✽ ✾ ✿ ❀ ❁ ❂ ❃ ❄ ❅ ❆ ❇ ❈ ❉ ❊ ❋ ❍ ❏ ❐ ❑ ❒ ❖ ❘ ❙ ❚ ❛ ❜ ❝ ❞ ❡ ❢ ❣ ❤ ❥ ❦ ❧ ❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿ ➀ ➁ ➂ ➃ ➄ ➅ ➆ ➇ ➈ ➉ ➊ ➋ ➌ ➍ ➎ ➏ ➐ ➑ ➒ ➓ ➔ ➘ ➙ ➚ ➛ ➜ ➝ ...
CJK Symbols and Punctuation
  、 。 〃 〄 々 〆 〈 〉 《 》 「 」 『 』 【 】 〒 〓 〖 〗 〘 〙 〚 〛 〜 〝 〞 〟 〠 〡 〢 〣 〤 〥 〦 〧 〨 〩 〪 〫 〬 〭 〮 〯 〰 〱 〲 〴 〵 〶 〷 〿
Hiragana
ぁ あ ぃ い ぅ う ぇ え ぉ お か が き ぎ く ぐ け げ こ ご さ ざ し じ す ず せ ぜ そ ぞ た だ ち ぢ っ つ づ て で と ど な に ぬ ね の は ば ぱ ひ び ぴ ふ ぶ ぷ へ べ ぺ ほ ぼ ぽ ま み む め も ゃ や ゅ ゆ ょ よ ら り る れ ろ ゎ わ ゐ ゑ を ん ゔ ゙ ゚ ゛ ゜ ゝ ゞ
Katakana
ァ ア ィ イ ゥ ウ ェ エ ォ オ カ ガ キ ギ ク グ ケ ゲ コ ゴ サ ザ シ ジ ス ズ セ ゼ ソ ゾ タ ダ チ ヂ ッ ツ ヅ テ デ ト ド ナ ニ ヌ ネ ハ バ パ ヒ ビ ピ フ ブ プ ヘ ベ ペ ホ ボ ポ マ ミ ム メ モ ャ ヤ ュ ユ ョ ヨ ラ リ ル レ ロ ヮ ワ ヰ ヱ ヲ ン ヴ ヵ ヶ ヷ ヸ ヹ ヺ ・ ー ヽ ヾ
Bopomofo
ㄅ ㄆ ㄇ ㄈ ㄉ ㄊ ㄋ ㄌ ㄍ ㄎ ㄏ ㄐ ㄑ ㄒ ㄓ ㄔ ㄕ ㄖ ㄗ ㄘ ㄙ ㄚ ㄛ ㄜ ㄝ ㄞ ㄟ ㄠ ㄡ ㄢ ㄣ ㄤ ㄥ ㄦ ㄧ ㄨ ㄩ ㄪ ㄫ ㄬ
Hangul Compatibility Jamo
ㄱ ㄲ ㄳ ㄴ ㄵ ㄶ ㄷ ㄸ ㄹ ㄺ ㄻ ㄼ ㄽ ㄾ ㄿ ㅀ ㅁ ㅂ ㅃ ㅄ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ ㅏ ㅐ ㅑ ㅒ ㅓ ㅔ ㅕ ㅖ ㅗ ㅘ ㅙ ㅚ ㅛ ㅜ ㅝ ㅞ ㅟ ㅠ ㅡ ㅢ ㅣ ㅥ ㅦ ㅧ ㅨ ㅩ ㅪ ㅫ ㅬ ㅭ ㅮ ㅯ ㅰ ㅱ ㅲ ㅳ ㅴ ㅵ ㅶ ㅷ ㅸ ㅹ ㅺ ㅻ ㅼ ㅽ ㅾ ㅿ ㆀ ㆁ ㆂ ㆃ ㆄ ㆅ ㆆ ㆇ ㆈ ㆉ ㆊ ㆋ ㆌ ㆍ ㆎ
Kanbun
㆐ ㆑ ㆒ ㆓ ㆔ ㆕ ㆖ ㆗ ㆘ ㆙ ㆚ ㆛ ㆜ ㆝ ㆞ ㆟
Enclosed CJK Letters and Months
㈀ ㈁ ㈂ ㈃ ㈄ ㈅ ㈆ ㈇ ㈈ ㈉ ㈊ ㈋ ㈌ ㈍ ㈎ ㈏ ㈐ ㈑ ㈒ ㈓ ㈔ ㈕ ㈖ ㈗ ㈘ ㈙ ㈚ ㈛ ㈜ ㈠ ㈡ ㈢ ㈣ ㈤ ㈥ ㈦ ㈧ ㈨ ㈩ ㈪ ㈫ ㈬ ㈭ ㈮ ㈯ ㈰ ㈱ ㈲ ㈳ ㈴ ㈵ ㈶ ㈷ ㈸ ㈹ ㈺ ㈻ ㈼ ㈽ ㈾ ㈿ ㉀ ㉁ ㉂ ㉃ ㉠ ㉡ ㉢ ㉣ ㉤ ㉥ ㉦ ㉧ ㉨ ㉩ ㉪ ㉫ ㉬ ㉭ ㉮ ㉯ ㉰ ㉱ ㉲ ㉳ ㉴ ㉵ ㉶ ㉷ ㉸ ㉹ ㉺ ㉻ ㉿ ㊀ ㊁ ㊂ ㊃ ㊄ ㊅ ㊆ ㊇ ㊈ ㊉ ㊊ ㊋ ㊌ ㊍ ㊎ ㊏ ㊐ ㊑ ㊒ ㊓ ㊔ ㊕ ㊖ ㊗ ㊘ ㊙ ㊚ ㊛ ㊜ ㊝ ㊞ ㊟ ㊠ ㊡ ...
CJK Compatibility
㌀ ㌁ ㌂ ㌃ ㌄ ㌅ ㌆ ㌇ ㌈ ㌉ ㌊ ㌋ ㌌ ㌍ ㌎ ㌏ ㌐ ㌑ ㌒ ㌓ ㌔ ㌕ ㌖ ㌗ ㌘ ㌙ ㌚ ㌛ ㌜ ㌝ ㌞ ㌟ ㌠ ㌡ ㌢ ㌣ ㌤ ㌥ ㌦ ㌧ ㌨ ㌩ ㌪ ㌫ ㌬ ㌭ ㌮ ㌯ ㌰ ㌱ ㌲ ㌳ ㌴ ㌵ ㌶ ㌷ ㌸ ㌹ ㌺ ㌻ ㌼ ㌽ ㌾ ㌿ ㍀ ㍁ ㍂ ㍃ ㍄ ㍅ ㍆ ㍇ ㍈ ㍉ ㍊ ㍋ ㍌ ㍍ ㍎ ㍏ ㍐ ㍑ ㍒ ㍓ ㍔ ㍕ ㍖ ㍗ ㍘ ㍙ ㍚ ㍛ ㍜ ㍝ ㍞ ㍟ ㍠ ㍡ ㍢ ㍣ ㍤ ㍥ ㍦ ㍧ ㍨ ㍩ ㍪ ㍫ ㍬ ㍭ ㍮ ㍯ ㍰ ㍱ ㍲ ㍳ ㍴ ㍵ ㍶ ㍻ ㍼ ㍽ ㍾ ㍿ ㎀ ㎁ ㎂ ㎃ ...
CJK Unified Ideographs
一 丁 丂 七 丄 丅 丆 万 丈 三 上 下 丌 不 与 丏 丐 丑 丒 专 且 丕 世 丗 丘 丙 业 丛 东 丝 丞 丟 丠 両 丢 丣 两 严 並 丧 丨 丩 个 丫 丬 中 丮 丯 丰 丱 串 丳 临 丵 丷 丸 丹 为 主 丼 丽 举 丿 乀 乁 乂 乃 乄 久 乆 乇 么 义 乊 之 乌 乍 乎 乏 乐 乑 乒 乓 乔 乕 乖 乗 乘 乙 乚 乛 乜 九 乞 也 习 乡 乢 乣 乤 乥 书 乧 乨 乩 乪 乫 乬 乭 乮 乯 买 乱 乲 乳 乴 乵 乶 乷 乸 乹 乺 乻 乼 乽 乾 乿 ...
Hangul Syllables
가 각 갂 갃 간 갅 갆 갇 갈 갉 갊 갋 갌 갍 갎 갏 감 갑 값 갓 갔 강 갖 갗 갘 같 갚 갛 개 객 갞 갟 갠 갡 갢 갣 갤 갥 갦 갧 갨 갩 갪 갫 갬 갭 갮 갯 갰 갱 갲 갳 갴 갵 갶 갷 갸 갹 갺 갻 갼 갽 갾 갿 걀 걁 걂 걃 걄 걅 걆 걇 걈 걉 걊 걋 걌 걍 걎 걏 걐 걑 걒 걓 걔 걕 걖 걗 걘 걙 걚 걛 걜 걝 걞 걟 걠 걡 걢 걣 걤 걥 걦 걧 걨 걩 걪 걫 걬 걭 걮 걯 거 걱 걲 걳 건 걵 걶 걷 걸 걹 걺 걻 걼 걽 걾 걿 ...
Private Use
                                                                                                                                ...
CJK Compatibility Ideographs
豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ...
Alphabetic Presentation Forms
ff fi fl ffi ffl ſt st ﬓ ﬔ ﬕ ﬖ ﬗ ﬞ ײַ ﬠ ﬡ ﬢ ﬣ ﬤ ﬥ ﬦ ﬧ ﬨ ﬩ שׁ שׂ שּׁ שּׂ אַ אָ אּ בּ גּ דּ הּ וּ זּ טּ יּ ךּ כּ לּ מּ נּ סּ ףּ פּ צּ קּ רּ שּ תּ וֹ בֿ כֿ פֿ ﭏ
Arabic Presentation Forms-A
ﭐ ﭑ ﭒ ﭓ ﭔ ﭕ ﭖ ﭗ ﭘ ﭙ ﭚ ﭛ ﭜ ﭝ ﭞ ﭟ ﭠ ﭡ ﭢ ﭣ ﭤ ﭥ ﭦ ﭧ ﭨ ﭩ ﭪ ﭫ ﭬ ﭭ ﭮ ﭯ ﭰ ﭱ ﭲ ﭳ ﭴ ﭵ ﭶ ﭷ ﭸ ﭹ ﭺ ﭻ ﭼ ﭽ ﭾ ﭿ ﮀ ﮁ ﮂ ﮃ ﮄ ﮅ ﮆ ﮇ ﮈ ﮉ ﮊ ﮋ ﮌ ﮍ ﮎ ﮏ ﮐ ﮑ ﮒ ﮓ ﮔ ﮕ ﮖ ﮗ ﮘ ﮙ ﮚ ﮛ ﮜ ﮝ ﮞ ﮟ ﮠ ﮡ ﮢ ﮣ ﮤ ﮥ ﮮ ﮯ ﮰ ﮱ ﯓ ﯔ ﯕ ﯖ ﯗ ﯘ ﯙ ﯚ ﯛ ﯜ ﯝ ﯞ ﯟ ﯠ ﯡ ﯢ ﯣ ﯤ ﯥ ﯦ ﯧ ﯨ ﯩ ﯪ ﯫ ﯬ ﯭ ﯮ ﯯ ﯰ ...
Combining Half Marks
︠ ︡ ︢ ︣
CJK Compatibility Forms
︱ ︲ ︳ ︴ ︵ ︶ ︷ ︸ ︹ ︺ ︻ ︼ ︽ ︾ ︿ ﹀ ﹁ ﹂ ﹃ ﹄ ﹉ ﹊ ﹋ ﹌
Small Form Variants
﹐ ﹑ ﹒ ﹔ ﹕ ﹖ ﹗ ﹙ ﹚ ﹛ ﹜ ﹝ ﹞ ﹟ ﹠ ﹡ ﹢ ﹣ ﹤ ﹥ ﹦ ﹩ ﹪ ﹫
Arabic Presentation Forms-B
ﹰ ﹱ ﹲ ﹴ ﹶ ﹷ ﹸ ﹹ ﹺ ﹻ ﹼ ﹽ ﹾ ﹿ ﺀ ﺁ ﺂ ﺃ ﺄ ﺅ ﺆ ﺇ ﺈ ﺉ ﺊ ﺋ ﺌ ﺏ ﺐ ﺑ ﺒ ﺓ ﺔ ﺕ ﺖ ﺗ ﺘ ﺙ ﺚ ﺛ ﺜ ﺝ ﺞ ﺟ ﺠ ﺡ ﺢ ﺣ ﺤ ﺥ ﺦ ﺧ ﺨ ﺩ ﺪ ﺫ ﺬ ﺭ ﺮ ﺯ ﺰ ﺱ ﺲ ﺳ ﺴ ﺵ ﺶ ﺷ ﺸ ﺹ ﺺ ﺻ ﺼ ﺽ ﺾ ﺿ ﻀ ﻁ ﻂ ﻃ ﻄ ﻅ ﻆ ﻇ ﻈ ﻉ ﻊ ﻋ ﻌ ﻍ ﻎ ﻏ ﻐ ﻑ ﻒ ﻓ ﻔ ﻕ ﻖ ﻗ ﻘ ﻙ ﻚ ﻛ ﻜ ﻝ ﻞ ﻟ ﻠ ﻡ ﻢ ﻣ ﻤ ﻥ ﻦ ﻧ ﻨ ﻭ ﻮ ﻯ ﻰ ﻱ ...
Halfwidth and Fullwidth Forms
_ 。 「 」 、 ・ ヲ ァ ィ ゥ ェ ォ ャ ュ ョ ッ ー ア イ ウ エ オ カ キ ク ケ コ サ シ ス セ ソ タ チ ツ ...
Specials

Specials
<20>

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests
import junit.framework.TestCase
import com.kunzisoft.keepass.database.element.PwDate
import org.junit.Assert
class PwDateTest : TestCase() {
fun testDate() {
val jDate = PwDate(System.currentTimeMillis())
val intermediate = PwDate(jDate)
val cDate = PwDate(intermediate.byteArrayDate!!, 0)
Assert.assertTrue("jDate and intermediate not equal", jDate == intermediate)
Assert.assertTrue("jDate and cDate not equal", cDate == jDate)
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests.crypto
import com.kunzisoft.keepass.crypto.CipherFactory
import junit.framework.TestCase
import java.security.InvalidAlgorithmParameterException
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import java.util.Random
import javax.crypto.BadPaddingException
import javax.crypto.Cipher
import javax.crypto.IllegalBlockSizeException
import javax.crypto.NoSuchPaddingException
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import org.junit.Assert.assertArrayEquals
class AESTest : TestCase() {
private val mRand = Random()
@Throws(InvalidKeyException::class, NoSuchAlgorithmException::class, NoSuchPaddingException::class, IllegalBlockSizeException::class, BadPaddingException::class, InvalidAlgorithmParameterException::class)
fun testEncrypt() {
// Test above below and at the blocksize
testFinal(15)
testFinal(16)
testFinal(17)
// Test random larger sizes
val size = mRand.nextInt(494) + 18
testFinal(size)
}
@Throws(NoSuchAlgorithmException::class, NoSuchPaddingException::class, IllegalBlockSizeException::class, BadPaddingException::class, InvalidKeyException::class, InvalidAlgorithmParameterException::class)
private fun testFinal(dataSize: Int) {
// Generate some input
val input = ByteArray(dataSize)
mRand.nextBytes(input)
// Generate key
val keyArray = ByteArray(32)
mRand.nextBytes(keyArray)
val key = SecretKeySpec(keyArray, "AES")
// Generate IV
val ivArray = ByteArray(16)
mRand.nextBytes(ivArray)
val iv = IvParameterSpec(ivArray)
val android = CipherFactory.getInstance("AES/CBC/PKCS5Padding", true)
android.init(Cipher.ENCRYPT_MODE, key, iv)
val outAndroid = android.doFinal(input, 0, dataSize)
val nat = CipherFactory.getInstance("AES/CBC/PKCS5Padding")
nat.init(Cipher.ENCRYPT_MODE, key, iv)
val outNative = nat.doFinal(input, 0, dataSize)
assertArrayEquals("Arrays differ on size: $dataSize", outAndroid, outNative)
}
}

View File

@@ -1,63 +1,50 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
* Copyright 2021 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests.crypto
import com.kunzisoft.keepass.utils.readBytesLength
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
import org.junit.Assert.assertArrayEquals
import org.junit.Test
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.security.InvalidAlgorithmParameterException
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import java.util.Random
import javax.crypto.BadPaddingException
import java.util.*
import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import javax.crypto.CipherOutputStream
import javax.crypto.IllegalBlockSizeException
import javax.crypto.NoSuchPaddingException
import junit.framework.TestCase
import com.kunzisoft.keepass.crypto.CipherFactory
import com.kunzisoft.keepass.crypto.engine.AesEngine
import com.kunzisoft.keepass.crypto.engine.CipherEngine
import com.kunzisoft.keepass.stream.BetterCipherInputStream
import com.kunzisoft.keepass.stream.LEDataInputStream
class CipherTest : TestCase() {
class EncryptionTest {
private val rand = Random()
@Throws(InvalidKeyException::class, NoSuchAlgorithmException::class, NoSuchPaddingException::class, InvalidAlgorithmParameterException::class, IllegalBlockSizeException::class, BadPaddingException::class)
@Test
fun testCipherFactory() {
val key = ByteArray(32)
rand.nextBytes(key)
val iv = ByteArray(16)
rand.nextBytes(iv)
val plaintext = ByteArray(1024)
rand.nextBytes(key)
rand.nextBytes(iv)
rand.nextBytes(plaintext)
val aes = CipherFactory.getInstance(AesEngine.CIPHER_UUID)
val aes = EncryptionAlgorithm.AESRijndael.cipherEngine
val encrypt = aes.getCipher(Cipher.ENCRYPT_MODE, key, iv)
val decrypt = aes.getCipher(Cipher.DECRYPT_MODE, key, iv)
@@ -67,20 +54,20 @@ class CipherTest : TestCase() {
assertArrayEquals("Encryption and decryption failed", plaintext, decrypttext)
}
@Throws(InvalidKeyException::class, NoSuchAlgorithmException::class, NoSuchPaddingException::class, InvalidAlgorithmParameterException::class, IllegalBlockSizeException::class, BadPaddingException::class, IOException::class)
@Test
fun testCipherStreams() {
val MESSAGE_LENGTH = 1024
val length = 1024
val key = ByteArray(32)
val iv = ByteArray(16)
val plaintext = ByteArray(MESSAGE_LENGTH)
rand.nextBytes(key)
val iv = ByteArray(16)
rand.nextBytes(iv)
val plaintext = ByteArray(length)
rand.nextBytes(plaintext)
val aes = CipherFactory.getInstance(AesEngine.CIPHER_UUID)
val aes = EncryptionAlgorithm.AESRijndael.cipherEngine
val encrypt = aes.getCipher(Cipher.ENCRYPT_MODE, key, iv)
val decrypt = aes.getCipher(Cipher.DECRYPT_MODE, key, iv)
@@ -92,10 +79,9 @@ class CipherTest : TestCase() {
val secrettext = bos.toByteArray()
val bis = ByteArrayInputStream(secrettext)
val cis = BetterCipherInputStream(bis, decrypt)
val lis = LEDataInputStream(cis)
val cis = CipherInputStream(bis, decrypt)
val decrypttext = lis.readBytes(MESSAGE_LENGTH)
val decrypttext = cis.readBytesLength(length)
assertArrayEquals("Encryption and decryption failed", plaintext, decrypttext)
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests.crypto
import org.junit.Assert.assertArrayEquals
import java.io.IOException
import java.util.Random
import junit.framework.TestCase
import com.kunzisoft.keepass.crypto.finalkey.AndroidFinalKey
import com.kunzisoft.keepass.crypto.finalkey.NativeFinalKey
class FinalKeyTest : TestCase() {
private var mRand: Random? = null
@Throws(Exception::class)
override fun setUp() {
super.setUp()
mRand = Random()
}
@Throws(IOException::class)
fun testNativeAndroid() {
// Test both an old and an even number to test my flip variable
testNativeFinalKey(5)
testNativeFinalKey(6)
}
@Throws(IOException::class)
private fun testNativeFinalKey(rounds: Int) {
val seed = ByteArray(32)
val key = ByteArray(32)
val nativeKey: ByteArray
val androidKey: ByteArray
mRand!!.nextBytes(seed)
mRand!!.nextBytes(key)
val aKey = AndroidFinalKey()
androidKey = aKey.transformMasterKey(seed, key, rounds.toLong())
val nKey = NativeFinalKey()
nativeKey = nKey.transformMasterKey(seed, key, rounds.toLong())
assertArrayEquals("Does not match", androidKey, nativeKey)
}
}

View File

@@ -0,0 +1,176 @@
package com.kunzisoft.keepass.tests.stream
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import com.kunzisoft.keepass.utils.readAllBytes
import com.kunzisoft.keepass.database.element.binary.BinaryCache
import com.kunzisoft.keepass.database.element.binary.BinaryFile
import com.kunzisoft.keepass.utils.UriUtil
import junit.framework.TestCase.assertEquals
import org.junit.Test
import java.io.DataInputStream
import java.io.File
import java.io.InputStream
import kotlin.random.Random
class BinaryDataTest {
private val context: Context by lazy {
InstrumentationRegistry.getInstrumentation().context
}
private val cacheDirectory = UriUtil.getBinaryDir(InstrumentationRegistry.getInstrumentation().targetContext)
private val fileA = File(cacheDirectory, TEST_FILE_CACHE_A)
private val fileB = File(cacheDirectory, TEST_FILE_CACHE_B)
private val fileC = File(cacheDirectory, TEST_FILE_CACHE_C)
private val binaryCache = BinaryCache()
private fun saveBinary(asset: String, binaryData: BinaryFile) {
context.assets.open(asset).use { assetInputStream ->
binaryData.getOutputDataStream(binaryCache).use { binaryOutputStream ->
assetInputStream.readAllBytes(DEFAULT_BUFFER_SIZE) { buffer ->
binaryOutputStream.write(buffer)
}
}
}
}
@Test
fun testSaveTextInCache() {
val binaryA = BinaryFile(fileA)
val binaryB = BinaryFile(fileB)
saveBinary(TEST_TEXT_ASSET, binaryA)
saveBinary(TEST_TEXT_ASSET, binaryB)
assertEquals("Save text binary length failed.", binaryA.getSize(), binaryB.getSize())
assertEquals("Save text binary MD5 failed.", binaryA.binaryHash(), binaryB.binaryHash())
}
@Test
fun testSaveImageInCache() {
val binaryA = BinaryFile(fileA)
val binaryB = BinaryFile(fileB)
saveBinary(TEST_IMAGE_ASSET, binaryA)
saveBinary(TEST_IMAGE_ASSET, binaryB)
assertEquals("Save image binary length failed.", binaryA.getSize(), binaryB.getSize())
assertEquals("Save image binary failed.", binaryA.binaryHash(), binaryB.binaryHash())
}
@Test
fun testCompressText() {
val binaryA = BinaryFile(fileA)
val binaryB = BinaryFile(fileB)
val binaryC = BinaryFile(fileC)
saveBinary(TEST_TEXT_ASSET, binaryA)
saveBinary(TEST_TEXT_ASSET, binaryB)
saveBinary(TEST_TEXT_ASSET, binaryC)
binaryA.compress(binaryCache)
binaryB.compress(binaryCache)
assertEquals("Compress text length failed.", binaryA.getSize(), binaryB.getSize())
assertEquals("Compress text MD5 failed.", binaryA.binaryHash(), binaryB.binaryHash())
binaryB.decompress(binaryCache)
assertEquals("Decompress text length failed.", binaryB.getSize(), binaryC.getSize())
assertEquals("Decompress text MD5 failed.", binaryB.binaryHash(), binaryC.binaryHash())
}
@Test
fun testCompressImage() {
val binaryA = BinaryFile(fileA)
var binaryB = BinaryFile(fileB)
val binaryC = BinaryFile(fileC)
saveBinary(TEST_IMAGE_ASSET, binaryA)
saveBinary(TEST_IMAGE_ASSET, binaryB)
saveBinary(TEST_IMAGE_ASSET, binaryC)
binaryA.compress(binaryCache)
binaryB.compress(binaryCache)
assertEquals("Compress image length failed.", binaryA.getSize(), binaryA.getSize())
assertEquals("Compress image failed.", binaryA.binaryHash(), binaryA.binaryHash())
binaryB = BinaryFile(fileB, true)
binaryB.decompress(binaryCache)
assertEquals("Decompress image length failed.", binaryB.getSize(), binaryC.getSize())
assertEquals("Decompress image failed.", binaryB.binaryHash(), binaryC.binaryHash())
}
@Test
fun testCompressBytes() {
// Test random byte array
val byteArray = ByteArray(50)
Random.nextBytes(byteArray)
testCompressBytes(byteArray)
// Test empty byte array
testCompressBytes(ByteArray(0))
}
private fun testCompressBytes(byteArray: ByteArray) {
val binaryA = binaryCache.getBinaryData("0", true)
binaryA.getOutputDataStream(binaryCache).use { outputStream ->
outputStream.write(byteArray)
}
val binaryB = binaryCache.getBinaryData("1", true)
binaryB.getOutputDataStream(binaryCache).use { outputStream ->
outputStream.write(byteArray)
}
val binaryC = binaryCache.getBinaryData("2", true)
binaryC.getOutputDataStream(binaryCache).use { outputStream ->
outputStream.write(byteArray)
}
binaryA.compress(binaryCache)
binaryB.compress(binaryCache)
assertEquals("Compress bytes decompressed failed.", binaryA.isCompressed, true)
assertEquals("Compress bytes length failed.", binaryA.getSize(), binaryA.getSize())
assertEquals("Compress bytes failed.", binaryA.binaryHash(), binaryA.binaryHash())
binaryB.decompress(binaryCache)
assertEquals("Decompress bytes decompressed failed.", binaryB.isCompressed, false)
assertEquals("Decompress bytes length failed.", binaryB.getSize(), binaryC.getSize())
assertEquals("Decompress bytes failed.", binaryB.binaryHash(), binaryC.binaryHash())
}
@Test
fun testReadText() {
val binaryA = BinaryFile(fileA)
saveBinary(TEST_TEXT_ASSET, binaryA)
assert(streamAreEquals(context.assets.open(TEST_TEXT_ASSET),
binaryA.getInputDataStream(binaryCache)))
}
@Test
fun testReadImage() {
val binaryA = BinaryFile(fileA)
saveBinary(TEST_IMAGE_ASSET, binaryA)
assert(streamAreEquals(context.assets.open(TEST_IMAGE_ASSET),
binaryA.getInputDataStream(binaryCache)))
}
private fun streamAreEquals(inputStreamA: InputStream,
inputStreamB: InputStream): Boolean {
val bufferA = ByteArray(DEFAULT_BUFFER_SIZE)
val bufferB = ByteArray(DEFAULT_BUFFER_SIZE)
val dataInputStreamB = DataInputStream(inputStreamB)
try {
var len: Int
while (inputStreamA.read(bufferA).also { len = it } > 0) {
dataInputStreamB.readFully(bufferB, 0, len)
for (i in 0 until len) {
if (bufferA[i] != bufferB[i])
return false
}
}
return inputStreamB.read() < 0 // is the end of the second file also.
} catch (e: Exception) {
return false
}
finally {
inputStreamA.close()
inputStreamB.close()
}
}
companion object {
private const val TEST_FILE_CACHE_A = "testA"
private const val TEST_FILE_CACHE_B = "testB"
private const val TEST_FILE_CACHE_C = "testC"
private const val TEST_IMAGE_ASSET = "test_image.png"
private const val TEST_TEXT_ASSET = "test_text.txt"
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests.stream
@@ -33,7 +33,7 @@ import junit.framework.TestCase
import com.kunzisoft.keepass.stream.HashedBlockInputStream
import com.kunzisoft.keepass.stream.HashedBlockOutputStream
class HashedBlock : TestCase() {
class HashedBlockTest : TestCase() {
@Throws(IOException::class)
fun testBlockAligned() {

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests.utils
import java.util.Locale
import com.kunzisoft.keepass.utils.StringUtil
import junit.framework.TestCase
class StringUtilTest : TestCase() {
private val text = "AbCdEfGhIj"
private val search = "BcDe"
private val badSearch = "Ed"
private val repText = "AbCtestingaBc"
private val repSearch = "ABc"
private val repSearchBad = "CCCCCC"
private val repNew = "12345"
private val repResult = "12345testing12345"
fun testIndexOfIgnoreCase1() {
assertEquals(1, StringUtil.indexOfIgnoreCase(text, search, Locale.ENGLISH))
}
fun testIndexOfIgnoreCase2() {
assertEquals(-1f, StringUtil.indexOfIgnoreCase(text, search, Locale.ENGLISH).toFloat(), 2f)
}
fun testIndexOfIgnoreCase3() {
assertEquals(-1, StringUtil.indexOfIgnoreCase(text, badSearch, Locale.ENGLISH))
}
fun testReplaceAllIgnoresCase1() {
assertEquals(repResult, StringUtil.replaceAllIgnoresCase(repText, repSearch, repNew, Locale.ENGLISH))
}
fun testReplaceAllIgnoresCase2() {
assertEquals(repText, StringUtil.replaceAllIgnoresCase(repText, repSearchBad, repNew, Locale.ENGLISH))
}
}

View File

@@ -0,0 +1,15 @@
package com.kunzisoft.keepass.tests.utils
import com.kunzisoft.keepass.utils.UuidUtil
import junit.framework.TestCase
import java.util.*
class UUIDTest: TestCase() {
fun testUUID() {
val randomUUID = UUID.randomUUID()
val hexStringUUID = UuidUtil.toHexString(randomUUID)
val retrievedUUID = UuidUtil.fromHexString(hexStringUUID)
assertEquals(randomUUID, retrievedUUID)
}
}

View File

@@ -0,0 +1,28 @@
package com.kunzisoft.keepass.tests.utils
import com.kunzisoft.keepass.utils.UnsignedInt
import junit.framework.TestCase
class UnsignedIntTest: TestCase() {
fun testUInt() {
val standardInt = UnsignedInt(15).toKotlinInt()
assertEquals(15, standardInt)
val unsignedInt = UnsignedInt(-1).toKotlinLong()
assertEquals(4294967295L, unsignedInt)
}
fun testMaxValue() {
val maxValue = UnsignedInt.MAX_VALUE.toKotlinLong()
assertEquals(4294967295L, maxValue)
val longValue = UnsignedInt.fromKotlinLong(4294967295L).toKotlinLong()
assertEquals(longValue, maxValue)
}
fun testLong() {
val longValue = UnsignedInt.fromKotlinLong(50L).toKotlinInt()
assertEquals(50, longValue)
val uIntLongValue = UnsignedInt.fromKotlinLong(4294967290).toKotlinLong()
assertEquals(4294967290, uIntLongValue)
}
}

View File

@@ -1,49 +1,43 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.tests
import org.junit.Assert.assertArrayEquals
import java.io.ByteArrayOutputStream
import java.util.Calendar
import java.util.Random
package com.kunzisoft.keepass.tests.utils
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.utils.*
import junit.framework.TestCase
import org.junit.Assert.assertArrayEquals
import java.io.ByteArrayOutputStream
import java.util.*
import com.kunzisoft.keepass.database.element.PwDate
import com.kunzisoft.keepass.stream.LEDataInputStream
import com.kunzisoft.keepass.stream.LEDataOutputStream
import com.kunzisoft.keepass.utils.Types
class TypesTest : TestCase() {
class ValuesTest : TestCase() {
fun testReadWriteLongZero() {
testReadWriteLong(0.toByte())
}
fun testReadWriteLongMax() {
testReadWriteLong(java.lang.Byte.MAX_VALUE)
testReadWriteLong(Byte.MAX_VALUE)
}
fun testReadWriteLongMin() {
testReadWriteLong(java.lang.Byte.MIN_VALUE)
testReadWriteLong(Byte.MIN_VALUE)
}
fun testReadWriteLongRnd() {
@@ -56,15 +50,9 @@ class TypesTest : TestCase() {
private fun testReadWriteLong(value: Byte) {
val orig = ByteArray(8)
val dest = ByteArray(8)
setArray(orig, value, 0, 8)
val one = LEDataInputStream.readLong(orig, 0)
LEDataOutputStream.writeLong(one, dest, 0)
assertArrayEquals(orig, dest)
setArray(orig, value, 8)
assertArrayEquals(orig, uLongTo8Bytes(bytes64ToULong(orig)))
}
fun testReadWriteIntZero() {
@@ -72,33 +60,30 @@ class TypesTest : TestCase() {
}
fun testReadWriteIntMin() {
testReadWriteInt(java.lang.Byte.MIN_VALUE)
testReadWriteInt(Byte.MIN_VALUE)
}
fun testReadWriteIntMax() {
testReadWriteInt(java.lang.Byte.MAX_VALUE)
testReadWriteInt(Byte.MAX_VALUE)
}
private fun testReadWriteInt(value: Byte) {
val orig = ByteArray(4)
val dest = ByteArray(4)
for (i in 0..3) {
orig[i] = 0
}
setArray(orig, value, 0, 4)
setArray(orig, value, 4)
val one = LEDataInputStream.readInt(orig, 0)
LEDataOutputStream.writeInt(one, dest, 0)
val one = bytes4ToUInt(orig)
val dest = uIntTo4Bytes(one)
assertArrayEquals(orig, dest)
}
private fun setArray(buf: ByteArray, value: Byte, offset: Int, size: Int) {
for (i in offset until offset + size) {
private fun setArray(buf: ByteArray, value: Byte, size: Int) {
for (i in 0 until size) {
buf[i] = value
}
}
@@ -109,32 +94,28 @@ class TypesTest : TestCase() {
orig[0] = 0
orig[1] = 1
val one = LEDataInputStream.readUShort(orig, 0)
val dest = LEDataOutputStream.writeUShortBuf(one)
val one = bytes2ToUShort(orig)
val dest = uShortTo2Bytes(one)
assertArrayEquals(orig, dest)
}
fun testReadWriteShortMin() {
testReadWriteShort(java.lang.Byte.MIN_VALUE)
testReadWriteShort(Byte.MIN_VALUE)
}
fun testReadWriteShortMax() {
testReadWriteShort(java.lang.Byte.MAX_VALUE)
testReadWriteShort(Byte.MAX_VALUE)
}
private fun testReadWriteShort(value: Byte) {
val orig = ByteArray(2)
val dest = ByteArray(2)
setArray(orig, value, 2)
setArray(orig, value, 0, 2)
val one = LEDataInputStream.readUShort(orig, 0)
LEDataOutputStream.writeUShort(one, dest, 0)
val one = bytes2ToUShort(orig)
val dest = uShortTo2Bytes(one)
assertArrayEquals(orig, dest)
}
fun testReadWriteByteZero() {
@@ -142,24 +123,16 @@ class TypesTest : TestCase() {
}
fun testReadWriteByteMin() {
testReadWriteByte(java.lang.Byte.MIN_VALUE)
testReadWriteByte(Byte.MIN_VALUE)
}
fun testReadWriteByteMax() {
testReadWriteShort(java.lang.Byte.MAX_VALUE)
testReadWriteShort(Byte.MAX_VALUE)
}
private fun testReadWriteByte(value: Byte) {
val orig = ByteArray(1)
val dest = ByteArray(1)
setArray(orig, value, 0, 1)
val one = Types.readUByte(orig, 0)
Types.writeUByte(one, dest, 0)
assertArrayEquals(orig, dest)
val dest: Byte = UnsignedInt(value.toInt() and 0xFF).toKotlinByte()
assert(value == dest)
}
fun testDate() {
@@ -168,27 +141,35 @@ class TypesTest : TestCase() {
val expected = Calendar.getInstance()
expected.set(2008, 1, 2, 3, 4, 5)
val buf = PwDate.writeTime(expected.time, cal)
val actual = Calendar.getInstance()
actual.time = PwDate.readTime(buf, 0, cal)
actual.time = DateInstant(bytes5ToDate(dateTo5Bytes(expected.time, cal), cal)).date
val jDate = DateInstant(System.currentTimeMillis())
val intermediate = DateInstant(jDate)
val cDate = DateInstant(bytes5ToDate(dateTo5Bytes(intermediate.date)))
assertEquals("Year mismatch: ", 2008, actual.get(Calendar.YEAR))
assertEquals("Month mismatch: ", 1, actual.get(Calendar.MONTH))
assertEquals("Day mismatch: ", 1, actual.get(Calendar.DAY_OF_MONTH))
assertEquals("Day mismatch: ", 2, actual.get(Calendar.DAY_OF_MONTH))
assertEquals("Hour mismatch: ", 3, actual.get(Calendar.HOUR_OF_DAY))
assertEquals("Minute mismatch: ", 4, actual.get(Calendar.MINUTE))
assertEquals("Second mismatch: ", 5, actual.get(Calendar.SECOND))
assertTrue("jDate and intermediate not equal", jDate == intermediate)
assertTrue("jDate $jDate and cDate $cDate not equal", cDate == jDate)
}
fun testUUID() {
val rnd = Random()
val bUUID = ByteArray(16)
rnd.nextBytes(bUUID)
Random().nextBytes(bUUID)
val uuid = Types.bytestoUUID(bUUID)
val eUUID = Types.UUIDtoBytes(uuid)
val uuid = bytes16ToUuid(bUUID)
val eUUID = uuidTo16Bytes(uuid)
val lUUID = bytes16ToUuid(bUUID)
val leUUID = uuidTo16Bytes(lUUID)
assertArrayEquals("UUID match failed", bUUID, eUUID)
assertArrayEquals("UUID match failed", bUUID, leUUID)
}
@Throws(Exception::class)
@@ -198,12 +179,10 @@ class TypesTest : TestCase() {
ulongBytes[i] = -1
}
val bos = ByteArrayOutputStream()
val leos = LEDataOutputStream(bos)
leos.writeLong(Types.ULONG_MAX_VALUE)
leos.close()
val uLongMax = bos.toByteArray()
val byteArrayOutputStream = ByteArrayOutputStream()
byteArrayOutputStream.write(UnsignedLong.MAX_BYTES)
byteArrayOutputStream.close()
val uLongMax = byteArrayOutputStream.toByteArray()
assertArrayEquals(ulongBytes, uLongMax)
}

View File

@@ -1,19 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="108"
android:viewportHeight="108"
android:width="108dp"
android:height="108dp">
xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="108"
android:viewportHeight="108"
android:width="108dp"
android:height="108dp">
<group
android:translateY="-332">
<group
android:translateY="332">
<path
android:pathData="M65.728516 32.791016L58.052734 35.904297 56.173828 48.380859 35.306641 69.267578 35.238281 73.759766 69.478516 108 108 108 108 70.810547 73.09375 35.904297 65.728516 32.791016Z"
android:fillColor="@color/long_shadow"
android:strokeLineJoin="round"
android:strokeLineCap="round"
android:strokeMiterLimit="4" />
android:strokeMiterLimit="4" >
<aapt:attr name="android:fillColor">
<gradient
android:endColor="#0000"
android:endX="80"
android:endY="80"
android:startColor="#4e000000"
android:startX="0"
android:startY="0"
android:type="linear"/>
</aapt:attr>
</path>
</group>
<group
android:scaleX="0.3939503"

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,19 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="108"
android:viewportHeight="108"
android:width="108dp"
android:height="108dp">
xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="108"
android:viewportHeight="108"
android:width="108dp"
android:height="108dp">
<group
android:translateY="-332">
<group
android:translateY="332">
<path
android:pathData="M65.728516 32.791016L58.052734 35.904297 56.173828 48.380859 35.306641 69.267578 35.238281 73.759766 69.478516 108 108 108 108 70.810547 73.09375 35.904297 65.728516 32.791016Z"
android:fillColor="@color/long_shadow"
android:strokeLineJoin="round"
android:strokeLineCap="round"
android:strokeMiterLimit="4" />
android:strokeMiterLimit="4" >
<aapt:attr name="android:fillColor">
<gradient
android:endColor="#0000"
android:endX="80"
android:endY="80"
android:startColor="#4e000000"
android:startX="0"
android:startY="0"
android:type="linear"/>
</aapt:attr>
</path>
</group>
<group
android:scaleX="0.3939503"

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.kunzisoft.keepass"
android:installLocation="auto">
<supports-screens
@@ -7,10 +8,21 @@
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission
android:name="android.permission.USE_BIOMETRIC" />
<uses-permission
android:name="android.permission.VIBRATE"/>
<!-- Write permission until Android 10 -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"
tools:ignore="ScopedStorage" />
<!-- Open apps from links -->
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<application
android:label="@string/app_name"
@@ -18,14 +30,15 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:name="com.kunzisoft.keepass.app.App"
android:allowBackup="true"
android:fullBackupContent="@xml/backup"
android:fullBackupContent="@xml/backup_rules"
android:backupAgent="com.kunzisoft.keepass.backup.SettingsBackupAgent"
android:theme="@style/KeepassDXStyle.Night">
<!-- TODO backup API Key -->
android:largeHeap="true"
android:resizeableActivity="true"
android:theme="@style/KeepassDXStyle.Night"
tools:targetApi="n">
<meta-data
android:name="com.google.android.backup.api_key"
android:value="" />
android:value="${googleAndroidBackupAPIKey}" />
<activity
android:name="com.kunzisoft.keepass.activities.FileDatabaseSelectActivity"
android:theme="@style/KeepassDXStyle.SplashScreen"
@@ -41,7 +54,7 @@
<activity
android:name="com.kunzisoft.keepass.activities.PasswordActivity"
android:configChanges="keyboardHidden"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize|stateUnchanged">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -116,37 +129,71 @@
<activity
android:name="com.kunzisoft.keepass.activities.EntryActivity"
android:configChanges="keyboardHidden" />
<activity
android:name="com.kunzisoft.keepass.activities.IconPickerActivity"
android:configChanges="keyboardHidden" />
<activity
android:name="com.kunzisoft.keepass.activities.ImageViewerActivity"
android:configChanges="keyboardHidden" />
<activity
android:name="com.kunzisoft.keepass.activities.EntryEditActivity"
android:configChanges="keyboardHidden"
android:windowSoftInputMode="adjustResize" />
<!-- About and Settings -->
<activity
android:name="com.kunzisoft.keepass.activities.AboutActivity"
android:launchMode="singleTask"
android:label="@string/menu_about" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
<activity android:name="com.kunzisoft.keepass.autofill.AutofillLauncherActivity"
android:label="@string/about" />
<activity
android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
<activity
android:name="com.kunzisoft.keepass.activities.AutofillLauncherActivity"
android:theme="@style/Theme.Transparent"
android:configChanges="keyboardHidden" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsAutofillActivity" />
<activity android:name="com.kunzisoft.keepass.magikeyboard.KeyboardLauncherActivity"
android:label="@string/keyboard_name">
<activity
android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" />
<activity
android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
<activity
android:name="com.kunzisoft.keepass.activities.EntrySelectionLauncherActivity"
android:theme="@style/Theme.Transparent">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="otpauth" android:host="totp" />
<data android:scheme="otpauth" android:host="hotp" />
</intent-filter>
</activity>
<activity android:name="com.kunzisoft.keepass.settings.MagikIMESettings"
<activity
android:name="com.kunzisoft.keepass.activities.MagikeyboardLauncherActivity"
android:theme="@style/Theme.Transparent" />
<activity
android:name="com.kunzisoft.keepass.settings.MagikeyboardSettingsActivity"
android:label="@string/keyboard_setting_label">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<service
android:name="com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService"
android:name="com.kunzisoft.keepass.services.DatabaseTaskNotificationService"
android:enabled="true"
android:exported="false" />
<service
android:name="com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService"
android:name="com.kunzisoft.keepass.services.AttachmentFileNotificationService"
android:enabled="true"
android:exported="false" />
<service
android:name="com.kunzisoft.keepass.services.ClipboardEntryNotificationService"
android:enabled="true"
android:exported="false" />
<service
android:name="com.kunzisoft.keepass.services.AdvancedUnlockNotificationService"
android:enabled="true"
android:exported="false" />
<!-- Receiver for Autofill -->
@@ -172,7 +219,7 @@
</intent-filter>
</service>
<service
android:name="com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService"
android:name="com.kunzisoft.keepass.services.KeyboardEntryNotificationService"
android:enabled="true"
android:exported="false" />

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,35 +1,35 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities
import android.content.pm.PackageManager.NameNotFoundException
import android.os.Bundle
import androidx.appcompat.widget.Toolbar
import android.text.method.LinkMovementMethod
import android.util.Log
import android.view.MenuItem
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import androidx.core.text.HtmlCompat
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import org.joda.time.DateTime
class AboutActivity : StylishActivity() {
@@ -40,7 +40,7 @@ class AboutActivity : StylishActivity() {
setContentView(R.layout.activity_about)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
toolbar.title = getString(R.string.menu_about)
toolbar.title = getString(R.string.about)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
@@ -64,9 +64,17 @@ class AboutActivity : StylishActivity() {
val buildTextView = findViewById<TextView>(R.id.activity_about_build)
buildTextView.text = build
findViewById<TextView>(R.id.activity_about_licence_text).apply {
movementMethod = LinkMovementMethod.getInstance()
text = HtmlCompat.fromHtml(getString(R.string.html_about_licence, DateTime().year),
HtmlCompat.FROM_HTML_MODE_LEGACY)
}
val disclaimerText = findViewById<TextView>(R.id.disclaimer)
disclaimerText.text = getString(R.string.disclaimer_formal, DateTime().year)
findViewById<TextView>(R.id.activity_about_contribution_text).apply {
movementMethod = LinkMovementMethod.getInstance()
text = HtmlCompat.fromHtml(getString(R.string.html_about_contribution),
HtmlCompat.FROM_HTML_MODE_LEGACY)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {

View File

@@ -0,0 +1,238 @@
/*
* 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.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.IntentSender
import android.os.Build
import android.os.Bundle
import android.view.inputmethod.InlineSuggestionsRequest
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.AutofillHelper.EXTRA_INLINE_SUGGESTIONS_REQUEST
import com.kunzisoft.keepass.autofill.KeeAutofillService
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.model.RegisterInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.LOCK_ACTION
@RequiresApi(api = Build.VERSION_CODES.O)
class AutofillLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Retrieve selection mode
EntrySelectionHelper.retrieveSpecialModeFromIntent(intent).let { specialMode ->
when (specialMode) {
SpecialMode.SELECTION -> {
// Build search param
val searchInfo = SearchInfo().apply {
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
webScheme = intent.getStringExtra(KEY_SEARCH_SCHEME)
}
SearchInfo.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
searchInfo.webDomain = concreteWebDomain
launchSelection(searchInfo)
}
}
SpecialMode.REGISTRATION -> {
// To register info
val registerInfo = intent.getParcelableExtra<RegisterInfo>(KEY_REGISTER_INFO)
val searchInfo = SearchInfo(registerInfo?.searchInfo)
SearchInfo.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
searchInfo.webDomain = concreteWebDomain
launchRegistration(searchInfo, registerInfo)
}
}
else -> {
// Not an autofill call
setResult(Activity.RESULT_CANCELED)
finish()
}
}
}
super.onCreate(savedInstanceState)
}
private fun launchSelection(searchInfo: SearchInfo) {
// Pass extra for Autofill (EXTRA_ASSIST_STRUCTURE)
val autofillComponent = AutofillHelper.retrieveAutofillComponent(intent)
if (autofillComponent == null) {
setResult(Activity.RESULT_CANCELED)
finish()
} else if (!KeeAutofillService.autofillAllowedFor(searchInfo.applicationId,
PreferencesUtil.applicationIdBlocklist(this))
|| !KeeAutofillService.autofillAllowedFor(searchInfo.webDomain,
PreferencesUtil.webDomainBlocklist(this))) {
showBlockRestartMessage()
setResult(Activity.RESULT_CANCELED)
finish()
} else {
val database = Database.getInstance()
val readOnly = database.isReadOnly
// If database is open
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
// Items found
AutofillHelper.buildResponseAndSetResult(this, items)
finish()
},
{
// Show the database UI to select the entry
GroupActivity.launchForAutofillResult(this,
readOnly,
autofillComponent,
searchInfo,
false)
},
{
// If database not open
FileDatabaseSelectActivity.launchForAutofillResult(this,
autofillComponent,
searchInfo)
}
)
}
}
private fun launchRegistration(searchInfo: SearchInfo, registerInfo: RegisterInfo?) {
if (!KeeAutofillService.autofillAllowedFor(searchInfo.applicationId,
PreferencesUtil.applicationIdBlocklist(this))
|| !KeeAutofillService.autofillAllowedFor(searchInfo.webDomain,
PreferencesUtil.webDomainBlocklist(this))) {
showBlockRestartMessage()
setResult(Activity.RESULT_CANCELED)
} else {
val database = Database.getInstance()
val readOnly = database.isReadOnly
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ _ ->
if (!readOnly) {
// Show the database UI to select the entry
GroupActivity.launchForRegistration(this,
registerInfo)
} else {
showReadOnlySaveMessage()
}
},
{
if (!readOnly) {
// Show the database UI to select the entry
GroupActivity.launchForRegistration(this,
registerInfo)
} else {
showReadOnlySaveMessage()
}
},
{
// If database not open
FileDatabaseSelectActivity.launchForRegistration(this,
registerInfo)
}
)
}
finish()
}
private fun showBlockRestartMessage() {
// If item not allowed, show a toast
Toast.makeText(this.applicationContext, R.string.autofill_block_restart, Toast.LENGTH_LONG).show()
}
private fun showReadOnlySaveMessage() {
Toast.makeText(this.applicationContext, R.string.autofill_read_only_save, Toast.LENGTH_LONG).show()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
if (PreferencesUtil.isAutofillCloseDatabaseEnable(this)) {
// Close the database
sendBroadcast(Intent(LOCK_ACTION))
}
super.onActivityResult(requestCode, resultCode, data)
}
companion object {
private const val KEY_SEARCH_APPLICATION_ID = "KEY_SEARCH_APPLICATION_ID"
private const val KEY_SEARCH_DOMAIN = "KEY_SEARCH_DOMAIN"
private const val KEY_SEARCH_SCHEME = "KEY_SEARCH_SCHEME"
private const val KEY_REGISTER_INFO = "KEY_REGISTER_INFO"
fun getAuthIntentSenderForSelection(context: Context,
searchInfo: SearchInfo? = null,
inlineSuggestionsRequest: InlineSuggestionsRequest? = null): IntentSender {
return PendingIntent.getActivity(context, 0,
// Doesn't work with Parcelable (don't know why?)
Intent(context, AutofillLauncherActivity::class.java).apply {
searchInfo?.let {
putExtra(KEY_SEARCH_APPLICATION_ID, it.applicationId)
putExtra(KEY_SEARCH_DOMAIN, it.webDomain)
putExtra(KEY_SEARCH_SCHEME, it.webScheme)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
inlineSuggestionsRequest?.let {
putExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST, it)
}
}
},
PendingIntent.FLAG_CANCEL_CURRENT).intentSender
}
fun getAuthIntentSenderForRegistration(context: Context,
registerInfo: RegisterInfo): IntentSender {
return PendingIntent.getActivity(context, 0,
Intent(context, AutofillLauncherActivity::class.java).apply {
EntrySelectionHelper.addSpecialModeInIntent(this, SpecialMode.REGISTRATION)
putExtra(KEY_REGISTER_INFO, registerInfo)
},
PendingIntent.FLAG_CANCEL_CURRENT).intentSender
}
fun launchForRegistration(context: Context,
registerInfo: RegisterInfo) {
val intent = Intent(context, AutofillLauncherActivity::class.java)
EntrySelectionHelper.addSpecialModeInIntent(intent, SpecialMode.REGISTRATION)
intent.putExtra(KEY_REGISTER_INFO, registerInfo)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
}

View File

@@ -1,67 +1,100 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* 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.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import com.google.android.material.appbar.CollapsingToolbarLayout
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar
import android.os.Looper
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingHideActivity
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged
import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.EntryVersioned
import com.kunzisoft.keepass.database.element.PwNodeId
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.education.EntryActivityEducation
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
import com.kunzisoft.keepass.model.EntryAttachmentState
import com.kunzisoft.keepass.model.StreamDirection
import com.kunzisoft.keepass.otp.OtpEntryFields
import com.kunzisoft.keepass.services.AttachmentFileNotificationService
import com.kunzisoft.keepass.services.ClipboardEntryNotificationService
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RELOAD_TASK
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.settings.SettingsAutofillActivity
import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager
import com.kunzisoft.keepass.timeout.ClipboardHelper
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.view.EntryContentsView
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import java.util.*
import kotlin.collections.HashMap
class EntryActivity : LockingHideActivity() {
class EntryActivity : LockingActivity() {
private var coordinatorLayout: CoordinatorLayout? = null
private var collapsingToolbarLayout: CollapsingToolbarLayout? = null
private var titleIconView: ImageView? = null
private var historyView: View? = null
private var entryContentsView: EntryContentsView? = null
private var entryProgress: ProgressBar? = null
private var lockView: View? = null
private var toolbar: Toolbar? = null
private var mEntry: EntryVersioned? = null
private var mDatabase: Database? = null
private var mEntry: Entry? = null
private var mIsHistory: Boolean = false
private var mEntryLastVersion: Entry? = null
private var mEntryHistoryPosition: Int = -1
private var mShowPassword: Boolean = false
private var mAttachmentFileBinderManager: AttachmentFileBinderManager? = null
private var mAttachmentsToDownload: HashMap<Int, Attachment> = HashMap()
private var clipboardHelper: ClipboardHelper? = null
private var firstLaunchOfActivity: Boolean = false
private var mFirstLaunchOfActivity: Boolean = false
private var mExternalFileHelper: ExternalFileHelper? = null
private var iconColor: Int = 0
@@ -75,19 +108,93 @@ class EntryActivity : LockingHideActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
val currentDatabase = Database.getInstance()
mReadOnly = currentDatabase.isReadOnly || mReadOnly
mDatabase = Database.getInstance()
mReadOnly = mDatabase!!.isReadOnly || mReadOnly
mShowPassword = !PreferencesUtil.isPasswordMask(this)
// Retrieve the textColor to tint the icon
val taIconColor = theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccent))
iconColor = taIconColor.getColor(0, Color.BLACK)
taIconColor.recycle()
// Refresh Menu contents in case onCreateMenuOptions was called before mEntry was set
invalidateOptionsMenu()
// Get views
coordinatorLayout = findViewById(R.id.toolbar_coordinator)
collapsingToolbarLayout = findViewById(R.id.toolbar_layout)
titleIconView = findViewById(R.id.entry_icon)
historyView = findViewById(R.id.history_container)
entryContentsView = findViewById(R.id.entry_contents)
entryContentsView?.applyFontVisibilityToFields(PreferencesUtil.fieldFontIsInVisibility(this))
entryContentsView?.setAttachmentCipherKey(mDatabase)
entryProgress = findViewById(R.id.entry_progress)
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
lockAndExit()
}
// Focus view to reinitialize timeout
coordinatorLayout?.resetAppTimeoutWhenViewFocusedOrChanged(this)
// Init the clipboard helper
clipboardHelper = ClipboardHelper(this)
mFirstLaunchOfActivity = savedInstanceState?.getBoolean(KEY_FIRST_LAUNCH_ACTIVITY) ?: true
// Init SAF manager
mExternalFileHelper = ExternalFileHelper(this)
// Init attachment service binder manager
mAttachmentFileBinderManager = AttachmentFileBinderManager(this)
mProgressDatabaseTaskProvider?.onActionFinish = { actionTask, result ->
when (actionTask) {
ACTION_DATABASE_RESTORE_ENTRY_HISTORY,
ACTION_DATABASE_DELETE_ENTRY_HISTORY -> {
// Close the current activity after an history action
if (result.isSuccess)
finish()
}
ACTION_DATABASE_RELOAD_TASK -> {
// Close the current activity
this.showActionErrorIfNeeded(result)
finish()
}
}
coordinatorLayout?.showActionErrorIfNeeded(result)
}
}
override fun onResume() {
super.onResume()
// Show the lock button
lockView?.visibility = if (PreferencesUtil.showLockDatabaseButton(this)) {
View.VISIBLE
} else {
View.GONE
}
// Get Entry from UUID
try {
val keyEntry: PwNodeId<*> = intent.getParcelableExtra(KEY_ENTRY)
mEntry = currentDatabase.getEntryById(keyEntry)
val keyEntry: NodeId<UUID>? = intent.getParcelableExtra(KEY_ENTRY)
if (keyEntry != null) {
mEntry = mDatabase?.getEntryById(keyEntry)
mEntryLastVersion = mEntry
}
} catch (e: ClassCastException) {
Log.e(TAG, "Unable to retrieve the entry key")
}
val historyPosition = intent.getIntExtra(KEY_ENTRY_HISTORY_POSITION, mEntryHistoryPosition)
mEntryHistoryPosition = historyPosition
if (historyPosition >= 0) {
mIsHistory = true
mEntry = mEntry?.getHistory()?.get(historyPosition)
}
if (mEntry == null) {
Toast.makeText(this, R.string.entry_not_found, Toast.LENGTH_LONG).show()
finish()
@@ -97,38 +204,15 @@ class EntryActivity : LockingHideActivity() {
// Update last access time.
mEntry?.touch(modified = false, touchParents = false)
// Retrieve the textColor to tint the icon
val taIconColor = theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccent))
iconColor = taIconColor.getColor(0, Color.BLACK)
taIconColor.recycle()
// Refresh Menu contents in case onCreateMenuOptions was called before mEntry was set
invalidateOptionsMenu()
// Get views
collapsingToolbarLayout = findViewById(R.id.toolbar_layout)
titleIconView = findViewById(R.id.entry_icon)
entryContentsView = findViewById(R.id.entry_contents)
entryContentsView?.applyFontVisibilityToFields(PreferencesUtil.fieldFontIsInVisibility(this))
// Init the clipboard helper
clipboardHelper = ClipboardHelper(this)
firstLaunchOfActivity = true
}
override fun onResume() {
super.onResume()
mEntry?.let { entry ->
// Fill data in resume to update from EntryEditActivity
fillEntryDataInContentsView(entry)
// Refresh Menu
invalidateOptionsMenu()
val entryInfo = entry.getEntryInfo(Database.getInstance())
val entryInfo = entry.getEntryInfo(mDatabase)
// Manage entry copy to start notification if allowed
if (firstLaunchOfActivity) {
if (mFirstLaunchOfActivity) {
// Manage entry to launch copying notification if allowed
ClipboardEntryNotificationService.launchNotificationIfAllowed(this, entryInfo)
// Manage entry to populate Magikeyboard and launch keyboard notification if allowed
@@ -138,30 +222,46 @@ class EntryActivity : LockingHideActivity() {
}
}
firstLaunchOfActivity = false
mAttachmentFileBinderManager?.apply {
registerProgressTask()
onActionTaskListener = object : AttachmentFileNotificationService.ActionTaskListener {
override fun onAttachmentAction(fileUri: Uri, entryAttachmentState: EntryAttachmentState) {
if (entryAttachmentState.streamDirection != StreamDirection.UPLOAD) {
entryContentsView?.putAttachment(entryAttachmentState)
}
}
}
}
mFirstLaunchOfActivity = false
}
private fun fillEntryDataInContentsView(entry: EntryVersioned) {
override fun onPause() {
mAttachmentFileBinderManager?.unregisterProgressTask()
super.onPause()
}
private fun fillEntryDataInContentsView(entry: Entry) {
val entryInfo = entry.getEntryInfo(mDatabase)
val database = Database.getInstance()
database.startManageEntry(entry)
// Assign title icon
titleIconView?.assignDatabaseIcon(database.drawFactory, entry.icon, iconColor)
titleIconView?.let { iconView ->
mDatabase?.iconDrawableFactory?.assignDatabaseIcon(iconView, entryInfo.icon, iconColor)
}
// Assign title text
val entryTitle = entry.title
val entryTitle = entryInfo.title
collapsingToolbarLayout?.title = entryTitle
toolbar?.title = entryTitle
// Assign basic fields
entryContentsView?.assignUserName(entry.username)
entryContentsView?.assignUserNameCopyListener(View.OnClickListener {
database.startManageEntry(entry)
clipboardHelper?.timeoutCopyToClipboard(entry.username,
getString(R.string.copy_field,
entryContentsView?.assignUserName(entryInfo.username) {
clipboardHelper?.timeoutCopyToClipboard(entryInfo.username,
getString(R.string.copy_field,
getString(R.string.entry_user_name)))
database.stopManageEntry(entry)
})
}
val isFirstTimeAskAllowCopyPasswordAndProtectedFields =
PreferencesUtil.isFirstTimeAskAllowCopyPasswordAndProtectedFields(this)
@@ -174,7 +274,7 @@ class EntryActivity : LockingHideActivity() {
"\n\n" +
getString(R.string.clipboard_warning))
.create().apply {
setButton(AlertDialog.BUTTON_POSITIVE, getText(R.string.enable)) {dialog, _ ->
setButton(AlertDialog.BUTTON_POSITIVE, getText(R.string.enable)) { dialog, _ ->
PreferencesUtil.setAllowCopyPasswordAndProtectedFields(this@EntryActivity, true)
dialog.dismiss()
fillEntryDataInContentsView(entry)
@@ -188,80 +288,96 @@ class EntryActivity : LockingHideActivity() {
}
}
entryContentsView?.assignPassword(entry.password, allowCopyPasswordAndProtectedFields)
if (allowCopyPasswordAndProtectedFields) {
entryContentsView?.assignPasswordCopyListener(View.OnClickListener {
database.startManageEntry(entry)
clipboardHelper?.timeoutCopyToClipboard(entry.password,
getString(R.string.copy_field,
val onPasswordCopyClickListener: View.OnClickListener? = if (allowCopyPasswordAndProtectedFields) {
View.OnClickListener {
clipboardHelper?.timeoutCopyToClipboard(entryInfo.password,
getString(R.string.copy_field,
getString(R.string.entry_password)))
database.stopManageEntry(entry)
})
}
} else {
// If dialog not already shown
if (isFirstTimeAskAllowCopyPasswordAndProtectedFields) {
entryContentsView?.assignPasswordCopyListener(showWarningClipboardDialogOnClickListener)
showWarningClipboardDialogOnClickListener
} else {
entryContentsView?.assignPasswordCopyListener(null)
null
}
}
entryContentsView?.assignPassword(entryInfo.password,
allowCopyPasswordAndProtectedFields,
onPasswordCopyClickListener)
//Assign OTP field
entry.getOtpElement()?.let { otpElement ->
entryContentsView?.assignOtp(otpElement, entryProgress) {
clipboardHelper?.timeoutCopyToClipboard(
otpElement.token,
getString(R.string.copy_field, getString(R.string.entry_otp))
)
}
}
entryContentsView?.assignURL(entry.url)
entryContentsView?.assignComment(entry.notes)
entryContentsView?.assignURL(entryInfo.url)
entryContentsView?.assignNotes(entryInfo.notes)
// Assign custom fields
if (entry.allowCustomFields()) {
if (mDatabase?.allowEntryCustomFields() == true) {
entryContentsView?.clearExtraFields()
for (element in entry.customFields.entries) {
val label = element.key
val value = element.value
val allowCopyProtectedField = !value.isProtected || allowCopyPasswordAndProtectedFields
if (allowCopyProtectedField) {
entryContentsView?.addExtraField(label, value, allowCopyProtectedField, View.OnClickListener {
clipboardHelper?.timeoutCopyToClipboard(
value.toString(),
getString(R.string.copy_field, label)
)
})
} else {
// If dialog not already shown
if (isFirstTimeAskAllowCopyPasswordAndProtectedFields) {
entryContentsView?.addExtraField(label, value, allowCopyProtectedField, showWarningClipboardDialogOnClickListener)
entryInfo.customFields.forEach { field ->
val label = field.name
// OTP field is already managed in dedicated view
if (label != OtpEntryFields.OTP_TOKEN_FIELD) {
val value = field.protectedValue
val allowCopyProtectedField = !value.isProtected || allowCopyPasswordAndProtectedFields
if (allowCopyProtectedField) {
entryContentsView?.addExtraField(label, value, allowCopyProtectedField) {
clipboardHelper?.timeoutCopyToClipboard(
value.toString(),
getString(R.string.copy_field, label)
)
}
} else {
entryContentsView?.addExtraField(label, value, allowCopyProtectedField, null)
// If dialog not already shown
if (isFirstTimeAskAllowCopyPasswordAndProtectedFields) {
entryContentsView?.addExtraField(label, value, allowCopyProtectedField, showWarningClipboardDialogOnClickListener)
} else {
entryContentsView?.addExtraField(label, value, allowCopyProtectedField, null)
}
}
}
}
}
entryContentsView?.setHiddenPasswordStyle(!mShowPassword)
entryContentsView?.setHiddenProtectedValue(!mShowPassword)
// Manage attachments
entryContentsView?.assignAttachments(entryInfo.attachments.toSet(), StreamDirection.DOWNLOAD) { attachmentItem ->
mExternalFileHelper?.createDocument(attachmentItem.name)?.let { requestCode ->
mAttachmentsToDownload[requestCode] = attachmentItem
}
}
// Assign dates
entry.creationTime.date?.let {
entryContentsView?.assignCreationDate(it)
entryContentsView?.assignCreationDate(entryInfo.creationTime)
entryContentsView?.assignModificationDate(entryInfo.lastModificationTime)
entryContentsView?.setExpires(entryInfo.expires, entryInfo.expiryTime)
// Manage history
historyView?.visibility = if (mIsHistory) View.VISIBLE else View.GONE
if (mIsHistory) {
val taColorAccent = theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccent))
collapsingToolbarLayout?.contentScrim = ColorDrawable(taColorAccent.getColor(0, Color.BLACK))
taColorAccent.recycle()
}
entry.lastModificationTime.date?.let {
entryContentsView?.assignModificationDate(it)
}
entry.lastAccessTime.date?.let {
entryContentsView?.assignLastAccessDate(it)
}
val expires = entry.expiryTime.date
if (entry.isExpires && expires != null) {
entryContentsView?.assignExpiresDate(expires)
} else {
entryContentsView?.assignExpiresDate(getString(R.string.never))
entryContentsView?.assignHistory(entry.getHistory()) { historyItem, position ->
launch(this, historyItem, mReadOnly, position)
}
// Assign special data
entryContentsView?.assignUUID(entry.nodeId.id)
database.stopManageEntry(entry)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE ->
// Not directly get the entry from intent data but from database
@@ -269,15 +385,14 @@ class EntryActivity : LockingHideActivity() {
fillEntryDataInContentsView(it)
}
}
}
private fun changeShowPasswordIcon(togglePassword: MenuItem?) {
if (mShowPassword) {
togglePassword?.setTitle(R.string.menu_hide_password)
togglePassword?.setIcon(R.drawable.ic_visibility_off_white_24dp)
} else {
togglePassword?.setTitle(R.string.menu_showpass)
togglePassword?.setIcon(R.drawable.ic_visibility_white_24dp)
mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { createdFileUri ->
if (createdFileUri != null) {
mAttachmentsToDownload[requestCode]?.let { attachmentToDownload ->
mAttachmentFileBinderManager
?.startDownloadAttachment(createdFileUri, attachmentToDownload)
}
}
}
}
@@ -287,19 +402,16 @@ class EntryActivity : LockingHideActivity() {
val inflater = menuInflater
MenuUtil.contributionMenuInflater(inflater, menu)
inflater.inflate(R.menu.entry, menu)
inflater.inflate(R.menu.database_lock, menu)
if (mReadOnly) {
inflater.inflate(R.menu.database, menu)
if (mIsHistory && !mReadOnly) {
inflater.inflate(R.menu.entry_history, menu)
}
if (mIsHistory || mReadOnly) {
menu.findItem(R.id.menu_save_database)?.isVisible = false
menu.findItem(R.id.menu_edit)?.isVisible = false
}
val togglePassword = menu.findItem(R.id.menu_toggle_pass)
entryContentsView?.let {
if (it.isPasswordPresent || it.atLeastOneFieldProtectedPresent()) {
changeShowPasswordIcon(togglePassword)
} else {
togglePassword?.isVisible = false
}
if (mSpecialMode != SpecialMode.DEFAULT) {
menu.findItem(R.id.menu_reload_database)?.isVisible = false
}
val gotoUrl = menu.findItem(R.id.menu_goto_url)
@@ -317,38 +429,38 @@ class EntryActivity : LockingHideActivity() {
}
// Show education views
Handler().post { performedNextEducation(EntryActivityEducation(this), menu) }
Handler(Looper.getMainLooper()).post { performedNextEducation(EntryActivityEducation(this), menu) }
return true
}
private fun performedNextEducation(entryActivityEducation: EntryActivityEducation,
menu: Menu) {
val entryCopyEducationPerformed = entryContentsView?.isUserNamePresent == true
val entryFieldCopyView = entryContentsView?.firstEntryFieldCopyView()
val entryCopyEducationPerformed = entryFieldCopyView != null
&& entryActivityEducation.checkAndPerformedEntryCopyEducation(
findViewById(R.id.entry_user_name_action_image),
entryFieldCopyView,
{
clipboardHelper?.timeoutCopyToClipboard(mEntry!!.username,
getString(R.string.copy_field,
getString(R.string.entry_user_name)))
val appNameString = getString(R.string.app_name)
clipboardHelper?.timeoutCopyToClipboard(appNameString,
getString(R.string.copy_field, appNameString))
},
{
// Launch autofill settings
startActivity(Intent(this@EntryActivity, SettingsAutofillActivity::class.java))
performedNextEducation(entryActivityEducation, menu)
})
if (!entryCopyEducationPerformed) {
val menuEditView = toolbar?.findViewById<View>(R.id.menu_edit)
// entryEditEducationPerformed
toolbar?.findViewById<View>(R.id.menu_edit) != null && entryActivityEducation.checkAndPerformedEntryEditEducation(
toolbar!!.findViewById(R.id.menu_edit),
{
onOptionsItemSelected(menu.findItem(R.id.menu_edit))
},
{
// Open Keepass doc to create field references
startActivity(Intent(Intent.ACTION_VIEW,
UriUtil.parse(getString(R.string.field_references_url))))
})
menuEditView != null && entryActivityEducation.checkAndPerformedEntryEditEducation(
menuEditView,
{
onOptionsItemSelected(menu.findItem(R.id.menu_edit))
},
{
performedNextEducation(entryActivityEducation, menu)
}
)
}
}
@@ -358,21 +470,12 @@ class EntryActivity : LockingHideActivity() {
MenuUtil.onContributionItemSelected(this)
return true
}
R.id.menu_toggle_pass -> {
mShowPassword = !mShowPassword
changeShowPasswordIcon(item)
entryContentsView?.setHiddenPasswordStyle(!mShowPassword)
return true
}
R.id.menu_edit -> {
mEntry?.let {
EntryEditActivity.launch(this@EntryActivity, it)
}
return true
}
R.id.menu_goto_url -> {
var url: String = mEntry?.url ?: ""
@@ -382,43 +485,65 @@ class EntryActivity : LockingHideActivity() {
}
UriUtil.gotoUrl(this, url)
return true
}
R.id.menu_lock -> {
lockAndExit()
return true
R.id.menu_restore_entry_history -> {
mEntryLastVersion?.let { mainEntry ->
mProgressDatabaseTaskProvider?.startDatabaseRestoreEntryHistory(
mainEntry,
mEntryHistoryPosition,
!mReadOnly && mAutoSaveEnable)
}
}
R.id.menu_delete_entry_history -> {
mEntryLastVersion?.let { mainEntry ->
mProgressDatabaseTaskProvider?.startDatabaseDeleteEntryHistory(
mainEntry,
mEntryHistoryPosition,
!mReadOnly && mAutoSaveEnable)
}
}
R.id.menu_save_database -> {
mProgressDatabaseTaskProvider?.startDatabaseSave(!mReadOnly)
}
R.id.menu_reload_database -> {
mProgressDatabaseTaskProvider?.startDatabaseReload(false)
}
android.R.id.home -> finish() // close this activity and return to preview activity (if there is any)
}
return super.onOptionsItemSelected(item)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(KEY_FIRST_LAUNCH_ACTIVITY, mFirstLaunchOfActivity)
}
override fun finish() {
// Transit data in previous Activity after an update
/*
TODO Slowdown when add entry as result
Intent intent = new Intent();
intent.putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry);
setResult(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, intent);
*/
Intent().apply {
putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry)
setResult(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, this)
}
super.finish()
}
companion object {
private val TAG = EntryActivity::class.java.name
const val KEY_ENTRY = "entry"
private const val KEY_FIRST_LAUNCH_ACTIVITY = "KEY_FIRST_LAUNCH_ACTIVITY"
fun launch(activity: Activity, pw: EntryVersioned, readOnly: Boolean) {
const val KEY_ENTRY = "KEY_ENTRY"
const val KEY_ENTRY_HISTORY_POSITION = "KEY_ENTRY_HISTORY_POSITION"
fun launch(activity: Activity, entry: Entry, readOnly: Boolean, historyPosition: Int? = null) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
val intent = Intent(activity, EntryActivity::class.java)
intent.putExtra(KEY_ENTRY, pw.nodeId)
intent.putExtra(KEY_ENTRY, entry.nodeId)
ReadOnlyHelper.putReadOnlyInIntent(intent, readOnly)
if (historyPosition != null)
intent.putExtra(KEY_ENTRY_HISTORY_POSITION, historyPosition)
activity.startActivityForResult(intent, EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE)
}
}

View File

@@ -0,0 +1,190 @@
/*
* 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 android.widget.Toast
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.otp.OtpEntryFields
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
var otpString: String? = null
when (intent?.action) {
Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
// Retrieve web domain or OTP
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { extra ->
if (OtpEntryFields.isOTPUri(extra))
otpString = extra
else
sharedWebDomain = Uri.parse(extra).host
}
}
}
Intent.ACTION_VIEW -> {
// Retrieve OTP
intent.dataString?.let { extra ->
if (OtpEntryFields.isOTPUri(extra))
otpString = extra
}
}
else -> {}
}
// Build domain search param
val searchInfo = SearchInfo().apply {
this.webDomain = sharedWebDomain
this.otpString = otpString
}
SearchInfo.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
searchInfo.webDomain = concreteWebDomain
launch(searchInfo)
}
super.onCreate(savedInstanceState)
}
private fun launch(searchInfo: SearchInfo) {
if (!searchInfo.containsOnlyNullValues()) {
// Setting to integrate Magikeyboard
val searchShareForMagikeyboard = PreferencesUtil.isKeyboardSearchShareEnable(this)
// If database is open
val database = Database.getInstance()
val readOnly = database.isReadOnly
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ items ->
// Items found
if (searchInfo.otpString != null) {
if (!readOnly) {
GroupActivity.launchForSaveResult(this,
searchInfo,
false)
} else {
Toast.makeText(applicationContext,
R.string.autofill_read_only_save,
Toast.LENGTH_LONG)
.show()
}
} else if (searchShareForMagikeyboard) {
if (items.size == 1) {
// Automatically populate keyboard
val entryPopulate = items[0]
populateKeyboardAndMoveAppToBackground(this,
entryPopulate,
intent)
} else {
// Select the one we want
GroupActivity.launchForKeyboardSelectionResult(this,
readOnly,
searchInfo,
true)
}
} else {
GroupActivity.launchForSearchResult(this,
readOnly,
searchInfo,
true)
}
},
{
// Show the database UI to select the entry
if (searchInfo.otpString != null) {
if (!readOnly) {
GroupActivity.launchForSaveResult(this,
searchInfo,
false)
} else {
Toast.makeText(applicationContext,
R.string.autofill_read_only_save,
Toast.LENGTH_LONG)
.show()
}
} else if (readOnly || searchShareForMagikeyboard) {
GroupActivity.launchForKeyboardSelectionResult(this,
readOnly,
searchInfo,
false)
} else {
GroupActivity.launchForSaveResult(this,
searchInfo,
false)
}
},
{
// If database not open
if (searchInfo.otpString != null) {
if (!readOnly) {
FileDatabaseSelectActivity.launchForSaveResult(this,
searchInfo)
} else {
Toast.makeText(applicationContext,
R.string.autofill_read_only_save,
Toast.LENGTH_LONG)
.show()
}
} else if (searchShareForMagikeyboard) {
FileDatabaseSelectActivity.launchForKeyboardSelectionResult(this,
searchInfo)
} else {
FileDatabaseSelectActivity.launchForSearchResult(this,
searchInfo)
}
}
)
}
finish()
}
}
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.removeModesFromIntent(intent)
activity.moveTaskToBack(true)
}

View File

@@ -1,79 +1,80 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities
import android.annotation.SuppressLint
import android.app.Activity
import android.app.assist.AssistStructure
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.preference.PreferenceManager
import androidx.annotation.RequiresApi
import com.google.android.material.snackbar.Snackbar
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import androidx.appcompat.widget.Toolbar
import android.os.Looper
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
import com.kunzisoft.keepass.activities.dialogs.BrowserDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.OpenFileHelper
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillComponent
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.database.action.CreateDatabaseRunnable
import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.action.ProgressDatabaseTaskProvider
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.education.FileDatabaseSelectActivityEducation
import com.kunzisoft.keepass.model.MainCredential
import com.kunzisoft.keepass.model.RegisterInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_TASK
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.view.asError
import kotlinx.android.synthetic.main.activity_file_selection.*
import net.cachapa.expandablelayout.ExpandableLayout
import com.kunzisoft.keepass.viewmodels.DatabaseFilesViewModel
import java.io.FileNotFoundException
class FileDatabaseSelectActivity : StylishActivity(),
class FileDatabaseSelectActivity : SpecialModeActivity(),
AssignMasterKeyDialogFragment.AssignPasswordDialogListener {
// Views
private var fileListContainer: View? = null
private var createButtonView: View? = null
private var browseButtonView: View? = null
private var openButtonView: View? = null
private var fileSelectExpandableButtonView: View? = null
private var fileSelectExpandableLayout: ExpandableLayout? = null
private var openFileNameView: EditText? = null
private lateinit var coordinatorLayout: CoordinatorLayout
private var createDatabaseButtonView: View? = null
private var openDatabaseButtonView: View? = null
private val databaseFilesViewModel: DatabaseFilesViewModel by viewModels()
// Adapter to manage database history list
private var mAdapterDatabaseHistory: FileDatabaseHistoryAdapter? = null
@@ -82,9 +83,9 @@ class FileDatabaseSelectActivity : StylishActivity(),
private var mDatabaseFileUri: Uri? = null
private var mOpenFileHelper: OpenFileHelper? = null
private var mExternalFileHelper: ExternalFileHelper? = null
private var mDefaultPath: String? = null
private var mProgressDatabaseTaskProvider: ProgressDatabaseTaskProvider? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -92,69 +93,20 @@ class FileDatabaseSelectActivity : StylishActivity(),
mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(applicationContext)
setContentView(R.layout.activity_file_selection)
fileListContainer = findViewById(R.id.container_file_list)
coordinatorLayout = findViewById(R.id.activity_file_selection_coordinator_layout)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
toolbar.title = ""
setSupportActionBar(toolbar)
openFileNameView = findViewById(R.id.file_filename)
// Create database button
createDatabaseButtonView = findViewById(R.id.create_database_button)
createDatabaseButtonView?.setOnClickListener { createNewFile() }
// Set the initial value of the filename
mDefaultPath = (Environment.getExternalStorageDirectory().absolutePath
+ getString(R.string.database_file_path_default)
+ getString(R.string.database_file_name_default)
+ getString(R.string.database_file_extension_default))
openFileNameView?.setHint(R.string.open_link_database)
// Button to expand file selection
fileSelectExpandableButtonView = findViewById(R.id.file_select_expandable_button)
fileSelectExpandableLayout = findViewById(R.id.file_select_expandable)
fileSelectExpandableButtonView?.setOnClickListener { _ ->
if (fileSelectExpandableLayout?.isExpanded == true)
fileSelectExpandableLayout?.collapse()
else
fileSelectExpandableLayout?.expand()
}
// Open button
openButtonView = findViewById(R.id.open_database)
openButtonView?.setOnClickListener { _ ->
var fileName = openFileNameView?.text?.toString() ?: ""
mDefaultPath?.let {
if (fileName.isEmpty())
fileName = it
}
UriUtil.parse(fileName)?.let { fileNameUri ->
launchPasswordActivityWithPath(fileNameUri)
} ?: run {
Log.e(TAG, "Unable to open the database link")
Snackbar.make(activity_file_selection_coordinator_layout, getString(R.string.error_can_not_handle_uri), Snackbar.LENGTH_LONG).asError().show()
null
}
}
// Create button
createButtonView = findViewById(R.id.create_database)
if (Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/x-keepass"
}.resolveActivity(packageManager) == null) {
// No Activity found that can handle this intent.
createButtonView?.visibility = View.GONE
}
else{
// There is an activity which can handle this intent.
createButtonView?.visibility = View.VISIBLE
}
createButtonView?.setOnClickListener { createNewFile() }
mOpenFileHelper = OpenFileHelper(this)
browseButtonView = findViewById(R.id.browse_button)
browseButtonView?.setOnClickListener(mOpenFileHelper!!.getOpenFileOnClickViewListener {
UriUtil.parse(openFileNameView?.text?.toString())
})
// Open database button
mExternalFileHelper = ExternalFileHelper(this)
openDatabaseButtonView = findViewById(R.id.open_keyfile_button)
openDatabaseButtonView?.setOpenDocumentClickListener(mExternalFileHelper)
// History list
val fileDatabaseHistoryRecyclerView = findViewById<RecyclerView>(R.id.file_list)
@@ -163,28 +115,25 @@ class FileDatabaseSelectActivity : StylishActivity(),
(fileDatabaseHistoryRecyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
// Construct adapter with listeners
mAdapterDatabaseHistory = FileDatabaseHistoryAdapter(this)
mAdapterDatabaseHistory?.setOnDefaultDatabaseListener { databaseFile ->
databaseFilesViewModel.setDefaultDatabase(databaseFile)
}
mAdapterDatabaseHistory?.setOnFileDatabaseHistoryOpenListener { fileDatabaseHistoryEntityToOpen ->
UriUtil.parse(fileDatabaseHistoryEntityToOpen.databaseUri)?.let { databaseFileUri ->
fileDatabaseHistoryEntityToOpen.databaseUri?.let { databaseFileUri ->
launchPasswordActivity(
databaseFileUri,
UriUtil.parse(fileDatabaseHistoryEntityToOpen.keyFileUri))
fileDatabaseHistoryEntityToOpen.keyFileUri
)
}
updateFileListVisibility()
}
mAdapterDatabaseHistory?.setOnFileDatabaseHistoryDeleteListener { fileDatabaseHistoryToDelete ->
// Remove from app database
mFileDatabaseHistoryAction?.deleteFileDatabaseHistory(fileDatabaseHistoryToDelete) { fileHistoryDeleted ->
// Remove from adapter
fileHistoryDeleted?.let { databaseFileHistoryDeleted ->
mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileHistoryDeleted)
mAdapterDatabaseHistory?.notifyDataSetChanged()
updateFileListVisibility()
}
}
databaseFilesViewModel.deleteDatabaseFile(fileDatabaseHistoryToDelete)
true
}
mAdapterDatabaseHistory?.setOnSaveAliasListener { fileDatabaseHistoryWithNewAlias ->
mFileDatabaseHistoryAction?.addOrUpdateFileDatabaseHistory(fileDatabaseHistoryWithNewAlias)
// Update in app database
databaseFilesViewModel.updateDatabaseFile(fileDatabaseHistoryWithNewAlias)
}
fileDatabaseHistoryRecyclerView.adapter = mAdapterDatabaseHistory
@@ -192,13 +141,12 @@ class FileDatabaseSelectActivity : StylishActivity(),
if (!(savedInstanceState != null
&& savedInstanceState.containsKey(EXTRA_STAY)
&& savedInstanceState.getBoolean(EXTRA_STAY, false))) {
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val databasePath = prefs.getString(PasswordActivity.KEY_DEFAULT_DATABASE_PATH, "")
val databasePath = PreferencesUtil.getDefaultDatabasePath(this)
UriUtil.parse(databasePath)?.let { databaseFileUri ->
launchPasswordActivityWithPath(databaseFileUri)
} ?: run {
Log.i(TAG, "Unable to launch Password Activity")
Log.i(TAG, "No default database to prepare")
}
}
@@ -207,64 +155,118 @@ class FileDatabaseSelectActivity : StylishActivity(),
&& savedInstanceState.containsKey(EXTRA_DATABASE_URI)) {
mDatabaseFileUri = savedInstanceState.getParcelable(EXTRA_DATABASE_URI)
}
// Observe list of databases
databaseFilesViewModel.databaseFilesLoaded.observe(this) { databaseFiles ->
try {
when (databaseFiles.databaseFileAction) {
DatabaseFilesViewModel.DatabaseFileAction.NONE -> {
mAdapterDatabaseHistory?.replaceAllDatabaseFileHistoryList(databaseFiles.databaseFileList)
}
DatabaseFilesViewModel.DatabaseFileAction.ADD -> {
databaseFiles.databaseFileToActivate?.let { databaseFileToAdd ->
mAdapterDatabaseHistory?.addDatabaseFileHistory(databaseFileToAdd)
}
}
DatabaseFilesViewModel.DatabaseFileAction.UPDATE -> {
databaseFiles.databaseFileToActivate?.let { databaseFileToUpdate ->
mAdapterDatabaseHistory?.updateDatabaseFileHistory(databaseFileToUpdate)
}
}
DatabaseFilesViewModel.DatabaseFileAction.DELETE -> {
databaseFiles.databaseFileToActivate?.let { databaseFileToDelete ->
mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileToDelete)
}
}
}
databaseFilesViewModel.consumeAction()
} catch (e: Exception) {
Log.e(TAG, "Unable to observe database action", e)
}
}
// Observe default database
databaseFilesViewModel.defaultDatabase.observe(this) {
// Retrieve settings for default database
mAdapterDatabaseHistory?.setDefaultDatabase(it)
}
// Attach the dialog thread to this activity
mProgressDatabaseTaskProvider = ProgressDatabaseTaskProvider(this).apply {
onActionFinish = { actionTask, result ->
when (actionTask) {
ACTION_DATABASE_CREATE_TASK -> {
result.data?.getParcelable<Uri?>(DATABASE_URI_KEY)?.let { databaseUri ->
val mainCredential = result.data?.getParcelable(DatabaseTaskNotificationService.MAIN_CREDENTIAL_KEY) ?: MainCredential()
databaseFilesViewModel.addDatabaseFile(databaseUri, mainCredential.keyFileUri)
}
GroupActivity.launch(this@FileDatabaseSelectActivity,
PreferencesUtil.enableReadOnlyDatabase(this@FileDatabaseSelectActivity))
}
ACTION_DATABASE_LOAD_TASK -> {
val database = Database.getInstance()
if (result.isSuccess
&& database.loaded) {
launchGroupActivity(database)
} else {
var resultError = ""
val resultMessage = result.message
// Show error message
if (resultMessage != null && resultMessage.isNotEmpty()) {
resultError = "$resultError $resultMessage"
}
Log.e(TAG, resultError)
Snackbar.make(coordinatorLayout,
resultError,
Snackbar.LENGTH_LONG).asError().show()
}
}
}
}
}
}
/**
* Create a new file by calling the content provider
*/
@SuppressLint("InlinedApi")
private fun createNewFile() {
try {
startActivityForResult(Intent(
Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/x-keepass"
putExtra(Intent.EXTRA_TITLE, getString(R.string.database_file_name_default) +
getString(R.string.database_file_extension_default))
},
CREATE_FILE_REQUEST_CODE)
} catch (e: Exception) {
BrowserDialogFragment().show(supportFragmentManager, "browserDialog")
}
mExternalFileHelper?.createDocument( getString(R.string.database_file_name_default) +
getString(R.string.database_file_extension_default), "application/x-keepass")
}
private fun fileNoFoundAction(e: FileNotFoundException) {
val error = getString(R.string.file_not_found_content)
Snackbar.make(activity_file_selection_coordinator_layout, error, Snackbar.LENGTH_LONG).asError().show()
Log.e(TAG, error, e)
Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show()
}
private fun launchPasswordActivity(databaseUri: Uri, keyFile: Uri?) {
EntrySelectionHelper.doEntrySelectionAction(intent,
{
try {
PasswordActivity.launch(this@FileDatabaseSelectActivity,
databaseUri, keyFile)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
PasswordActivity.launch(this,
databaseUri,
keyFile,
{ exception ->
fileNoFoundAction(exception)
},
{
try {
PasswordActivity.launchForKeyboardResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile)
finish()
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
},
{ assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
PasswordActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile,
assistStructure)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
{ onCancelSpecialMode() },
{ onLaunchActivitySpecialMode() })
}
}
})
private fun launchGroupActivity(database: Database) {
GroupActivity.launch(this,
database.isReadOnly,
{ onValidateSpecialMode() },
{ onCancelSpecialMode() },
{ onLaunchActivitySpecialMode() })
}
override fun onValidateSpecialMode() {
super.onValidateSpecialMode()
finish()
}
override fun onCancelSpecialMode() {
super.onCancelSpecialMode()
finish()
}
private fun launchPasswordActivityWithPath(databaseUri: Uri) {
@@ -274,38 +276,48 @@ class FileDatabaseSelectActivity : StylishActivity(),
overridePendingTransition(0, 0)
}
private fun updateExternalStorageWarning() {
// To show errors
var warning = -1
val state = Environment.getExternalStorageState()
if (state == Environment.MEDIA_MOUNTED_READ_ONLY) {
warning = R.string.read_only_warning
} else if (state != Environment.MEDIA_MOUNTED) {
warning = R.string.warning_unmounted
}
val labelWarningView = findViewById<TextView>(R.id.label_warning)
if (warning != -1) {
labelWarningView.setText(warning)
labelWarningView.visibility = View.VISIBLE
} else {
labelWarningView.visibility = View.INVISIBLE
}
}
override fun onResume() {
super.onResume()
updateExternalStorageWarning()
// Construct adapter with listeners
mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
databaseFileHistoryList?.let {
mAdapterDatabaseHistory?.addDatabaseFileHistoryList(it)
updateFileListVisibility()
mAdapterDatabaseHistory?.notifyDataSetChanged()
// Show open and create button or special mode
when (mSpecialMode) {
SpecialMode.DEFAULT -> {
if (ExternalFileHelper.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
}
}
else -> {
// Disable create button if in selection mode or request for autofill
createDatabaseButtonView?.visibility = View.GONE
}
}
val database = Database.getInstance()
if (database.loaded) {
launchGroupActivity(database)
} else {
// Construct adapter with listeners
if (PreferencesUtil.showRecentFiles(this)) {
databaseFilesViewModel.loadListOfDatabases()
} else {
mAdapterDatabaseHistory?.clearDatabaseFileHistoryList()
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
// Register progress task
mProgressDatabaseTaskProvider?.registerProgressTask()
}
}
override fun onPause() {
// Unregister progress task
mProgressDatabaseTaskProvider?.unregisterProgressTask()
super.onPause()
}
override fun onSaveInstanceState(outState: Bundle) {
@@ -316,71 +328,25 @@ class FileDatabaseSelectActivity : StylishActivity(),
outState.putParcelable(EXTRA_DATABASE_URI, mDatabaseFileUri)
}
private fun updateFileListVisibility() {
if (mAdapterDatabaseHistory?.itemCount == 0)
fileListContainer?.visibility = View.INVISIBLE
else
fileListContainer?.visibility = View.VISIBLE
}
override fun onAssignKeyDialogPositiveClick(
masterPasswordChecked: Boolean, masterPassword: String?,
keyFileChecked: Boolean, keyFile: Uri?) {
override fun onAssignKeyDialogPositiveClick(mainCredential: MainCredential) {
try {
mDatabaseFileUri?.let { databaseUri ->
// Create the new database
ProgressDialogThread(this@FileDatabaseSelectActivity,
{
CreateDatabaseRunnable(this@FileDatabaseSelectActivity,
databaseUri,
Database.getInstance(),
masterPasswordChecked,
masterPassword,
keyFileChecked,
keyFile,
true, // TODO get readonly
LaunchGroupActivityFinish(databaseUri, keyFile)
)
},
R.string.progress_create)
.start()
mProgressDatabaseTaskProvider?.startDatabaseCreate(
databaseUri,
mainCredential
)
}
} catch (e: Exception) {
val error = getString(R.string.error_create_database_file)
Snackbar.make(activity_file_selection_coordinator_layout, error, Snackbar.LENGTH_LONG).asError().show()
Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show()
Log.e(TAG, error, e)
}
}
private inner class LaunchGroupActivityFinish(private val databaseFileUri: Uri,
private val keyFileUri: Uri?) : ActionRunnable() {
override fun run() {
finishRun(true, null)
}
override fun onFinishRun(result: Result) {
runOnUiThread {
if (result.isSuccess) {
// Add database to recent files
mFileDatabaseHistoryAction?.addOrUpdateDatabaseUri(databaseFileUri, keyFileUri)
mAdapterDatabaseHistory?.notifyDataSetChanged()
updateFileListVisibility()
GroupActivity.launch(this@FileDatabaseSelectActivity)
} else {
Log.e(TAG, "Unable to open the database")
}
}
}
}
override fun onAssignKeyDialogNegativeClick(
masterPasswordChecked: Boolean, masterPassword: String?,
keyFileChecked: Boolean, keyFile: Uri?) {
}
override fun onAssignKeyDialogNegativeClick(mainCredential: MainCredential) {}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
@@ -389,46 +355,47 @@ class FileDatabaseSelectActivity : StylishActivity(),
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
}
mOpenFileHelper?.onActivityResultCallback(requestCode, resultCode, data
) { uri ->
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
if (uri != null) {
if (PreferencesUtil.autoOpenSelectedFile(this@FileDatabaseSelectActivity)) {
launchPasswordActivityWithPath(uri)
} else {
fileSelectExpandableLayout?.expand(false)
openFileNameView?.setText(uri.toString())
}
launchPasswordActivityWithPath(uri)
}
}
// Retrieve the created URI from the file manager
if (requestCode == CREATE_FILE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
mDatabaseFileUri = data?.data
mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { databaseFileCreatedUri ->
mDatabaseFileUri = databaseFileCreatedUri
if (mDatabaseFileUri != null) {
AssignMasterKeyDialogFragment().show(supportFragmentManager, "passwordDialog")
AssignMasterKeyDialogFragment.getInstance(true)
.show(supportFragmentManager, "passwordDialog")
} else {
val error = getString(R.string.error_create_database)
Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show()
Log.e(TAG, error)
}
// else {
// TODO Show error
// }
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
MenuUtil.defaultMenuInflater(menuInflater, menu)
Handler().post { performedNextEducation(FileDatabaseSelectActivityEducation(this)) }
if (mSpecialMode == SpecialMode.DEFAULT) {
MenuUtil.defaultMenuInflater(menuInflater, menu)
}
Handler(Looper.getMainLooper()).post { performedNextEducation(FileDatabaseSelectActivityEducation(this)) }
return true
}
private fun performedNextEducation(fileDatabaseSelectActivityEducation: FileDatabaseSelectActivityEducation) {
// If no recent files
val createDatabaseEducationPerformed = createButtonView != null && createButtonView!!.visibility == View.VISIBLE
val createDatabaseEducationPerformed =
createDatabaseButtonView != null
&& createDatabaseButtonView!!.visibility == View.VISIBLE
&& mAdapterDatabaseHistory != null
&& mAdapterDatabaseHistory!!.itemCount > 0
&& mAdapterDatabaseHistory!!.itemCount == 0
&& fileDatabaseSelectActivityEducation.checkAndPerformedCreateDatabaseEducation(
createButtonView!!,
createDatabaseButtonView!!,
{
createNewFile()
},
@@ -438,26 +405,25 @@ class FileDatabaseSelectActivity : StylishActivity(),
})
if (!createDatabaseEducationPerformed) {
// selectDatabaseEducationPerformed
browseButtonView != null
openDatabaseButtonView != null
&& fileDatabaseSelectActivityEducation.checkAndPerformedSelectDatabaseEducation(
browseButtonView!!,
{tapTargetView ->
openDatabaseButtonView!!,
{ tapTargetView ->
tapTargetView?.let {
mOpenFileHelper?.openFileOnClickViewListener?.onClick(it)
mExternalFileHelper?.openDocument()
}
},
{
fileSelectExpandableButtonView?.let {
fileDatabaseSelectActivityEducation
.checkAndPerformedOpenLinkDatabaseEducation(it)
}
}
{}
)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return MenuUtil.onDefaultMenuOptionsItemSelected(this, item) && super.onOptionsItemSelected(item)
when (item.itemId) {
android.R.id.home -> UriUtil.gotoUrl(this, R.string.file_manager_explanation_url)
}
MenuUtil.onDefaultMenuOptionsItemSelected(this, item)
return super.onOptionsItemSelected(item)
}
companion object {
@@ -466,22 +432,53 @@ class FileDatabaseSelectActivity : StylishActivity(),
private const val EXTRA_STAY = "EXTRA_STAY"
private const val EXTRA_DATABASE_URI = "EXTRA_DATABASE_URI"
private const val CREATE_FILE_REQUEST_CODE = 3853
/*
* -------------------------
* Standard Launch
* -------------------------
*/
fun launch(context: Context) {
context.startActivity(Intent(context, FileDatabaseSelectActivity::class.java))
}
/*
* -------------------------
* No Standard Launch, pass by PasswordActivity
* Search Launch
* -------------------------
*/
fun launchForSearchResult(context: Context,
searchInfo: SearchInfo) {
EntrySelectionHelper.startActivityForSearchModeResult(context,
Intent(context, FileDatabaseSelectActivity::class.java),
searchInfo)
}
/*
* -------------------------
* Save Launch
* -------------------------
*/
fun launchForSaveResult(context: Context,
searchInfo: SearchInfo) {
EntrySelectionHelper.startActivityForSaveModeResult(context,
Intent(context, FileDatabaseSelectActivity::class.java),
searchInfo)
}
/*
* -------------------------
* Keyboard Launch
* -------------------------
*/
fun launchForKeyboardSelection(activity: Activity) {
EntrySelectionHelper.startActivityForEntrySelection(activity, Intent(activity, FileDatabaseSelectActivity::class.java))
fun launchForKeyboardSelectionResult(activity: Activity,
searchInfo: SearchInfo? = null) {
EntrySelectionHelper.startActivityForKeyboardSelectionModeResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
searchInfo)
}
/*
@@ -491,10 +488,25 @@ class FileDatabaseSelectActivity : StylishActivity(),
*/
@RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity, assistStructure: AssistStructure) {
fun launchForAutofillResult(activity: Activity,
autofillComponent: AutofillComponent,
searchInfo: SearchInfo? = null) {
AutofillHelper.startActivityForAutofillResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
assistStructure)
autofillComponent,
searchInfo)
}
/*
* -------------------------
* Registration Launch
* -------------------------
*/
fun launchForRegistration(context: Context,
registerInfo: RegisterInfo? = null) {
EntrySelectionHelper.startActivityForRegistrationModeResult(context,
Intent(context, FileDatabaseSelectActivity::class.java),
registerInfo)
}
}
}

View File

@@ -0,0 +1,324 @@
/*
* 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 android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.commit
import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.fragments.IconPickerFragment
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.BinaryDatabaseManager
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.updateLockPaddingLeft
import com.kunzisoft.keepass.viewmodels.IconPickerViewModel
import kotlinx.coroutines.*
class IconPickerActivity : LockingActivity() {
private lateinit var toolbar: Toolbar
private lateinit var coordinatorLayout: CoordinatorLayout
private lateinit var uploadButton: View
private var lockView: View? = null
private var mIconImage: IconImage = IconImage()
private val mainScope = CoroutineScope(Dispatchers.Main)
private val iconPickerViewModel: IconPickerViewModel by viewModels()
private var mCustomIconsSelectionMode = false
private var mIconsSelected: List<IconImageCustom> = ArrayList()
private var mDatabase: Database? = null
private var mExternalFileHelper: ExternalFileHelper? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_icon_picker)
mDatabase = Database.getInstance()
toolbar = findViewById(R.id.toolbar)
toolbar.title = " "
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
updateIconsSelectedViews()
coordinatorLayout = findViewById(R.id.icon_picker_coordinator)
mExternalFileHelper = ExternalFileHelper(this)
uploadButton = findViewById(R.id.icon_picker_upload)
if (mDatabase?.allowCustomIcons == true) {
uploadButton.setOpenDocumentClickListener(mExternalFileHelper)
} else {
uploadButton.visibility = View.GONE
}
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
lockAndExit()
}
intent?.getParcelableExtra<IconImage>(EXTRA_ICON)?.let {
mIconImage = it
}
if (savedInstanceState == null) {
supportFragmentManager.commit {
setReorderingAllowed(true)
add(R.id.icon_picker_fragment, IconPickerFragment.getInstance(
// Default selection tab
if (mIconImage.custom.isUnknown)
IconPickerFragment.IconTab.STANDARD
else
IconPickerFragment.IconTab.CUSTOM
), ICON_PICKER_FRAGMENT_TAG)
}
} else {
mIconImage = savedInstanceState.getParcelable(EXTRA_ICON) ?: mIconImage
}
// Focus view to reinitialize timeout
findViewById<ViewGroup>(R.id.icon_picker_container)?.resetAppTimeoutWhenViewFocusedOrChanged(this)
iconPickerViewModel.standardIconPicked.observe(this) { iconStandard ->
mIconImage.standard = iconStandard
// Remove the custom icon if a standard one is selected
mIconImage.custom = IconImageCustom()
setResult()
finish()
}
iconPickerViewModel.customIconPicked.observe(this) { iconCustom ->
// Keep the standard icon if a custom one is selected
mIconImage.custom = iconCustom
setResult()
finish()
}
iconPickerViewModel.customIconsSelected.observe(this) { iconsSelected ->
mIconsSelected = iconsSelected
updateIconsSelectedViews()
}
iconPickerViewModel.customIconAdded.observe(this) { iconCustomAdded ->
if (iconCustomAdded.error && !iconCustomAdded.errorConsumed) {
Snackbar.make(coordinatorLayout, iconCustomAdded.errorStringId, Snackbar.LENGTH_LONG).asError().show()
iconCustomAdded.errorConsumed = true
}
uploadButton.isEnabled = true
}
iconPickerViewModel.customIconRemoved.observe(this) { iconCustomRemoved ->
if (iconCustomRemoved.error && !iconCustomRemoved.errorConsumed) {
Snackbar.make(coordinatorLayout, iconCustomRemoved.errorStringId, Snackbar.LENGTH_LONG).asError().show()
iconCustomRemoved.errorConsumed = true
}
uploadButton.isEnabled = true
}
}
private fun updateIconsSelectedViews() {
if (mIconsSelected.isEmpty()) {
mCustomIconsSelectionMode = false
toolbar.title = " "
} else {
mCustomIconsSelectionMode = true
toolbar.title = mIconsSelected.size.toString()
}
invalidateOptionsMenu()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelable(EXTRA_ICON, mIconImage)
}
override fun onResume() {
super.onResume()
// Show the lock button
lockView?.visibility = if (PreferencesUtil.showLockDatabaseButton(this)) {
View.VISIBLE
} else {
View.GONE
}
// Padding if lock button visible
toolbar.updateLockPaddingLeft()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
super.onCreateOptionsMenu(menu)
if (mCustomIconsSelectionMode) {
menuInflater.inflate(R.menu.icon, menu)
}
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
if (mCustomIconsSelectionMode) {
iconPickerViewModel.deselectAllCustomIcons()
} else {
onBackPressed()
}
}
R.id.menu_delete -> {
mIconsSelected.forEach { iconToRemove ->
removeCustomIcon(iconToRemove)
}
}
}
return super.onOptionsItemSelected(item)
}
private fun addCustomIcon(iconToUploadUri: Uri?) {
uploadButton.isEnabled = false
mainScope.launch {
withContext(Dispatchers.IO) {
// on Progress with thread
val asyncResult: Deferred<IconPickerViewModel.IconCustomState?> = async {
val iconCustomState = IconPickerViewModel.IconCustomState(null, true, R.string.error_upload_file)
UriUtil.getFileData(this@IconPickerActivity, iconToUploadUri)?.also { documentFile ->
if (documentFile.length() > MAX_ICON_SIZE) {
iconCustomState.errorStringId = R.string.error_file_to_big
} else {
mDatabase?.buildNewCustomIcon { customIcon, binary ->
if (customIcon != null) {
iconCustomState.iconCustom = customIcon
mDatabase?.let { database ->
BinaryDatabaseManager.resizeBitmapAndStoreDataInBinaryFile(
contentResolver,
database,
iconToUploadUri,
binary)
when {
binary == null -> {
}
binary.getSize() <= 0 -> {
}
database.isCustomIconBinaryDuplicate(binary) -> {
iconCustomState.errorStringId = R.string.error_duplicate_file
}
else -> {
iconCustomState.error = false
}
}
}
if (iconCustomState.error) {
mDatabase?.removeCustomIcon(customIcon)
}
}
}
}
}
iconCustomState
}
withContext(Dispatchers.Main) {
asyncResult.await()?.let { customIcon ->
iconPickerViewModel.addCustomIcon(customIcon)
}
}
}
}
}
private fun removeCustomIcon(iconImageCustom: IconImageCustom) {
uploadButton.isEnabled = false
iconPickerViewModel.deselectAllCustomIcons()
mDatabase?.removeCustomIcon(iconImageCustom)
iconPickerViewModel.removeCustomIcon(
IconPickerViewModel.IconCustomState(iconImageCustom, false, R.string.error_remove_file)
)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
addCustomIcon(uri)
}
}
private fun setResult() {
setResult(Activity.RESULT_OK, Intent().apply {
putExtra(EXTRA_ICON, mIconImage)
})
}
override fun onBackPressed() {
setResult()
super.onBackPressed()
}
companion object {
private const val ICON_PICKER_FRAGMENT_TAG = "ICON_PICKER_FRAGMENT_TAG"
private const val ICON_SELECTED_REQUEST = 15861
private const val EXTRA_ICON = "EXTRA_ICON"
private const val MAX_ICON_SIZE = 5242880
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?, listener: (icon: IconImage) -> Unit) {
if (requestCode == ICON_SELECTED_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
listener.invoke(data?.getParcelableExtra(EXTRA_ICON) ?: IconImage())
}
}
}
fun launch(context: Activity,
previousIcon: IconImage?) {
// Create an instance to return the picker icon
context.startActivityForResult(
Intent(context,
IconPickerActivity::class.java).apply {
if (previousIcon != null)
putExtra(EXTRA_ICON, previousIcon)
},
ICON_SELECTED_REQUEST)
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright 2021 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.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.format.Formatter
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.widget.Toolbar
import com.igreenwood.loupe.Loupe
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.tasks.BinaryDatabaseManager
import kotlin.math.max
class ImageViewerActivity : LockingActivity() {
private var mDatabase: Database? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_image_viewer)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
val imageContainerView: ViewGroup = findViewById(R.id.image_viewer_container)
val imageView: ImageView = findViewById(R.id.image_viewer_image)
val progressView: View = findViewById(R.id.image_viewer_progress)
// Approximately, to not OOM and allow a zoom
val mImagePreviewMaxWidth = max(
resources.displayMetrics.widthPixels * 2,
resources.displayMetrics.heightPixels * 2
)
mDatabase = Database.getInstance()
try {
progressView.visibility = View.VISIBLE
intent.getParcelableExtra<Attachment>(IMAGE_ATTACHMENT_TAG)?.let { attachment ->
supportActionBar?.title = attachment.name
val size = attachment.binaryData.getSize()
supportActionBar?.subtitle = Formatter.formatFileSize(this, size)
mDatabase?.let { database ->
BinaryDatabaseManager.loadBitmap(
database,
attachment.binaryData,
mImagePreviewMaxWidth
) { bitmapLoaded ->
if (bitmapLoaded == null) {
finish()
} else {
progressView.visibility = View.GONE
imageView.setImageBitmap(bitmapLoaded)
}
}
}
} ?: finish()
} catch (e: Exception) {
Log.e(TAG, "Unable to view the binary", e)
finish()
}
Loupe.create(imageView, imageContainerView) {
onViewTranslateListener = object : Loupe.OnViewTranslateListener {
override fun onStart(view: ImageView) {
// called when the view starts moving
}
override fun onViewTranslate(view: ImageView, amount: Float) {
// called whenever the view position changed
}
override fun onRestore(view: ImageView) {
// called when the view drag gesture ended
}
override fun onDismiss(view: ImageView) {
// called when the view drag gesture ended
finish()
}
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> finish()
}
return super.onOptionsItemSelected(item)
}
companion object {
private val TAG = ImageViewerActivity::class.simpleName
private const val IMAGE_ATTACHMENT_TAG = "IMAGE_ATTACHMENT_TAG"
fun getInstance(context: Context, imageAttachment: Attachment) {
context.startActivity(Intent(context, ImageViewerActivity::class.java).apply {
putExtra(IMAGE_ATTACHMENT_TAG, imageAttachment)
})
}
}
}

View File

@@ -1,305 +0,0 @@
package com.kunzisoft.keepass.activities
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.adapters.NodeAdapter
import com.kunzisoft.keepass.database.SortNodeEnum
import com.kunzisoft.keepass.database.element.GroupVersioned
import com.kunzisoft.keepass.database.element.NodeVersioned
import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.activities.stylish.StylishFragment
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.database.element.Database
class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionListener {
private var nodeClickCallback: NodeAdapter.NodeClickCallback? = null
private var nodeMenuListener: NodeAdapter.NodeMenuListener? = null
private var onScrollListener: OnScrollListener? = null
private var listView: RecyclerView? = null
var mainGroup: GroupVersioned? = null
private set
private var mAdapter: NodeAdapter? = null
private var notFoundView: View? = null
private var isASearchResult: Boolean = false
// Preferences for sorting
private var prefs: SharedPreferences? = null
private var readOnly: Boolean = false
get() {
return field || selectionMode
}
private var selectionMode: Boolean = false
val isEmpty: Boolean
get() = mAdapter == null || mAdapter?.itemCount?:0 <= 0
override fun onAttach(context: Context) {
super.onAttach(context)
try {
nodeClickCallback = context as NodeAdapter.NodeClickCallback
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + NodeAdapter.NodeClickCallback::class.java.name)
}
try {
nodeMenuListener = context as NodeAdapter.NodeMenuListener
} catch (e: ClassCastException) {
nodeMenuListener = null
// Context menu can be omit
Log.w(TAG, context.toString()
+ " must implement " + NodeAdapter.NodeMenuListener::class.java.name)
}
try {
onScrollListener = context as OnScrollListener
} catch (e: ClassCastException) {
onScrollListener = null
// Context menu can be omit
Log.w(TAG, context.toString()
+ " must implement " + RecyclerView.OnScrollListener::class.java.name)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.let { currentActivity ->
setHasOptionsMenu(true)
readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrArguments(savedInstanceState, arguments)
arguments?.let { args ->
// Contains all the group in element
if (args.containsKey(GROUP_KEY)) {
mainGroup = args.getParcelable(GROUP_KEY)
}
if (args.containsKey(IS_SEARCH)) {
isASearchResult = args.getBoolean(IS_SEARCH)
}
}
contextThemed?.let { context ->
mAdapter = NodeAdapter(context, currentActivity.menuInflater)
mAdapter?.apply {
setReadOnly(readOnly)
setIsASearchResult(isASearchResult)
setOnNodeClickListener(nodeClickCallback)
setActivateContextMenu(true)
setNodeMenuListener(nodeMenuListener)
}
}
prefs = PreferenceManager.getDefaultSharedPreferences(context)
}
}
override fun onSaveInstanceState(outState: Bundle) {
ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
super.onSaveInstanceState(outState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
// To apply theme
val rootView = inflater.cloneInContext(contextThemed)
.inflate(R.layout.fragment_list_nodes, container, false)
listView = rootView.findViewById(R.id.nodes_list)
notFoundView = rootView.findViewById(R.id.not_found_container)
onScrollListener?.let { onScrollListener ->
listView?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
onScrollListener.onScrolled(dy)
}
})
}
rebuildList()
return rootView
}
override fun onResume() {
super.onResume()
activity?.intent?.let {
selectionMode = EntrySelectionHelper.retrieveEntrySelectionModeFromIntent(it)
}
// Force read only mode if selection mode
mAdapter?.apply {
setReadOnly(readOnly)
}
// Refresh data
mAdapter?.notifyDataSetChanged()
if (isASearchResult && mAdapter!= null && mAdapter!!.isEmpty) {
// To show the " no search entry found "
listView?.visibility = View.GONE
notFoundView?.visibility = View.VISIBLE
} else {
listView?.visibility = View.VISIBLE
notFoundView?.visibility = View.GONE
}
}
fun rebuildList() {
// Add elements to the list
mainGroup?.let { mainGroup ->
mAdapter?.rebuildList(mainGroup)
}
listView?.apply {
scrollBarStyle = View.SCROLLBARS_INSIDE_INSET
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
}
}
override fun onSortSelected(sortNodeEnum: SortNodeEnum, ascending: Boolean, groupsBefore: Boolean, recycleBinBottom: Boolean) {
// Toggle setting
prefs?.edit()?.apply {
putString(getString(R.string.sort_node_key), sortNodeEnum.name)
putBoolean(getString(R.string.sort_ascending_key), ascending)
putBoolean(getString(R.string.sort_group_before_key), groupsBefore)
putBoolean(getString(R.string.sort_recycle_bin_bottom_key), recycleBinBottom)
apply()
}
// Tell the adapter to refresh it's list
mAdapter?.notifyChangeSort(sortNodeEnum, ascending, groupsBefore)
mainGroup?.let { mainGroup ->
mAdapter?.rebuildList(mainGroup)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.tree, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_sort -> {
context?.let { context ->
val sortDialogFragment: SortDialogFragment =
if (Database.getInstance().isRecycleBinAvailable
&& Database.getInstance().isRecycleBinEnabled) {
SortDialogFragment.getInstance(
PreferencesUtil.getListSort(context),
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context),
PreferencesUtil.getRecycleBinBottomSort(context))
} else {
SortDialogFragment.getInstance(
PreferencesUtil.getListSort(context),
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context))
}
sortDialogFragment.show(childFragmentManager, "sortDialog")
}
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE -> {
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE
|| resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) {
data?.getParcelableExtra<NodeVersioned>(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY)?.let { newNode ->
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE)
mAdapter?.addNode(newNode)
if (resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) {
//mAdapter.updateLastNodeRegister(newNode);
mainGroup?.let { mainGroup ->
mAdapter?.rebuildList(mainGroup)
}
}
} ?: Log.e(this.javaClass.name, "New node can be retrieve in Activity Result")
}
}
}
}
fun contains(node: NodeVersioned): Boolean {
return mAdapter?.contains(node) ?: false
}
fun addNode(newNode: NodeVersioned) {
mAdapter?.addNode(newNode)
}
fun updateNode(oldNode: NodeVersioned, newNode: NodeVersioned? = null) {
mAdapter?.updateNode(oldNode, newNode ?: oldNode)
}
fun removeNode(pwNode: NodeVersioned) {
mAdapter?.removeNode(pwNode)
}
fun removeNodeAt(position: Int) {
mAdapter?.removeNodeAt(position)
}
interface OnScrollListener {
/**
* Callback method to be invoked when the RecyclerView has been scrolled. This will be
* called after the scroll has completed.
*
* @param dy The amount of vertical scroll.
*/
fun onScrolled(dy: Int)
}
companion object {
private val TAG = ListNodesFragment::class.java.name
private const val GROUP_KEY = "GROUP_KEY"
private const val IS_SEARCH = "IS_SEARCH"
fun newInstance(group: GroupVersioned?, readOnly: Boolean, isASearch: Boolean): ListNodesFragment {
val bundle = Bundle()
if (group != null) {
bundle.putParcelable(GROUP_KEY, group)
}
bundle.putBoolean(IS_SEARCH, isASearch)
ReadOnlyHelper.putReadOnlyInBundle(bundle, readOnly)
val listNodesFragment = ListNodesFragment()
listNodesFragment.arguments = bundle
return listNodesFragment
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* 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.activities
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
/**
* Activity to select entry in database and populate it in Magikeyboard
*/
class MagikeyboardLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val database = Database.getInstance()
val readOnly = database.isReadOnly
SearchHelper.checkAutoSearchInfo(this,
database,
null,
{
// Not called
// if items found directly returns before calling this activity
},
{
// Select if not found
GroupActivity.launchForKeyboardSelectionResult(this, readOnly)
},
{
// Pass extra to get entry
FileDatabaseSelectActivity.launchForKeyboardSelectionResult(this)
}
)
finish()
super.onCreate(savedInstanceState)
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -25,17 +25,21 @@ import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import com.google.android.material.textfield.TextInputLayout
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.text.Editable
import android.text.SpannableStringBuilder
import android.text.TextWatcher
import android.view.View
import android.widget.CompoundButton
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.OpenFileHelper
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
import com.kunzisoft.keepass.model.MainCredential
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.view.KeyFileSelectionView
class AssignMasterKeyDialogFragment : DialogFragment() {
@@ -45,17 +49,22 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
private var rootView: View? = null
private var passwordCheckBox: CompoundButton? = null
private var passwordTextInputLayout: TextInputLayout? = null
private var passwordView: TextView? = null
private var passwordRepeatTextInputLayout: TextInputLayout? = null
private var passwordRepeatView: TextView? = null
private var keyFileTextInputLayout: TextInputLayout? = null
private var keyFileCheckBox: CompoundButton? = null
private var keyFileView: TextView? = null
private var keyFileSelectionView: KeyFileSelectionView? = null
private var mListener: AssignPasswordDialogListener? = null
private var mOpenFileHelper: OpenFileHelper? = null
private var mExternalFileHelper: ExternalFileHelper? = null
private var mEmptyPasswordConfirmationDialog: AlertDialog? = null
private var mNoKeyConfirmationDialog: AlertDialog? = null
private var mEmptyKeyFileConfirmationDialog: AlertDialog? = null
private val passwordTextWatcher = object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
@@ -67,21 +76,9 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
}
}
private val keyFileTextWatcher = object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
keyFileCheckBox?.isChecked = true
}
}
interface AssignPasswordDialogListener {
fun onAssignKeyDialogPositiveClick(masterPasswordChecked: Boolean, masterPassword: String?,
keyFileChecked: Boolean, keyFile: Uri?)
fun onAssignKeyDialogNegativeClick(masterPasswordChecked: Boolean, masterPassword: String?,
keyFileChecked: Boolean, keyFile: Uri?)
fun onAssignKeyDialogPositiveClick(mainCredential: MainCredential)
fun onAssignKeyDialogNegativeClick(mainCredential: MainCredential)
}
override fun onAttach(activity: Context) {
@@ -94,30 +91,50 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
}
}
override fun onDetach() {
mListener = null
mEmptyPasswordConfirmationDialog?.dismiss()
mEmptyPasswordConfirmationDialog = null
mNoKeyConfirmationDialog?.dismiss()
mNoKeyConfirmationDialog = null
mEmptyKeyFileConfirmationDialog?.dismiss()
mEmptyKeyFileConfirmationDialog = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
var allowNoMasterKey = false
arguments?.apply {
if (containsKey(ALLOW_NO_MASTER_KEY_ARG))
allowNoMasterKey = getBoolean(ALLOW_NO_MASTER_KEY_ARG, false)
}
val builder = AlertDialog.Builder(activity)
val inflater = activity.layoutInflater
rootView = inflater.inflate(R.layout.fragment_set_password, null)
builder.setView(rootView)
.setTitle(R.string.assign_master_key)
// Add action buttons
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setNegativeButton(R.string.cancel) { _, _ -> }
.setNegativeButton(android.R.string.cancel) { _, _ -> }
rootView?.findViewById<View>(R.id.credentials_information)?.setOnClickListener {
UriUtil.gotoUrl(activity, R.string.credentials_explanation_url)
}
passwordCheckBox = rootView?.findViewById(R.id.password_checkbox)
passwordTextInputLayout = rootView?.findViewById(R.id.password_input_layout)
passwordView = rootView?.findViewById(R.id.pass_password)
passwordRepeatTextInputLayout = rootView?.findViewById(R.id.password_repeat_input_layout)
passwordRepeatView = rootView?.findViewById(R.id.pass_conf_password)
keyFileTextInputLayout = rootView?.findViewById(R.id.keyfile_input_layout)
keyFileCheckBox = rootView?.findViewById(R.id.keyfile_checkox)
keyFileView = rootView?.findViewById(R.id.pass_keyfile)
keyFileSelectionView = rootView?.findViewById(R.id.keyfile_selection)
mOpenFileHelper = OpenFileHelper(this)
rootView?.findViewById<View>(R.id.browse_button)?.setOnClickListener { view ->
mOpenFileHelper?.openFileOnClickViewListener?.onClick(view) }
mExternalFileHelper = ExternalFileHelper(this)
keyFileSelectionView?.setOpenDocumentClickListener(mExternalFileHelper)
val dialog = builder.create()
@@ -129,23 +146,23 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
mMasterPassword = ""
mKeyFile = null
var error = verifyPassword() || verifyFile()
var error = verifyPassword() || verifyKeyFile()
if (!passwordCheckBox!!.isChecked && !keyFileCheckBox!!.isChecked) {
error = true
showNoKeyConfirmationDialog()
if (allowNoMasterKey)
showNoKeyConfirmationDialog()
else {
passwordTextInputLayout?.error = getString(R.string.error_disallow_no_credentials)
}
}
if (!error) {
mListener?.onAssignKeyDialogPositiveClick(
passwordCheckBox!!.isChecked, mMasterPassword,
keyFileCheckBox!!.isChecked, mKeyFile)
mListener?.onAssignKeyDialogPositiveClick(retrieveMainCredential())
dismiss()
}
}
val negativeButton = dialog1.getButton(DialogInterface.BUTTON_NEGATIVE)
negativeButton.setOnClickListener {
mListener?.onAssignKeyDialogNegativeClick(
passwordCheckBox!!.isChecked, mMasterPassword,
keyFileCheckBox!!.isChecked, mKeyFile)
mListener?.onAssignKeyDialogNegativeClick(retrieveMainCredential())
dismiss()
}
}
@@ -157,19 +174,23 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
return super.onCreateDialog(savedInstanceState)
}
private fun retrieveMainCredential(): MainCredential {
val masterPassword = if (passwordCheckBox!!.isChecked) mMasterPassword else null
val keyFile = if (keyFileCheckBox!!.isChecked) mKeyFile else null
return MainCredential(masterPassword, keyFile)
}
override fun onResume() {
super.onResume()
// To check checkboxes if a text is present
passwordView?.addTextChangedListener(passwordTextWatcher)
keyFileView?.addTextChangedListener(keyFileTextWatcher)
}
override fun onPause() {
super.onPause()
passwordView?.removeTextChangedListener(passwordTextWatcher)
keyFileView?.removeTextChangedListener(keyFileTextWatcher)
}
private fun verifyPassword(): Boolean {
@@ -193,19 +214,20 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
showEmptyPasswordConfirmationDialog()
}
}
return error
}
private fun verifyFile(): Boolean {
private fun verifyKeyFile(): Boolean {
var error = false
if (keyFileCheckBox != null
&& keyFileCheckBox!!.isChecked) {
UriUtil.parse(keyFileView?.text?.toString())?.let { uri ->
keyFileSelectionView?.uri?.let { uri ->
mKeyFile = uri
} ?: run {
error = true
keyFileTextInputLayout?.error = getString(R.string.error_nokeyfile)
keyFileSelectionView?.error = getString(R.string.error_nokeyfile)
}
}
return error
@@ -216,15 +238,14 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
val builder = AlertDialog.Builder(it)
builder.setMessage(R.string.warning_empty_password)
.setPositiveButton(android.R.string.ok) { _, _ ->
if (!verifyFile()) {
mListener?.onAssignKeyDialogPositiveClick(
passwordCheckBox!!.isChecked, mMasterPassword,
keyFileCheckBox!!.isChecked, mKeyFile)
if (!verifyKeyFile()) {
mListener?.onAssignKeyDialogPositiveClick(retrieveMainCredential())
this@AssignMasterKeyDialogFragment.dismiss()
}
}
.setNegativeButton(R.string.cancel) { _, _ -> }
builder.create().show()
.setNegativeButton(android.R.string.cancel) { _, _ -> }
mEmptyPasswordConfirmationDialog = builder.create()
mEmptyPasswordConfirmationDialog?.show()
}
}
@@ -233,26 +254,62 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
val builder = AlertDialog.Builder(it)
builder.setMessage(R.string.warning_no_encryption_key)
.setPositiveButton(android.R.string.ok) { _, _ ->
mListener?.onAssignKeyDialogPositiveClick(
passwordCheckBox!!.isChecked, mMasterPassword,
keyFileCheckBox!!.isChecked, mKeyFile)
mListener?.onAssignKeyDialogPositiveClick(retrieveMainCredential())
this@AssignMasterKeyDialogFragment.dismiss()
}
.setNegativeButton(R.string.cancel) { _, _ -> }
builder.create().show()
.setNegativeButton(android.R.string.cancel) { _, _ -> }
mNoKeyConfirmationDialog = builder.create()
mNoKeyConfirmationDialog?.show()
}
}
private fun showEmptyKeyFileConfirmationDialog() {
activity?.let {
val builder = AlertDialog.Builder(it)
builder.setMessage(SpannableStringBuilder().apply {
append(getString(R.string.warning_empty_keyfile))
append("\n\n")
append(getString(R.string.warning_empty_keyfile_explanation))
append("\n\n")
append(getString(R.string.warning_sure_add_file))
})
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setNegativeButton(android.R.string.cancel) { _, _ ->
keyFileCheckBox?.isChecked = false
keyFileSelectionView?.uri = null
}
mEmptyKeyFileConfirmationDialog = builder.create()
mEmptyKeyFileConfirmationDialog?.show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
mOpenFileHelper?.onActivityResultCallback(requestCode, resultCode, data
) { uri ->
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
uri?.let { pathUri ->
keyFileCheckBox?.isChecked = true
keyFileView?.text = pathUri.toString()
UriUtil.getFileData(requireContext(), uri)?.length()?.let { lengthFile ->
keyFileSelectionView?.error = null
keyFileCheckBox?.isChecked = true
keyFileSelectionView?.uri = pathUri
if (lengthFile <= 0L) {
showEmptyKeyFileConfirmationDialog()
}
}
}
}
}
companion object {
private const val ALLOW_NO_MASTER_KEY_ARG = "ALLOW_NO_MASTER_KEY_ARG"
fun getInstance(allowNoMasterKey: Boolean): AssignMasterKeyDialogFragment {
val fragment = AssignMasterKeyDialogFragment()
val args = Bundle()
args.putBoolean(ALLOW_NO_MASTER_KEY_ARG, allowNoMasterKey)
fragment.arguments = args
return fragment
}
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.activities.dialogs
import android.app.Dialog
import android.os.Bundle
import android.text.SpannableStringBuilder
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
class DatabaseChangedDialogFragment : DialogFragment() {
var actionDatabaseListener: ActionDatabaseChangedListener? = null
override fun onPause() {
super.onPause()
actionDatabaseListener = null
this.dismiss()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val oldSnapFileDatabaseInfo: SnapFileDatabaseInfo? = arguments?.getParcelable(OLD_FILE_DATABASE_INFO)
val newSnapFileDatabaseInfo: SnapFileDatabaseInfo? = arguments?.getParcelable(NEW_FILE_DATABASE_INFO)
if (oldSnapFileDatabaseInfo != null && newSnapFileDatabaseInfo != null) {
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(activity)
val stringBuilder = SpannableStringBuilder()
if (newSnapFileDatabaseInfo.exists) {
stringBuilder.append(getString(R.string.warning_database_info_changed))
stringBuilder.append("\n\n" +oldSnapFileDatabaseInfo.toString(activity)
+ "\n\n" +
newSnapFileDatabaseInfo.toString(activity) + "\n\n")
stringBuilder.append(getString(R.string.warning_database_info_changed_options))
} else {
stringBuilder.append(getString(R.string.warning_database_revoked))
}
builder.setMessage(stringBuilder)
builder.setPositiveButton(android.R.string.ok) { _, _ ->
actionDatabaseListener?.validateDatabaseChanged()
}
return builder.create()
}
}
return super.onCreateDialog(savedInstanceState)
}
interface ActionDatabaseChangedListener {
fun validateDatabaseChanged()
}
companion object {
const val DATABASE_CHANGED_DIALOG_TAG = "databaseChangedDialogFragment"
private const val OLD_FILE_DATABASE_INFO = "OLD_FILE_DATABASE_INFO"
private const val NEW_FILE_DATABASE_INFO = "NEW_FILE_DATABASE_INFO"
fun getInstance(oldSnapFileDatabaseInfo: SnapFileDatabaseInfo,
newSnapFileDatabaseInfo: SnapFileDatabaseInfo)
: DatabaseChangedDialogFragment {
val fragment = DatabaseChangedDialogFragment()
fragment.arguments = Bundle().apply {
putParcelable(OLD_FILE_DATABASE_INFO, oldSnapFileDatabaseInfo)
putParcelable(NEW_FILE_DATABASE_INFO, newSnapFileDatabaseInfo)
}
return fragment
}
}
}

View File

@@ -0,0 +1,66 @@
package com.kunzisoft.keepass.activities.dialogs
import android.app.DatePickerDialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.DialogFragment
class DatePickerFragment : DialogFragment() {
private var mDefaultYear: Int = 2000
private var mDefaultMonth: Int = 1
private var mDefaultDay: Int = 1
private var mListener: DatePickerDialog.OnDateSetListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
mListener = context as DatePickerDialog.OnDateSetListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + DatePickerDialog.OnDateSetListener::class.java.name)
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Create a new instance of DatePickerDialog and return it
return context?.let {
arguments?.apply {
if (containsKey(DEFAULT_YEAR_BUNDLE_KEY))
mDefaultYear = getInt(DEFAULT_YEAR_BUNDLE_KEY)
if (containsKey(DEFAULT_MONTH_BUNDLE_KEY))
mDefaultMonth = getInt(DEFAULT_MONTH_BUNDLE_KEY)
if (containsKey(DEFAULT_DAY_BUNDLE_KEY))
mDefaultDay = getInt(DEFAULT_DAY_BUNDLE_KEY)
}
DatePickerDialog(it, mListener, mDefaultYear, mDefaultMonth, mDefaultDay)
} ?: super.onCreateDialog(savedInstanceState)
}
companion object {
private const val DEFAULT_YEAR_BUNDLE_KEY = "DEFAULT_YEAR_BUNDLE_KEY"
private const val DEFAULT_MONTH_BUNDLE_KEY = "DEFAULT_MONTH_BUNDLE_KEY"
private const val DEFAULT_DAY_BUNDLE_KEY = "DEFAULT_DAY_BUNDLE_KEY"
fun getInstance(defaultYear: Int,
defaultMonth: Int,
defaultDay: Int): DatePickerFragment {
return DatePickerFragment().apply {
arguments = Bundle().apply {
putInt(DEFAULT_YEAR_BUNDLE_KEY, defaultYear)
putInt(DEFAULT_MONTH_BUNDLE_KEY, defaultMonth)
putInt(DEFAULT_DAY_BUNDLE_KEY, defaultDay)
}
}
}
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.node.Node
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.getBundleFromListNodes
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.getListNodesFromBundle
open class DeleteNodesDialogFragment : DialogFragment() {
private var mNodesToDelete: List<Node> = ArrayList()
private var mListener: DeleteNodeListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
mListener = context as DeleteNodeListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + DeleteNodeListener::class.java.name)
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
protected open fun retrieveMessage(): String {
return getString(R.string.warning_permanently_delete_nodes)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
arguments?.apply {
if (containsKey(DatabaseTaskNotificationService.GROUPS_ID_KEY)
&& containsKey(DatabaseTaskNotificationService.ENTRIES_ID_KEY)) {
mNodesToDelete = getListNodesFromBundle(Database.getInstance(), this)
}
} ?: savedInstanceState?.apply {
if (containsKey(DatabaseTaskNotificationService.GROUPS_ID_KEY)
&& containsKey(DatabaseTaskNotificationService.ENTRIES_ID_KEY)) {
mNodesToDelete = getListNodesFromBundle(Database.getInstance(), savedInstanceState)
}
}
activity?.let { activity ->
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(activity)
builder.setMessage(retrieveMessage())
builder.setPositiveButton(android.R.string.ok) { _, _ ->
mListener?.permanentlyDeleteNodes(mNodesToDelete)
}
builder.setNegativeButton(android.R.string.cancel) { _, _ -> dismiss() }
// Create the AlertDialog object and return it
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putAll(getBundleFromListNodes(mNodesToDelete))
}
interface DeleteNodeListener {
fun permanentlyDeleteNodes(nodes: List<Node>)
}
companion object {
fun getInstance(nodesToDelete: List<Node>): DeleteNodesDialogFragment {
return DeleteNodesDialogFragment().apply {
arguments = getBundleFromListNodes(nodesToDelete)
}
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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.dialogs
import android.app.Dialog
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
class DuplicateUuidDialog : DialogFragment() {
var positiveAction: (() -> Unit)? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(activity).apply {
val message = getString(R.string.contains_duplicate_uuid) +
"\n\n" + getString(R.string.contains_duplicate_uuid_procedure)
setMessage(message)
setPositiveButton(getString(android.R.string.ok)) { _, _ ->
positiveAction?.invoke()
dismiss()
}
setNegativeButton(getString(android.R.string.cancel)) { _, _ -> dismiss() }
}
// Create the AlertDialog object and return it
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
override fun onPause() {
super.onPause()
this.dismiss()
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.activities.dialogs
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.node.Node
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.getBundleFromListNodes
class EmptyRecycleBinDialogFragment : DeleteNodesDialogFragment() {
override fun retrieveMessage(): String {
return getString(R.string.warning_empty_recycle_bin)
}
companion object {
fun getInstance(nodesToDelete: List<Node>): EmptyRecycleBinDialogFragment {
return EmptyRecycleBinDialogFragment().apply {
arguments = getBundleFromListNodes(nodesToDelete)
}
}
}
}

View File

@@ -0,0 +1,182 @@
/*
* 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.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.CompoundButton
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.security.ProtectedString
import com.kunzisoft.keepass.model.Field
class EntryCustomFieldDialogFragment: DialogFragment() {
private var oldField: Field? = null
private var entryCustomFieldListener: EntryCustomFieldListener? = null
private var customFieldLabelContainer: TextInputLayout? = null
private var customFieldLabel: TextView? = null
private var customFieldDeleteButton: ImageView? = null
private var customFieldProtectionButton: CompoundButton? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
entryCustomFieldListener = context as EntryCustomFieldListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + EntryCustomFieldListener::class.java.name)
}
}
override fun onDetach() {
entryCustomFieldListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val root = activity.layoutInflater.inflate(R.layout.fragment_entry_new_field, null)
customFieldLabelContainer = root?.findViewById(R.id.entry_custom_field_label_container)
customFieldLabel = root?.findViewById(R.id.entry_custom_field_label)
customFieldDeleteButton = root?.findViewById(R.id.entry_custom_field_delete)
customFieldProtectionButton = root?.findViewById(R.id.entry_custom_field_protection)
oldField = arguments?.getParcelable(KEY_FIELD)
oldField?.let { oldCustomField ->
customFieldLabel?.text = oldCustomField.name
customFieldProtectionButton?.isChecked = oldCustomField.protectedValue.isProtected
customFieldDeleteButton?.visibility = View.VISIBLE
customFieldDeleteButton?.setOnClickListener {
entryCustomFieldListener?.onDeleteCustomFieldApproved(oldCustomField)
(dialog as AlertDialog?)?.dismiss()
}
} ?: run {
customFieldDeleteButton?.visibility = View.GONE
}
val builder = AlertDialog.Builder(activity)
builder.setView(root)
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(android.R.string.cancel) { _, _ -> }
val dialogCreated = builder.create()
customFieldLabel?.requestFocus()
customFieldLabel?.imeOptions = EditorInfo.IME_ACTION_DONE
customFieldLabel?.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
approveIfValid()
}
false
}
dialogCreated.window?.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE)
return dialogCreated
}
return super.onCreateDialog(savedInstanceState)
}
override fun onResume() {
super.onResume()
// To prevent auto dismiss
val d = dialog as AlertDialog?
if (d != null) {
val positiveButton = d.getButton(Dialog.BUTTON_POSITIVE) as Button
positiveButton.setOnClickListener {
approveIfValid()
}
}
}
private fun approveIfValid() {
if (isValid()) {
oldField?.let {
// New property with old value
entryCustomFieldListener?.onEditCustomFieldApproved(it,
Field(customFieldLabel?.text?.toString() ?: "",
ProtectedString(customFieldProtectionButton?.isChecked == true,
it.protectedValue.stringValue))
)
} ?: run {
entryCustomFieldListener?.onNewCustomFieldApproved(
Field(customFieldLabel?.text?.toString() ?: "",
ProtectedString(customFieldProtectionButton?.isChecked == true))
)
}
(dialog as AlertDialog?)?.dismiss()
}
}
private fun isValid(): Boolean {
return if (customFieldLabel?.text?.toString()?.isNotEmpty() != true) {
setError(R.string.error_string_key)
false
} else {
setError(null)
true
}
}
fun setError(@StringRes errorId: Int?) {
customFieldLabelContainer?.error = if (errorId == null) null else {
requireContext().getString(errorId)
}
}
interface EntryCustomFieldListener {
fun onNewCustomFieldApproved(newField: Field)
fun onEditCustomFieldApproved(oldField: Field, newField: Field)
fun onDeleteCustomFieldApproved(oldField: Field)
}
companion object {
private const val KEY_FIELD = "KEY_FIELD"
fun getInstance(): EntryCustomFieldDialogFragment {
return EntryCustomFieldDialogFragment()
}
fun getInstance(field: Field): EntryCustomFieldDialogFragment {
return EntryCustomFieldDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_FIELD, field)
}
}
}
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -28,7 +28,7 @@ import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.utils.UriUtil
class BrowserDialogFragment : DialogFragment() {
class FileManagerDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
@@ -36,20 +36,13 @@ class BrowserDialogFragment : DialogFragment() {
// Get the layout inflater
val root = activity.layoutInflater.inflate(R.layout.fragment_browser_install, null)
builder.setView(root)
.setNegativeButton(R.string.cancel) { _, _ -> }
.setNegativeButton(android.R.string.cancel) { _, _ -> }
val textDescription = root.findViewById<TextView>(R.id.file_manager_install_description)
textDescription.text = getString(R.string.file_manager_install_description)
val market = root.findViewById<Button>(R.id.file_manager_install_play_store)
market.setOnClickListener {
UriUtil.gotoUrl(context!!, R.string.file_manager_play_store)
dismiss()
}
val web = root.findViewById<Button>(R.id.file_manager_install_f_droid)
web.setOnClickListener {
UriUtil.gotoUrl(context!!, R.string.file_manager_f_droid)
root.findViewById<Button>(R.id.file_manager_button).setOnClickListener {
UriUtil.gotoUrl(requireContext(), R.string.file_manager_explanation_url)
dismiss()
}

View File

@@ -0,0 +1,97 @@
/*
* 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.dialogs
import android.app.Dialog
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.text.SpannableStringBuilder
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
/**
* Custom Dialog to confirm big file to upload
*/
class FileTooBigDialogFragment : DialogFragment() {
private var mActionChooseListener: ActionChooseListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
// Verify that the host activity implements the callback interface
try {
mActionChooseListener = context as ActionChooseListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + ActionChooseListener::class.java.name)
}
}
override fun onDetach() {
mActionChooseListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(activity)
builder.setMessage(SpannableStringBuilder().apply {
append(getString(R.string.warning_file_too_big))
append("\n\n")
append(getString(R.string.warning_sure_add_file))
})
builder.setPositiveButton(android.R.string.ok) { _, _ ->
mActionChooseListener?.onValidateUploadFileTooBig(
arguments?.getParcelable(KEY_FILE_URI),
arguments?.getString(KEY_FILE_NAME))
}
builder.setNegativeButton(android.R.string.cancel) { _, _ ->
dismiss()
}
// Create the AlertDialog object and return it
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
interface ActionChooseListener {
fun onValidateUploadFileTooBig(attachmentToUploadUri: Uri?, fileName: String?)
}
companion object {
const val MAX_WARNING_BINARY_FILE = 5242880
private const val KEY_FILE_URI = "KEY_FILE_URI"
private const val KEY_FILE_NAME = "KEY_FILE_NAME"
fun build(attachmentToUploadUri: Uri,
fileName: String): FileTooBigDialogFragment {
val fragment = FileTooBigDialogFragment()
fragment.arguments = Bundle().apply {
putParcelable(KEY_FILE_URI, attachmentToUploadUri)
putString(KEY_FILE_NAME, fileName)
}
return fragment
}
}
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog
import android.content.Intent
import android.os.Build
import android.os.Bundle
import androidx.annotation.RequiresApi
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.view.View
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.biometric.FingerPrintAnimatedVector
import com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity
@RequiresApi(api = Build.VERSION_CODES.M)
class FingerPrintExplanationDialog : DialogFragment() {
private var fingerPrintAnimatedVector: FingerPrintAnimatedVector? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val builder = AlertDialog.Builder(activity)
val inflater = activity.layoutInflater
val rootView = inflater.inflate(R.layout.fragment_fingerprint_explanation, null)
rootView.findViewById<View>(R.id.fingerprint_setting_link_text).setOnClickListener {
startActivity(Intent(android.provider.Settings.ACTION_SECURITY_SETTINGS))
}
rootView.findViewById<View>(R.id.auto_open_biometric_prompt_button).setOnClickListener {
startActivity(Intent(activity, SettingsAdvancedUnlockActivity::class.java))
}
fingerPrintAnimatedVector = FingerPrintAnimatedVector(activity,
rootView.findViewById(R.id.biometric_image))
builder.setView(rootView)
.setPositiveButton(android.R.string.ok) { _, _ -> }
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
override fun onResume() {
super.onResume()
fingerPrintAnimatedVector?.startScan()
}
override fun onPause() {
super.onPause()
fingerPrintAnimatedVector?.stopScan()
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -26,13 +26,11 @@ import com.google.android.material.textfield.TextInputLayout
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.view.View
import android.widget.Button
import android.widget.CompoundButton
import android.widget.EditText
import android.widget.SeekBar
import android.widget.*
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.password.PasswordGenerator
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.ClipboardHelper
import com.kunzisoft.keepass.view.applyFontVisibility
class GeneratePasswordDialogFragment : DialogFragment() {
@@ -64,6 +62,11 @@ class GeneratePasswordDialogFragment : DialogFragment() {
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val builder = AlertDialog.Builder(activity)
@@ -73,6 +76,15 @@ class GeneratePasswordDialogFragment : DialogFragment() {
passwordInputLayoutView = root?.findViewById(R.id.password_input_layout)
passwordView = root?.findViewById(R.id.password)
passwordView?.applyFontVisibility()
val passwordCopyView: ImageView? = root?.findViewById(R.id.password_copy_button)
passwordCopyView?.visibility = if(PreferencesUtil.allowCopyPasswordAndProtectedFields(activity))
View.VISIBLE else View.GONE
val clipboardHelper = ClipboardHelper(activity)
passwordCopyView?.setOnClickListener {
clipboardHelper.timeoutCopyToClipboard(passwordView!!.text.toString(),
getString(R.string.copy_field,
getString(R.string.entry_password)))
}
lengthTextView = root?.findViewById(R.id.length)
@@ -114,7 +126,7 @@ class GeneratePasswordDialogFragment : DialogFragment() {
dismiss()
}
.setNegativeButton(R.string.cancel) { _, _ ->
.setNegativeButton(android.R.string.cancel) { _, _ ->
val bundle = Bundle()
mListener?.cancelPassword(bundle)
@@ -167,7 +179,6 @@ class GeneratePasswordDialogFragment : DialogFragment() {
var password = ""
try {
val length = Integer.valueOf(root?.findViewById<EditText>(R.id.length)?.text.toString())
password = PasswordGenerator(resources).generatePassword(length,
uppercaseBox?.isChecked == true,
lowercaseBox?.isChecked == true,
@@ -178,6 +189,7 @@ class GeneratePasswordDialogFragment : DialogFragment() {
specialsBox?.isChecked == true,
bracketsBox?.isChecked == true,
extendedBox?.isChecked == true)
passwordInputLayoutView?.error = null
} catch (e: NumberFormatException) {
passwordInputLayoutView?.error = getString(R.string.error_wrong_length)
} catch (e: IllegalArgumentException) {
@@ -193,7 +205,6 @@ class GeneratePasswordDialogFragment : DialogFragment() {
}
companion object {
const val KEY_PASSWORD_ID = "KEY_PASSWORD_ID"
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -23,34 +23,40 @@ import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.os.Bundle
import com.google.android.material.textfield.TextInputLayout
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.IconPickerActivity
import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment.EditGroupDialogAction.CREATION
import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment.EditGroupDialogAction.UPDATE
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.GroupVersioned
import com.kunzisoft.keepass.database.element.PwIcon
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.model.GroupInfo
import com.kunzisoft.keepass.view.ExpirationView
import org.joda.time.DateTime
class GroupEditDialogFragment : DialogFragment(), IconPickerDialogFragment.IconPickerListener {
class GroupEditDialogFragment : DialogFragment() {
private var mDatabase: Database? = null
private var editGroupListener: EditGroupListener? = null
private var mEditGroupListener: EditGroupListener? = null
private var editGroupDialogAction: EditGroupDialogAction? = null
private var nameGroup: String? = null
private var iconGroup: PwIcon? = null
private var mEditGroupDialogAction = EditGroupDialogAction.NONE
private var mGroupInfo = GroupInfo()
private var nameTextLayoutView: TextInputLayout? = null
private var nameTextView: TextView? = null
private var iconButtonView: ImageView? = null
private lateinit var iconButtonView: ImageView
private var iconColor: Int = 0
private lateinit var nameTextLayoutView: TextInputLayout
private lateinit var nameTextView: TextView
private lateinit var notesTextLayoutView: TextInputLayout
private lateinit var notesTextView: TextView
private lateinit var expirationView: ExpirationView
enum class EditGroupDialogAction {
CREATION, UPDATE, NONE;
@@ -67,21 +73,28 @@ class GroupEditDialogFragment : DialogFragment(), IconPickerDialogFragment.IconP
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
editGroupListener = context as EditGroupListener
mEditGroupListener = context as EditGroupListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + GroupEditDialogFragment::class.java.name)
}
}
override fun onDetach() {
mEditGroupListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val root = activity.layoutInflater.inflate(R.layout.fragment_group_edit, null)
nameTextLayoutView = root?.findViewById(R.id.group_edit_name_container)
nameTextView = root?.findViewById(R.id.group_edit_name)
iconButtonView = root?.findViewById(R.id.group_edit_icon_button)
iconButtonView = root.findViewById(R.id.group_edit_icon_button)
nameTextLayoutView = root.findViewById(R.id.group_edit_name_container)
nameTextView = root.findViewById(R.id.group_edit_name)
notesTextLayoutView = root.findViewById(R.id.group_edit_note_container)
notesTextView = root.findViewById(R.id.group_edit_note)
expirationView = root.findViewById(R.id.group_edit_expiration)
// Retrieve the textColor to tint the icon
val ta = activity.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
@@ -90,49 +103,47 @@ class GroupEditDialogFragment : DialogFragment(), IconPickerDialogFragment.IconP
// Init elements
mDatabase = Database.getInstance()
editGroupDialogAction = EditGroupDialogAction.NONE
nameGroup = ""
iconGroup = mDatabase?.iconFactory?.folderIcon
if (savedInstanceState != null
&& savedInstanceState.containsKey(KEY_ACTION_ID)
&& savedInstanceState.containsKey(KEY_NAME)
&& savedInstanceState.containsKey(KEY_ICON)) {
editGroupDialogAction = EditGroupDialogAction.getActionFromOrdinal(savedInstanceState.getInt(KEY_ACTION_ID))
nameGroup = savedInstanceState.getString(KEY_NAME)
iconGroup = savedInstanceState.getParcelable(KEY_ICON)
&& savedInstanceState.containsKey(KEY_GROUP_INFO)) {
mEditGroupDialogAction = EditGroupDialogAction.getActionFromOrdinal(savedInstanceState.getInt(KEY_ACTION_ID))
mGroupInfo = savedInstanceState.getParcelable(KEY_GROUP_INFO) ?: mGroupInfo
} else {
arguments?.apply {
if (containsKey(KEY_ACTION_ID))
editGroupDialogAction = EditGroupDialogAction.getActionFromOrdinal(getInt(KEY_ACTION_ID))
if (containsKey(KEY_NAME) && containsKey(KEY_ICON)) {
nameGroup = getString(KEY_NAME)
iconGroup = getParcelable(KEY_ICON)
mEditGroupDialogAction = EditGroupDialogAction.getActionFromOrdinal(getInt(KEY_ACTION_ID))
if (containsKey(KEY_GROUP_INFO)) {
mGroupInfo = getParcelable(KEY_GROUP_INFO) ?: mGroupInfo
}
}
}
// populate the name
nameTextView?.text = nameGroup
// populate the icon
assignIconView()
// populate info in views
populateInfoToViews()
expirationView.setOnDateClickListener = {
expirationView.expiryTime.date.let { expiresDate ->
val dateTime = DateTime(expiresDate)
val defaultYear = dateTime.year
val defaultMonth = dateTime.monthOfYear-1
val defaultDay = dateTime.dayOfMonth
DatePickerFragment.getInstance(defaultYear, defaultMonth, defaultDay)
.show(parentFragmentManager, "DatePickerFragment")
}
}
val builder = AlertDialog.Builder(activity)
builder.setView(root)
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(R.string.cancel) { _, _ ->
editGroupListener?.cancelEditGroup(
editGroupDialogAction,
nameTextView?.text?.toString(),
iconGroup)
.setNegativeButton(android.R.string.cancel) { _, _ ->
retrieveGroupInfoFromViews()
mEditGroupListener?.cancelEditGroup(
mEditGroupDialogAction,
mGroupInfo)
}
iconButtonView?.setOnClickListener { _ ->
fragmentManager?.let {
IconPickerDialogFragment().show(it, "IconPickerDialogFragment")
}
iconButtonView.setOnClickListener { _ ->
IconPickerActivity.launch(activity, mGroupInfo.icon)
}
return builder.create()
@@ -148,69 +159,104 @@ class GroupEditDialogFragment : DialogFragment(), IconPickerDialogFragment.IconP
if (d != null) {
val positiveButton = d.getButton(Dialog.BUTTON_POSITIVE) as Button
positiveButton.setOnClickListener {
retrieveGroupInfoFromViews()
if (isValid()) {
editGroupListener?.approveEditGroup(
editGroupDialogAction,
nameTextView?.text?.toString(),
iconGroup)
mEditGroupListener?.approveEditGroup(
mEditGroupDialogAction,
mGroupInfo)
d.dismiss()
}
}
}
}
private fun assignIconView() {
if (mDatabase?.drawFactory != null && iconGroup != null) {
iconButtonView?.assignDatabaseIcon(mDatabase?.drawFactory!!, iconGroup!!, iconColor)
}
fun getExpiryTime(): DateInstant {
retrieveGroupInfoFromViews()
return mGroupInfo.expiryTime
}
override fun iconPicked(bundle: Bundle) {
iconGroup = IconPickerDialogFragment.getIconStandardFromBundle(bundle)
fun setExpiryTime(expiryTime: DateInstant) {
mGroupInfo.expiryTime = expiryTime
populateInfoToViews()
}
private fun populateInfoToViews() {
assignIconView()
nameTextView.text = mGroupInfo.title
notesTextLayoutView.visibility = if (mGroupInfo.notes == null) View.GONE else View.VISIBLE
mGroupInfo.notes?.let {
notesTextView.text = it
}
expirationView.expires = mGroupInfo.expires
expirationView.expiryTime = mGroupInfo.expiryTime
}
private fun retrieveGroupInfoFromViews() {
mGroupInfo.title = nameTextView.text.toString()
// Only if there
val newNotes = notesTextView.text.toString()
if (newNotes.isNotEmpty()) {
mGroupInfo.notes = newNotes
}
mGroupInfo.expires = expirationView.expires
mGroupInfo.expiryTime = expirationView.expiryTime
}
private fun assignIconView() {
mDatabase?.iconDrawableFactory?.assignDatabaseIcon(iconButtonView, mGroupInfo.icon, iconColor)
}
fun setIcon(icon: IconImage) {
mGroupInfo.icon = icon
assignIconView()
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putInt(KEY_ACTION_ID, editGroupDialogAction!!.ordinal)
outState.putString(KEY_NAME, nameGroup)
outState.putParcelable(KEY_ICON, iconGroup)
retrieveGroupInfoFromViews()
outState.putInt(KEY_ACTION_ID, mEditGroupDialogAction.ordinal)
outState.putParcelable(KEY_GROUP_INFO, mGroupInfo)
super.onSaveInstanceState(outState)
}
private fun isValid(): Boolean {
if (nameTextView?.text?.toString()?.isNotEmpty() != true) {
nameTextLayoutView?.error = getString(R.string.error_no_name)
return false
val error = mEditGroupListener?.isValidGroupName(nameTextView.text.toString()) ?: Error(false, null)
error.messageId?.let { messageId ->
nameTextLayoutView.error = getString(messageId)
} ?: kotlin.run {
nameTextLayoutView.error = null
}
return true
return !error.isError
}
data class Error(val isError: Boolean, val messageId: Int?)
interface EditGroupListener {
fun approveEditGroup(action: EditGroupDialogAction?, name: String?, icon: PwIcon?)
fun cancelEditGroup(action: EditGroupDialogAction?, name: String?, icon: PwIcon?)
fun isValidGroupName(name: String): Error
fun approveEditGroup(action: EditGroupDialogAction,
groupInfo: GroupInfo)
fun cancelEditGroup(action: EditGroupDialogAction,
groupInfo: GroupInfo)
}
companion object {
const val TAG_CREATE_GROUP = "TAG_CREATE_GROUP"
const val KEY_NAME = "KEY_NAME"
const val KEY_ICON = "KEY_ICON"
const val KEY_ACTION_ID = "KEY_ACTION_ID"
const val KEY_GROUP_INFO = "KEY_GROUP_INFO"
fun build(): GroupEditDialogFragment {
fun create(groupInfo: GroupInfo): GroupEditDialogFragment {
val bundle = Bundle()
bundle.putInt(KEY_ACTION_ID, CREATION.ordinal)
bundle.putParcelable(KEY_GROUP_INFO, groupInfo)
val fragment = GroupEditDialogFragment()
fragment.arguments = bundle
return fragment
}
fun build(group: GroupVersioned): GroupEditDialogFragment {
fun update(groupInfo: GroupInfo): GroupEditDialogFragment {
val bundle = Bundle()
bundle.putString(KEY_NAME, group.title)
bundle.putParcelable(KEY_ICON, group.icon)
bundle.putInt(KEY_ACTION_ID, UPDATE.ordinal)
bundle.putParcelable(KEY_GROUP_INFO, groupInfo)
val fragment = GroupEditDialogFragment()
fragment.arguments = bundle
return fragment

View File

@@ -1,141 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.core.widget.ImageViewCompat
import androidx.appcompat.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.GridView
import android.widget.ImageView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.database.element.PwIconStandard
import com.kunzisoft.keepass.icons.IconPack
import com.kunzisoft.keepass.icons.IconPackChooser
class IconPickerDialogFragment : DialogFragment() {
private var iconPickerListener: IconPickerListener? = null
private var iconPack: IconPack? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
iconPickerListener = context as IconPickerListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + IconPickerListener::class.java.name)
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val builder = AlertDialog.Builder(activity)
iconPack = IconPackChooser.getSelectedIconPack(context!!)
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
val root = activity.layoutInflater.inflate(R.layout.fragment_icon_picker, null)
builder.setView(root)
val currIconGridView = root.findViewById<GridView>(R.id.IconGridView)
currIconGridView.adapter = ImageAdapter(activity)
currIconGridView.setOnItemClickListener { _, _, position, _ ->
val bundle = Bundle()
bundle.putParcelable(KEY_ICON_STANDARD, PwIconStandard(position))
iconPickerListener?.iconPicked(bundle)
dismiss()
}
builder.setNegativeButton(R.string.cancel) { _, _ -> this@IconPickerDialogFragment.dialog?.cancel() }
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
inner class ImageAdapter internal constructor(private val context: Context) : BaseAdapter() {
override fun getCount(): Int {
return iconPack?.numberOfIcons() ?: 0
}
override fun getItem(position: Int): Any? {
return null
}
override fun getItemId(position: Int): Long {
return 0
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val currentView: View = convertView
?: (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
.inflate(R.layout.item_icon, parent, false)
iconPack?.let { iconPack ->
val iconImageView = currentView.findViewById<ImageView>(R.id.icon_image)
iconImageView.setImageResource(iconPack.iconToResId(position))
// Assign color if icons are tintable
if (iconPack.tintable()) {
// Retrieve the textColor to tint the icon
val ta = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
ImageViewCompat.setImageTintList(iconImageView, ColorStateList.valueOf(ta.getColor(0, Color.BLACK)))
ta?.recycle()
}
}
return currentView
}
}
interface IconPickerListener {
fun iconPicked(bundle: Bundle)
}
companion object {
private const val KEY_ICON_STANDARD = "KEY_ICON_STANDARD"
fun getIconStandardFromBundle(bundle: Bundle): PwIconStandard? {
return bundle.getParcelable(KEY_ICON_STANDARD)
}
fun launch(activity: StylishActivity) {
// Create an instance of the dialog fragment and show it
val dialog = IconPickerDialogFragment()
dialog.show(activity.supportFragmentManager, "IconPickerDialogFragment")
}
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Bundle
import android.provider.Settings
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.view.View
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.utils.UriUtil
class KeyboardExplanationDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let {
val builder = AlertDialog.Builder(activity!!)
val inflater = activity!!.layoutInflater
val rootView = inflater.inflate(R.layout.fragment_keyboard_explanation, null)
rootView.findViewById<View>(R.id.keyboards_activate_device_setting_button)
.setOnClickListener { launchActivateKeyboardSetting() }
val containerKeyboardSwitcher = rootView.findViewById<View>(R.id.container_keyboard_switcher)
if (BuildConfig.CLOSED_STORE) {
containerKeyboardSwitcher.setOnClickListener { UriUtil.gotoUrl(context!!, R.string.keyboard_switcher_play_store) }
} else {
containerKeyboardSwitcher.setOnClickListener { UriUtil.gotoUrl(context!!, R.string.keyboard_switcher_f_droid) }
}
builder.setView(rootView)
.setPositiveButton(android.R.string.ok) { _, _ -> }
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
private fun launchActivateKeyboardSetting() {
val intent = Intent(Settings.ACTION_INPUT_METHOD_SETTINGS)
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}

View File

@@ -1,46 +1,91 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
import android.app.AlertDialog
import android.app.Dialog
import android.content.DialogInterface
import android.content.Context
import android.net.Uri
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.model.MainCredential
class PasswordEncodingDialogFragment : DialogFragment() {
var positiveButtonClickListener: DialogInterface.OnClickListener? = null
private var mListener: Listener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
mListener = context as Listener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + Listener::class.java.name)
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val databaseUri: Uri? = savedInstanceState?.getParcelable(DATABASE_URI_KEY)
val mainCredential: MainCredential = savedInstanceState?.getParcelable(MAIN_CREDENTIAL) ?: MainCredential()
activity?.let { activity ->
val builder = AlertDialog.Builder(activity)
builder.setMessage(activity.getString(R.string.warning_password_encoding)).setTitle(R.string.warning)
builder.setPositiveButton(android.R.string.ok, positiveButtonClickListener)
builder.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
builder.setPositiveButton(android.R.string.ok) { _, _ ->
mListener?.onPasswordEncodingValidateListener(
databaseUri,
mainCredential
)
}
builder.setNegativeButton(android.R.string.cancel) { dialog, _ -> dialog.cancel() }
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
interface Listener {
fun onPasswordEncodingValidateListener(databaseUri: Uri?,
mainCredential: MainCredential)
}
companion object {
private const val DATABASE_URI_KEY = "DATABASE_URI_KEY"
private const val MAIN_CREDENTIAL = "MAIN_CREDENTIAL"
fun getInstance(databaseUri: Uri,
mainCredential: MainCredential): SortDialogFragment {
val fragment = SortDialogFragment()
fragment.arguments = Bundle().apply {
putParcelable(DATABASE_URI_KEY, databaseUri)
putParcelable(MAIN_CREDENTIAL, mainCredential)
}
return fragment
}
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -45,13 +45,13 @@ class ProFeatureDialogFragment : DialogFragment() {
stringBuilder.append(HtmlCompat.fromHtml(getString(R.string.html_text_ad_free), FROM_HTML_MODE_LEGACY)).append("\n\n")
stringBuilder.append(HtmlCompat.fromHtml(getString(R.string.html_text_buy_pro), FROM_HTML_MODE_LEGACY))
builder.setPositiveButton(R.string.download) { _, _ ->
UriUtil.gotoUrl(context!!, R.string.app_pro_url)
UriUtil.gotoUrl(requireContext(), R.string.app_pro_url)
}
} else {
stringBuilder.append(HtmlCompat.fromHtml(getString(R.string.html_text_feature_generosity), FROM_HTML_MODE_LEGACY)).append("\n\n")
stringBuilder.append(HtmlCompat.fromHtml(getString(R.string.html_text_donation), FROM_HTML_MODE_LEGACY))
builder.setPositiveButton(R.string.contribute) { _, _ ->
UriUtil.gotoUrl(context!!, R.string.contribution_url)
UriUtil.gotoUrl(requireContext(), R.string.contribution_url)
}
}
builder.setMessage(stringBuilder)

View File

@@ -1,56 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
class ReadOnlyDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
// Use the Builder class for convenient dialog construction
val builder = androidx.appcompat.app.AlertDialog.Builder(activity)
var warning = getString(R.string.read_only_warning)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
warning = warning + "\n\n" + getString(R.string.read_only_kitkat_warning)
}
builder.setMessage(warning)
builder.setPositiveButton(getString(android.R.string.ok)) { _, _ -> dismiss() }
builder.setNegativeButton(getString(R.string.beta_dontask)) { _, _ ->
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val edit = prefs.edit()
edit.putBoolean(getString(R.string.show_read_only_warning), false)
edit.apply()
dismiss()
}
// Create the AlertDialog object and return it
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.dialogs
import android.app.Dialog
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.text.SpannableStringBuilder
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Attachment
/**
* Custom Dialog to confirm big file to upload
*/
class ReplaceFileDialogFragment : DialogFragment() {
private var mActionChooseListener: ActionChooseListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
// Verify that the host activity implements the callback interface
try {
mActionChooseListener = context as ActionChooseListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + ActionChooseListener::class.java.name)
}
}
override fun onDetach() {
mActionChooseListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(activity)
builder.setMessage(SpannableStringBuilder().apply {
append(getString(R.string.warning_replace_file))
append("\n\n")
append(getString(R.string.warning_sure_add_file))
})
builder.setPositiveButton(android.R.string.ok) { _, _ ->
mActionChooseListener?.onValidateReplaceFile(
arguments?.getParcelable(KEY_FILE_URI),
arguments?.getParcelable(KEY_ENTRY_ATTACHMENT))
}
builder.setNegativeButton(android.R.string.cancel) { _, _ ->
dismiss()
}
// Create the AlertDialog object and return it
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
interface ActionChooseListener {
fun onValidateReplaceFile(attachmentToUploadUri: Uri?, attachment: Attachment?)
}
companion object {
private const val KEY_FILE_URI = "KEY_FILE_URI"
private const val KEY_ENTRY_ATTACHMENT = "KEY_ENTRY_ATTACHMENT"
fun build(attachmentToUploadUri: Uri,
attachment: Attachment): ReplaceFileDialogFragment {
val fragment = ReplaceFileDialogFragment()
fragment.arguments = Bundle().apply {
putParcelable(KEY_FILE_URI, attachmentToUploadUri)
putParcelable(KEY_ENTRY_ATTACHMENT, attachment)
}
return fragment
}
}
}

View File

@@ -0,0 +1,462 @@
/*
* 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.dialogs
import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.model.OtpModel
import com.kunzisoft.keepass.otp.OtpElement
import com.kunzisoft.keepass.otp.OtpElement.Companion.MAX_HOTP_COUNTER
import com.kunzisoft.keepass.otp.OtpElement.Companion.MAX_OTP_DIGITS
import com.kunzisoft.keepass.otp.OtpElement.Companion.MAX_TOTP_PERIOD
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_HOTP_COUNTER
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_OTP_DIGITS
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_TOTP_PERIOD
import com.kunzisoft.keepass.otp.OtpTokenType
import com.kunzisoft.keepass.otp.OtpType
import com.kunzisoft.keepass.otp.TokenCalculator
import com.kunzisoft.keepass.utils.UriUtil
import java.util.*
class SetOTPDialogFragment : DialogFragment() {
private var mCreateOTPElementListener: CreateOtpListener? = null
private var mOtpElement: OtpElement = OtpElement()
private var otpTypeMessage: TextView? = null
private var otpTypeSpinner: Spinner? = null
private var otpTokenTypeSpinner: Spinner? = null
private var otpSecretContainer: TextInputLayout? = null
private var otpSecretTextView: EditText? = null
private var otpPeriodContainer: TextInputLayout? = null
private var otpPeriodTextView: EditText? = null
private var otpCounterContainer: TextInputLayout? = null
private var otpCounterTextView: EditText? = null
private var otpDigitsContainer: TextInputLayout? = null
private var otpDigitsTextView: EditText? = null
private var otpAlgorithmSpinner: Spinner? = null
private var otpTypeAdapter: ArrayAdapter<OtpType>? = null
private var otpTokenTypeAdapter: ArrayAdapter<OtpTokenType>? = null
private var totpTokenTypeAdapter: ArrayAdapter<OtpTokenType>? = null
private var hotpTokenTypeAdapter: ArrayAdapter<OtpTokenType>? = null
private var otpAlgorithmAdapter: ArrayAdapter<TokenCalculator.HashAlgorithm>? = null
private var mHotpTokenTypeArray: Array<OtpTokenType>? = null
private var mTotpTokenTypeArray: Array<OtpTokenType>? = null
private var mManualEvent = false
private var mOnFocusChangeListener = View.OnFocusChangeListener { _, isFocus ->
if (!isFocus)
mManualEvent = true
}
private var mOnTouchListener = View.OnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
mManualEvent = true
}
}
false
}
private var mSecretWellFormed = false
private var mCounterWellFormed = false
private var mPeriodWellFormed = false
private var mDigitsWellFormed = false
override fun onAttach(context: Context) {
super.onAttach(context)
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mCreateOTPElementListener = context as CreateOtpListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + CreateOtpListener::class.java.name)
}
}
override fun onDetach() {
mCreateOTPElementListener = null
super.onDetach()
}
@SuppressLint("ClickableViewAccessibility")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Retrieve OTP model from instance state
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(KEY_OTP)) {
savedInstanceState.getParcelable<OtpModel>(KEY_OTP)?.let { otpModel ->
mOtpElement = OtpElement(otpModel)
}
}
} else {
arguments?.apply {
if (containsKey(KEY_OTP)) {
getParcelable<OtpModel?>(KEY_OTP)?.let { otpModel ->
mOtpElement = OtpElement(otpModel)
}
}
}
}
activity?.let { activity ->
val root = activity.layoutInflater.inflate(R.layout.fragment_set_otp, null) as ViewGroup?
otpTypeMessage = root?.findViewById(R.id.setup_otp_type_message)
otpTypeSpinner = root?.findViewById(R.id.setup_otp_type)
otpTokenTypeSpinner = root?.findViewById(R.id.setup_otp_token_type)
otpSecretContainer = root?.findViewById(R.id.setup_otp_secret_label)
otpSecretTextView = root?.findViewById(R.id.setup_otp_secret)
otpAlgorithmSpinner = root?.findViewById(R.id.setup_otp_algorithm)
otpPeriodContainer= root?.findViewById(R.id.setup_otp_period_label)
otpPeriodTextView = root?.findViewById(R.id.setup_otp_period)
otpCounterContainer= root?.findViewById(R.id.setup_otp_counter_label)
otpCounterTextView = root?.findViewById(R.id.setup_otp_counter)
otpDigitsContainer = root?.findViewById(R.id.setup_otp_digits_label)
otpDigitsTextView = root?.findViewById(R.id.setup_otp_digits)
// To fix init element
// With tab keyboard selection
otpSecretTextView?.onFocusChangeListener = mOnFocusChangeListener
// With finger selection
otpTypeSpinner?.setOnTouchListener(mOnTouchListener)
otpTokenTypeSpinner?.setOnTouchListener(mOnTouchListener)
otpSecretTextView?.setOnTouchListener(mOnTouchListener)
otpAlgorithmSpinner?.setOnTouchListener(mOnTouchListener)
otpPeriodTextView?.setOnTouchListener(mOnTouchListener)
otpCounterTextView?.setOnTouchListener(mOnTouchListener)
otpDigitsTextView?.setOnTouchListener(mOnTouchListener)
// To manage focus
otpPeriodTextView?.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_NEXT) {
otpDigitsTextView?.requestFocus()
true
} else
false
}
otpCounterTextView?.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_NEXT) {
otpDigitsTextView?.requestFocus()
true
} else
false
}
otpCounterTextView?.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_NEXT) {
root?.requestFocus(View.FOCUS_DOWN)
true
} else
false
}
// HOTP / TOTP Type selection
val otpTypeArray = OtpType.values()
otpTypeAdapter = ArrayAdapter(activity,
android.R.layout.simple_spinner_item, otpTypeArray).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
}
otpTypeSpinner?.adapter = otpTypeAdapter
// Otp Token type selection
mHotpTokenTypeArray = OtpTokenType.getHotpTokenTypeValues()
hotpTokenTypeAdapter = ArrayAdapter(activity,
android.R.layout.simple_spinner_item, mHotpTokenTypeArray!!).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
}
// Proprietary only on closed and full version
mTotpTokenTypeArray = OtpTokenType.getTotpTokenTypeValues(
BuildConfig.CLOSED_STORE && BuildConfig.FULL_VERSION)
totpTokenTypeAdapter = ArrayAdapter(activity,
android.R.layout.simple_spinner_item, mTotpTokenTypeArray!!).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
}
otpTokenTypeAdapter = hotpTokenTypeAdapter
otpTokenTypeSpinner?.adapter = otpTokenTypeAdapter
// OTP Algorithm
val otpAlgorithmArray = TokenCalculator.HashAlgorithm.values()
otpAlgorithmAdapter = ArrayAdapter(activity,
android.R.layout.simple_spinner_item, otpAlgorithmArray).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
}
otpAlgorithmSpinner?.adapter = otpAlgorithmAdapter
// Set the default value of OTP element
upgradeType()
upgradeTokenType()
upgradeParameters()
attachListeners()
val builder = AlertDialog.Builder(activity)
builder.apply {
setView(root)
.setPositiveButton(android.R.string.ok) {_, _ -> }
.setNegativeButton(android.R.string.cancel) { _, _ ->
}
}
root?.findViewById<View>(R.id.otp_information)?.setOnClickListener {
UriUtil.gotoUrl(activity, R.string.otp_explanation_url)
}
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
override fun onResume() {
super.onResume()
(dialog as AlertDialog).getButton(Dialog.BUTTON_POSITIVE).setOnClickListener {
if (mSecretWellFormed
&& mCounterWellFormed
&& mPeriodWellFormed
&& mDigitsWellFormed) {
mCreateOTPElementListener?.onOtpCreated(mOtpElement)
dismiss()
}
}
}
private fun attachListeners() {
// Set Type listener
otpTypeSpinner?.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (mManualEvent) {
(parent?.selectedItem as OtpType?)?.let {
mOtpElement.type = it
upgradeTokenType()
}
}
}
}
// Set type token listener
otpTokenTypeSpinner?.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (mManualEvent) {
(parent?.selectedItem as OtpTokenType?)?.let {
mOtpElement.tokenType = it
upgradeParameters()
}
}
}
}
// Set algorithm spinner
otpAlgorithmSpinner?.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (mManualEvent) {
(parent?.selectedItem as TokenCalculator.HashAlgorithm?)?.let {
mOtpElement.algorithm = it
}
}
}
}
// Set secret in OtpElement
otpSecretTextView?.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable?) {
s?.toString()?.let { userString ->
try {
mOtpElement.setBase32Secret(userString.toUpperCase(Locale.ENGLISH))
otpSecretContainer?.error = null
} catch (exception: Exception) {
otpSecretContainer?.error = getString(R.string.error_otp_secret_key)
}
mSecretWellFormed = otpSecretContainer?.error == null
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
// Set counter in OtpElement
otpCounterTextView?.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (mManualEvent) {
s?.toString()?.toLongOrNull()?.let {
try {
mOtpElement.counter = it
otpCounterContainer?.error = null
} catch (exception: Exception) {
otpCounterContainer?.error = getString(R.string.error_otp_counter,
MIN_HOTP_COUNTER, MAX_HOTP_COUNTER)
}
mCounterWellFormed = otpCounterContainer?.error == null
}
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
// Set period in OtpElement
otpPeriodTextView?.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (mManualEvent) {
s?.toString()?.toIntOrNull()?.let {
try {
mOtpElement.period = it
otpPeriodContainer?.error = null
} catch (exception: Exception) {
otpPeriodContainer?.error = getString(R.string.error_otp_period,
MIN_TOTP_PERIOD, MAX_TOTP_PERIOD)
}
mPeriodWellFormed = otpPeriodContainer?.error == null
}
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
// Set digits in OtpElement
otpDigitsTextView?.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (mManualEvent) {
s?.toString()?.toIntOrNull()?.let {
try {
mOtpElement.digits = it
otpDigitsContainer?.error = null
} catch (exception: Exception) {
otpDigitsContainer?.error = getString(R.string.error_otp_digits,
MIN_OTP_DIGITS, MAX_OTP_DIGITS)
}
mDigitsWellFormed = otpDigitsContainer?.error == null
}
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
}
private fun upgradeType() {
otpTypeSpinner?.setSelection(OtpType.values().indexOf(mOtpElement.type))
}
private fun upgradeTokenType() {
val tokenType = mOtpElement.tokenType
when (mOtpElement.type) {
OtpType.HOTP -> {
otpPeriodContainer?.visibility = View.GONE
otpCounterContainer?.visibility = View.VISIBLE
otpTokenTypeSpinner?.adapter = hotpTokenTypeAdapter
mHotpTokenTypeArray?.let { otpTokenTypeArray ->
defineOtpTokenTypeSpinner(otpTokenTypeArray, tokenType, OtpTokenType.RFC4226)
}
}
OtpType.TOTP -> {
otpPeriodContainer?.visibility = View.VISIBLE
otpCounterContainer?.visibility = View.GONE
otpTokenTypeSpinner?.adapter = totpTokenTypeAdapter
mTotpTokenTypeArray?.let { otpTokenTypeArray ->
defineOtpTokenTypeSpinner(otpTokenTypeArray, tokenType, OtpTokenType.RFC6238)
}
}
}
}
private fun defineOtpTokenTypeSpinner(otpTokenTypeArray: Array<OtpTokenType>,
tokenType: OtpTokenType,
defaultTokenType: OtpTokenType) {
val formTokenType = if (otpTokenTypeArray.contains(tokenType)) {
otpTypeMessage?.visibility = View.GONE
tokenType
} else {
otpTypeMessage?.visibility = View.VISIBLE
defaultTokenType
}
otpTokenTypeSpinner?.setSelection(otpTokenTypeArray.indexOf(formTokenType))
}
private fun upgradeParameters() {
otpAlgorithmSpinner?.setSelection(TokenCalculator.HashAlgorithm.values()
.indexOf(mOtpElement.algorithm))
val secret = mOtpElement.getBase32Secret()
otpSecretTextView?.apply {
setText(secret)
// Cursor at end
setSelection(this.text.length)
}
mSecretWellFormed = OtpElement.isValidBase32(secret)
val counter = mOtpElement.counter
otpCounterTextView?.setText(counter.toString())
mCounterWellFormed = OtpElement.isValidCounter(counter)
val period = mOtpElement.period
otpPeriodTextView?.setText(period.toString())
mPeriodWellFormed = OtpElement.isValidPeriod(period)
val digits = mOtpElement.digits
otpDigitsTextView?.setText(digits.toString())
mDigitsWellFormed = OtpElement.isValidDigits(digits)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelable(KEY_OTP, mOtpElement.otpModel)
}
interface CreateOtpListener {
fun onOtpCreated(otpElement: OtpElement)
}
companion object {
private const val KEY_OTP = "KEY_OTP"
fun build(otpModel: OtpModel? = null): SetOTPDialogFragment {
return SetOTPDialogFragment().apply {
if (otpModel != null) {
arguments = Bundle().apply {
putParcelable(KEY_OTP, otpModel)
}
}
}
}
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -29,7 +29,7 @@ import android.view.View
import android.widget.CompoundButton
import android.widget.RadioGroup
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.SortNodeEnum
import com.kunzisoft.keepass.database.element.SortNodeEnum
class SortDialogFragment : DialogFragment() {
@@ -54,6 +54,11 @@ class SortDialogFragment : DialogFragment() {
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val builder = AlertDialog.Builder(activity)
@@ -82,8 +87,10 @@ class SortDialogFragment : DialogFragment() {
builder.setView(rootView)
// Add action buttons
.setPositiveButton(android.R.string.ok
) { _, _ -> mListener?.onSortSelected(mSortNodeEnum, mAscending, mGroupsBefore, mRecycleBinBottom) }
.setNegativeButton(R.string.cancel) { _, _ -> }
) { _, _ -> mListener?.onSortSelected(mSortNodeEnum,
SortNodeEnum.SortNodeParameters(mAscending, mGroupsBefore, mRecycleBinBottom))
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
val ascendingView = rootView.findViewById<CompoundButton>(R.id.sort_selection_ascending)
// Check if is ascending or descending
@@ -150,10 +157,7 @@ class SortDialogFragment : DialogFragment() {
}
interface SortSelectionListener {
fun onSortSelected(sortNodeEnum: SortNodeEnum,
ascending: Boolean,
groupsBefore: Boolean,
recycleBinBottom: Boolean)
fun onSortSelected(sortNodeEnum: SortNodeEnum, sortNodeParameters: SortNodeEnum.SortNodeParameters)
}
companion object {

View File

@@ -0,0 +1,62 @@
package com.kunzisoft.keepass.activities.dialogs
import android.app.DatePickerDialog
import android.app.Dialog
import android.app.TimePickerDialog
import android.content.Context
import android.os.Bundle
import android.text.format.DateFormat
import androidx.fragment.app.DialogFragment
class TimePickerFragment : DialogFragment() {
private var defaultHour: Int = 0
private var defaultMinute: Int = 0
private var mListener: TimePickerDialog.OnTimeSetListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
mListener = context as TimePickerDialog.OnTimeSetListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + DatePickerDialog.OnDateSetListener::class.java.name)
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Create a new instance of DatePickerDialog and return it
return context?.let {
arguments?.apply {
if (containsKey(DEFAULT_HOUR_BUNDLE_KEY))
defaultHour = getInt(DEFAULT_HOUR_BUNDLE_KEY)
if (containsKey(DEFAULT_MINUTE_BUNDLE_KEY))
defaultMinute = getInt(DEFAULT_MINUTE_BUNDLE_KEY)
}
TimePickerDialog(it, mListener, defaultHour, defaultMinute, DateFormat.is24HourFormat(activity))
} ?: super.onCreateDialog(savedInstanceState)
}
companion object {
private const val DEFAULT_HOUR_BUNDLE_KEY = "DEFAULT_HOUR_BUNDLE_KEY"
private const val DEFAULT_MINUTE_BUNDLE_KEY = "DEFAULT_MINUTE_BUNDLE_KEY"
fun getInstance(defaultHour: Int,
defaultMinute: Int): TimePickerFragment {
return TimePickerFragment().apply {
arguments = Bundle().apply {
putInt(DEFAULT_HOUR_BUNDLE_KEY, defaultHour)
putInt(DEFAULT_MINUTE_BUNDLE_KEY, defaultMinute)
}
}
}
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -24,7 +24,6 @@ import android.os.Build
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.text.Html
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.widget.TextView
@@ -91,12 +90,12 @@ class UnavailableFeatureDialogFragment : DialogFragment() {
}
}
if (apiName.isEmpty()) {
val mapper = arrayOf("ANDROID BASE", "ANDROID BASE 1.1", "CUPCAKE", "DONUT", "ECLAIR", "ECLAIR_0_1", "ECLAIR_MR1", "FROYO", "GINGERBREAD", "GINGERBREAD_MR1", "HONEYCOMB", "HONEYCOMB_MR1", "HONEYCOMB_MR2", "ICE_CREAM_SANDWICH", "ICE_CREAM_SANDWICH_MR1", "JELLY_BEAN", "JELLY_BEAN", "JELLY_BEAN", "KITKAT", "KITKAT", "LOLLIPOOP", "LOLLIPOOP_MR1", "MARSHMALLOW", "NOUGAT", "NOUGAT", "OREO", "OREO")
val mapper = arrayOf("ANDROID BASE", "ANDROID BASE 1.1", "CUPCAKE", "DONUT", "ECLAIR", "ECLAIR_0_1", "ECLAIR_MR1", "FROYO", "GINGERBREAD", "GINGERBREAD_MR1", "HONEYCOMB", "HONEYCOMB_MR1", "HONEYCOMB_MR2", "ICE_CREAM_SANDWICH", "ICE_CREAM_SANDWICH_MR1", "JELLY_BEAN", "JELLY_BEAN", "JELLY_BEAN", "KITKAT", "KITKAT", "LOLLIPOOP", "LOLLIPOOP_MR1", "MARSHMALLOW", "NOUGAT", "NOUGAT", "OREO", "OREO", "PIE", "", "")
val index = apiNumber - 1
apiName = if (index < mapper.size) mapper[index] else "UNKNOWN_VERSION"
}
if (version.isEmpty()) {
val versions = arrayOf("1.0", "1.1", "1.5", "1.6", "2.0", "2.0.1", "2.1", "2.2.X", "2.3", "2.3.3", "3.0", "3.1", "3.2.0", "4.0.1", "4.0.3", "4.1.0", "4.2.0", "4.3.0", "4.4", "4.4", "5.0", "5.1", "6.0", "7.0", "7.1", "8.0.0", "8.1.0")
val versions = arrayOf("1.0", "1.1", "1.5", "1.6", "2.0", "2.0.1", "2.1", "2.2.X", "2.3", "2.3.3", "3.0", "3.1", "3.2.0", "4.0.1", "4.0.3", "4.1.0", "4.2.0", "4.3.0", "4.4", "4.4", "5.0", "5.1", "6.0", "7.0", "7.1", "8.0.0", "8.1.0", "9", "10", "11")
val index = apiNumber - 1
version = if (index < versions.size) versions[index] else "UNKNOWN_VERSION"
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.dialogs
@@ -52,7 +52,7 @@ class UnderDevelopmentFeatureDialogFragment : DialogFragment() {
.append(HtmlCompat.fromHtml(getString(R.string.html_text_dev_feature_buy_pro), HtmlCompat.FROM_HTML_MODE_LEGACY)).append("\n")
.append(HtmlCompat.fromHtml(getString(R.string.html_text_dev_feature_encourage), HtmlCompat.FROM_HTML_MODE_LEGACY))
builder.setPositiveButton(R.string.download) { _, _ ->
UriUtil.gotoUrl(context!!, R.string.app_pro_url)
UriUtil.gotoUrl(requireContext(), R.string.app_pro_url)
}
builder.setNegativeButton(android.R.string.cancel) { _, _ -> dismiss() }
}
@@ -61,7 +61,7 @@ class UnderDevelopmentFeatureDialogFragment : DialogFragment() {
.append(HtmlCompat.fromHtml(getString(R.string.html_text_dev_feature_contibute), HtmlCompat.FROM_HTML_MODE_LEGACY)).append(" ")
.append(HtmlCompat.fromHtml(getString(R.string.html_text_dev_feature_encourage), HtmlCompat.FROM_HTML_MODE_LEGACY))
builder.setPositiveButton(R.string.contribute) { _, _ ->
UriUtil.gotoUrl(context!!, R.string.contribution_url)
UriUtil.gotoUrl(requireContext(), R.string.contribution_url)
}
builder.setNegativeButton(android.R.string.cancel) { _, _ -> dismiss() }
}

View File

@@ -0,0 +1,528 @@
/*
* 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.fragments
import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.ImageView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.EntryEditActivity
import com.kunzisoft.keepass.activities.dialogs.GeneratePasswordDialogFragment
import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged
import com.kunzisoft.keepass.activities.stylish.StylishFragment
import com.kunzisoft.keepass.adapters.EntryAttachmentsItemsAdapter
import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.education.EntryEditActivityEducation
import com.kunzisoft.keepass.icons.IconDrawableFactory
import com.kunzisoft.keepass.model.*
import com.kunzisoft.keepass.otp.OtpEntryFields
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.view.ExpirationView
import com.kunzisoft.keepass.view.applyFontVisibility
import com.kunzisoft.keepass.view.collapse
import com.kunzisoft.keepass.view.expand
class EntryEditFragment: StylishFragment() {
private lateinit var entryTitleLayoutView: TextInputLayout
private lateinit var entryTitleView: EditText
private lateinit var entryIconView: ImageView
private lateinit var entryUserNameView: EditText
private lateinit var entryUrlView: EditText
private lateinit var entryPasswordLayoutView: TextInputLayout
private lateinit var entryPasswordView: EditText
private lateinit var entryPasswordGeneratorView: View
private lateinit var entryExpirationView: ExpirationView
private lateinit var entryNotesView: EditText
private lateinit var extraFieldsContainerView: View
private lateinit var extraFieldsListView: ViewGroup
private lateinit var attachmentsContainerView: View
private lateinit var attachmentsListView: RecyclerView
private lateinit var attachmentsAdapter: EntryAttachmentsItemsAdapter
private var fontInVisibility: Boolean = false
private var iconColor: Int = 0
var drawFactory: IconDrawableFactory? = null
var setOnDateClickListener: (() -> Unit)? = null
var setOnPasswordGeneratorClickListener: View.OnClickListener? = null
var setOnIconViewClickListener: ((IconImage) -> Unit)? = null
var setOnEditCustomField: ((Field) -> Unit)? = null
var setOnRemoveAttachment: ((Attachment) -> Unit)? = null
// Elements to modify the current entry
private var mEntryInfo = EntryInfo()
private var mLastFocusedEditField: FocusedEditField? = null
private var mExtraViewToRequestFocus: EditText? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
val rootView = inflater.cloneInContext(contextThemed)
.inflate(R.layout.fragment_entry_edit_contents, container, false)
fontInVisibility = PreferencesUtil.fieldFontIsInVisibility(requireContext())
entryTitleLayoutView = rootView.findViewById(R.id.entry_edit_container_title)
entryTitleView = rootView.findViewById(R.id.entry_edit_title)
entryIconView = rootView.findViewById(R.id.entry_edit_icon_button)
entryIconView.setOnClickListener {
setOnIconViewClickListener?.invoke(mEntryInfo.icon)
}
entryUserNameView = rootView.findViewById(R.id.entry_edit_user_name)
entryUrlView = rootView.findViewById(R.id.entry_edit_url)
entryPasswordLayoutView = rootView.findViewById(R.id.entry_edit_container_password)
entryPasswordView = rootView.findViewById(R.id.entry_edit_password)
entryPasswordGeneratorView = rootView.findViewById(R.id.entry_edit_password_generator_button)
entryPasswordGeneratorView.setOnClickListener {
setOnPasswordGeneratorClickListener?.onClick(it)
}
entryExpirationView = rootView.findViewById(R.id.entry_edit_expiration)
entryExpirationView.setOnDateClickListener = setOnDateClickListener
entryNotesView = rootView.findViewById(R.id.entry_edit_notes)
extraFieldsContainerView = rootView.findViewById(R.id.extra_fields_container)
extraFieldsListView = rootView.findViewById(R.id.extra_fields_list)
attachmentsContainerView = rootView.findViewById(R.id.entry_attachments_container)
attachmentsListView = rootView.findViewById(R.id.entry_attachments_list)
attachmentsAdapter = EntryAttachmentsItemsAdapter(requireContext())
// TODO retrieve current database with its unique key
attachmentsAdapter.database = Database.getInstance()
//attachmentsAdapter.database = arguments?.getInt(KEY_DATABASE)
attachmentsAdapter.onListSizeChangedListener = { previousSize, newSize ->
if (previousSize > 0 && newSize == 0) {
attachmentsContainerView.collapse(true)
} else if (previousSize == 0 && newSize == 1) {
attachmentsContainerView.expand(true)
}
}
attachmentsListView.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
adapter = attachmentsAdapter
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
}
// Retrieve the textColor to tint the icon
val taIconColor = contextThemed?.theme?.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
iconColor = taIconColor?.getColor(0, Color.WHITE) ?: Color.WHITE
taIconColor?.recycle()
rootView?.resetAppTimeoutWhenViewFocusedOrChanged(requireContext())
// Retrieve the new entry after an orientation change
if (arguments?.containsKey(KEY_TEMP_ENTRY_INFO) == true)
mEntryInfo = arguments?.getParcelable(KEY_TEMP_ENTRY_INFO) ?: mEntryInfo
else if (savedInstanceState?.containsKey(KEY_TEMP_ENTRY_INFO) == true) {
mEntryInfo = savedInstanceState.getParcelable(KEY_TEMP_ENTRY_INFO) ?: mEntryInfo
}
if (savedInstanceState?.containsKey(KEY_LAST_FOCUSED_FIELD) == true) {
mLastFocusedEditField = savedInstanceState.getParcelable(KEY_LAST_FOCUSED_FIELD) ?: mLastFocusedEditField
}
populateViewsWithEntry()
return rootView
}
override fun onDetach() {
super.onDetach()
drawFactory = null
setOnDateClickListener = null
setOnPasswordGeneratorClickListener = null
setOnIconViewClickListener = null
setOnRemoveAttachment = null
setOnEditCustomField = null
}
fun getEntryInfo(): EntryInfo {
populateEntryWithViews()
return mEntryInfo
}
fun generatePasswordEducationPerformed(entryEditActivityEducation: EntryEditActivityEducation): Boolean {
return entryEditActivityEducation.checkAndPerformedGeneratePasswordEducation(
entryPasswordGeneratorView,
{
GeneratePasswordDialogFragment().show(parentFragmentManager, "PasswordGeneratorFragment")
},
{
try {
(activity as? EntryEditActivity?)?.performedNextEducation(entryEditActivityEducation)
} catch (ignore: Exception) {}
}
)
}
private fun populateViewsWithEntry() {
// Set info in view
icon = mEntryInfo.icon
title = mEntryInfo.title
username = mEntryInfo.username
url = mEntryInfo.url
password = mEntryInfo.password
expires = mEntryInfo.expires
expiryTime = mEntryInfo.expiryTime
notes = mEntryInfo.notes
assignExtraFields(mEntryInfo.customFields) { fields ->
setOnEditCustomField?.invoke(fields)
}
assignAttachments(mEntryInfo.attachments, StreamDirection.UPLOAD) { attachment ->
setOnRemoveAttachment?.invoke(attachment)
}
}
private fun populateEntryWithViews() {
// Icon already populate
mEntryInfo.title = title
mEntryInfo.username = username
mEntryInfo.url = url
mEntryInfo.password = password
mEntryInfo.expires = expires
mEntryInfo.expiryTime = expiryTime
mEntryInfo.notes = notes
mEntryInfo.customFields = getExtraFields()
mEntryInfo.otpModel = OtpEntryFields.parseFields { key ->
getExtraFields().firstOrNull { it.name == key }?.protectedValue?.toString()
}?.otpModel
mEntryInfo.attachments = getAttachments()
}
var title: String
get() {
return entryTitleView.text.toString()
}
set(value) {
entryTitleView.setText(value)
if (fontInVisibility)
entryTitleView.applyFontVisibility()
}
var icon: IconImage
get() {
return mEntryInfo.icon
}
set(value) {
mEntryInfo.icon = value
drawFactory?.assignDatabaseIcon(entryIconView, value, iconColor)
}
var username: String
get() {
return entryUserNameView.text.toString()
}
set(value) {
entryUserNameView.setText(value)
if (fontInVisibility)
entryUserNameView.applyFontVisibility()
}
var url: String
get() {
return entryUrlView.text.toString()
}
set(value) {
entryUrlView.setText(value)
if (fontInVisibility)
entryUrlView.applyFontVisibility()
}
var password: String
get() {
return entryPasswordView.text.toString()
}
set(value) {
entryPasswordView.setText(value)
if (fontInVisibility) {
entryPasswordView.applyFontVisibility()
}
}
var expires: Boolean
get() {
return entryExpirationView.expires
}
set(value) {
entryExpirationView.expires = value
}
var expiryTime: DateInstant
get() {
return entryExpirationView.expiryTime
}
set(value) {
entryExpirationView.expiryTime = value
}
var notes: String
get() {
return entryNotesView.text.toString()
}
set(value) {
entryNotesView.setText(value)
if (fontInVisibility)
entryNotesView.applyFontVisibility()
}
/* -------------
* Extra Fields
* -------------
*/
private var mExtraFieldsList: MutableList<Field> = ArrayList()
private var mOnEditButtonClickListener: ((item: Field)->Unit)? = null
private fun buildViewFromField(extraField: Field): View? {
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
val itemView: View? = inflater?.inflate(R.layout.item_entry_edit_extra_field, extraFieldsListView, false)
itemView?.id = View.NO_ID
val extraFieldValueContainer: TextInputLayout? = itemView?.findViewById(R.id.entry_extra_field_value_container)
extraFieldValueContainer?.endIconMode = if (extraField.protectedValue.isProtected)
TextInputLayout.END_ICON_PASSWORD_TOGGLE else TextInputLayout.END_ICON_NONE
extraFieldValueContainer?.hint = extraField.name
extraFieldValueContainer?.id = View.NO_ID
val extraFieldValue: TextInputEditText? = itemView?.findViewById(R.id.entry_extra_field_value)
extraFieldValue?.apply {
if (extraField.protectedValue.isProtected) {
inputType = extraFieldValue.inputType or EditorInfo.TYPE_TEXT_VARIATION_PASSWORD
}
setText(extraField.protectedValue.toString())
if (fontInVisibility)
applyFontVisibility()
}
extraFieldValue?.id = View.NO_ID
extraFieldValue?.tag = "FIELD_VALUE_TAG"
if (mLastFocusedEditField?.field == extraField) {
mExtraViewToRequestFocus = extraFieldValue
}
val extraFieldEditButton: View? = itemView?.findViewById(R.id.entry_extra_field_edit)
extraFieldEditButton?.setOnClickListener {
mOnEditButtonClickListener?.invoke(extraField)
}
extraFieldEditButton?.id = View.NO_ID
return itemView
}
fun getExtraFields(): List<Field> {
mLastFocusedEditField = null
for (index in 0 until extraFieldsListView.childCount) {
val extraFieldValue: EditText = extraFieldsListView.getChildAt(index)
.findViewWithTag("FIELD_VALUE_TAG")
val extraField = mExtraFieldsList[index]
extraField.protectedValue.stringValue = extraFieldValue.text?.toString() ?: ""
if (extraFieldValue.isFocused) {
mLastFocusedEditField = FocusedEditField().apply {
field = extraField
cursorSelectionStart = extraFieldValue.selectionStart
cursorSelectionEnd = extraFieldValue.selectionEnd
}
}
}
return mExtraFieldsList
}
/**
* Remove all children and add new views for each field
*/
fun assignExtraFields(fields: List<Field>,
onEditButtonClickListener: ((item: Field)->Unit)?) {
extraFieldsContainerView.visibility = if (fields.isEmpty()) View.GONE else View.VISIBLE
// Reinit focused field
mExtraFieldsList.clear()
mExtraFieldsList.addAll(fields)
extraFieldsListView.removeAllViews()
fields.forEach {
extraFieldsListView.addView(buildViewFromField(it))
}
// Request last focus
mLastFocusedEditField?.let { focusField ->
mExtraViewToRequestFocus?.apply {
requestFocus()
setSelection(focusField.cursorSelectionStart,
focusField.cursorSelectionEnd)
}
}
mLastFocusedEditField = null
mOnEditButtonClickListener = onEditButtonClickListener
}
/**
* Update an extra field or create a new one if doesn't exists, the old value is lost
*/
fun putExtraField(extraField: Field) {
extraFieldsContainerView.visibility = View.VISIBLE
val oldField = mExtraFieldsList.firstOrNull { it.name == extraField.name }
oldField?.let {
val index = mExtraFieldsList.indexOf(oldField)
mExtraFieldsList.removeAt(index)
mExtraFieldsList.add(index, extraField)
extraFieldsListView.removeViewAt(index)
val newView = buildViewFromField(extraField)
extraFieldsListView.addView(newView, index)
newView?.requestFocus()
} ?: kotlin.run {
mExtraFieldsList.add(extraField)
val newView = buildViewFromField(extraField)
extraFieldsListView.addView(newView)
newView?.requestFocus()
}
}
/**
* Update an extra field and keep the old value
*/
fun replaceExtraField(oldExtraField: Field, newExtraField: Field) {
extraFieldsContainerView.visibility = View.VISIBLE
val index = mExtraFieldsList.indexOf(oldExtraField)
val oldValueEditText: EditText = extraFieldsListView.getChildAt(index)
.findViewWithTag("FIELD_VALUE_TAG")
val oldValue = oldValueEditText.text.toString()
val newExtraFieldWithOldValue = Field(newExtraField).apply {
this.protectedValue.stringValue = oldValue
}
mExtraFieldsList.removeAt(index)
mExtraFieldsList.add(index, newExtraFieldWithOldValue)
extraFieldsListView.removeViewAt(index)
val newView = buildViewFromField(newExtraFieldWithOldValue)
extraFieldsListView.addView(newView, index)
newView?.requestFocus()
}
fun removeExtraField(oldExtraField: Field) {
val previousSize = mExtraFieldsList.size
val index = mExtraFieldsList.indexOf(oldExtraField)
extraFieldsListView.getChildAt(index)?.let {
it.collapse(true) {
mExtraFieldsList.removeAt(index)
extraFieldsListView.removeViewAt(index)
val newSize = mExtraFieldsList.size
if (previousSize > 0 && newSize == 0) {
extraFieldsContainerView.collapse(true)
} else if (previousSize == 0 && newSize == 1) {
extraFieldsContainerView.expand(true)
}
}
}
}
/* -------------
* Attachments
* -------------
*/
fun getAttachments(): List<Attachment> {
return attachmentsAdapter.itemsList.map { it.attachment }
}
fun assignAttachments(attachments: List<Attachment>,
streamDirection: StreamDirection,
onDeleteItem: (attachment: Attachment)->Unit) {
attachmentsContainerView.visibility = if (attachments.isEmpty()) View.GONE else View.VISIBLE
attachmentsAdapter.assignItems(attachments.map { EntryAttachmentState(it, streamDirection) })
attachmentsAdapter.onDeleteButtonClickListener = { item ->
onDeleteItem.invoke(item.attachment)
}
}
fun containsAttachment(): Boolean {
return !attachmentsAdapter.isEmpty()
}
fun containsAttachment(attachment: EntryAttachmentState): Boolean {
return attachmentsAdapter.contains(attachment)
}
fun putAttachment(attachment: EntryAttachmentState,
onPreviewLoaded: (()-> Unit)? = null) {
attachmentsContainerView.visibility = View.VISIBLE
attachmentsAdapter.putItem(attachment)
attachmentsAdapter.onBinaryPreviewLoaded = {
onPreviewLoaded?.invoke()
}
}
fun removeAttachment(attachment: EntryAttachmentState) {
attachmentsAdapter.removeItem(attachment)
}
fun clearAttachments() {
attachmentsAdapter.clear()
}
fun getAttachmentViewPosition(attachment: EntryAttachmentState, position: (Float) -> Unit) {
attachmentsListView.postDelayed({
position.invoke(attachmentsContainerView.y
+ attachmentsListView.y
+ (attachmentsListView.getChildAt(attachmentsAdapter.indexOf(attachment))?.y
?: 0F)
)
}, 250)
}
override fun onSaveInstanceState(outState: Bundle) {
populateEntryWithViews()
outState.putParcelable(KEY_TEMP_ENTRY_INFO, mEntryInfo)
outState.putParcelable(KEY_LAST_FOCUSED_FIELD, mLastFocusedEditField)
super.onSaveInstanceState(outState)
}
companion object {
const val KEY_TEMP_ENTRY_INFO = "KEY_TEMP_ENTRY_INFO"
const val KEY_DATABASE = "KEY_DATABASE"
const val KEY_LAST_FOCUSED_FIELD = "KEY_LAST_FOCUSED_FIELD"
fun getInstance(entryInfo: EntryInfo?): EntryEditFragment {
//database: Database?): EntryEditFragment {
return EntryEditFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_TEMP_ENTRY_INFO, entryInfo)
// TODO Unique database key database.key
putInt(KEY_DATABASE, 0)
}
}
}
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2021 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.fragments
import android.os.Bundle
import android.view.View
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
class IconCustomFragment : IconFragment<IconImageCustom>() {
override fun retrieveMainLayoutId(): Int {
return R.layout.fragment_icon_grid
}
override fun defineIconList() {
mDatabase?.doForEachCustomIcons { customIcon, _ ->
iconPickerAdapter.addIcon(customIcon, false)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
iconPickerViewModel.customIconsSelected.observe(viewLifecycleOwner) { customIconsSelected ->
if (customIconsSelected.isEmpty()) {
iconActionSelectionMode = false
iconPickerAdapter.deselectAllIcons()
} else {
iconActionSelectionMode = true
iconPickerAdapter.updateIconSelectedState(customIconsSelected)
}
}
iconPickerViewModel.customIconAdded.observe(viewLifecycleOwner) { iconCustomAdded ->
if (!iconCustomAdded.error) {
iconCustomAdded?.iconCustom?.let { icon ->
iconPickerAdapter.addIcon(icon)
iconCustomAdded.iconCustom = null
}
iconsGridView.smoothScrollToPosition(iconPickerAdapter.lastPosition)
}
}
iconPickerViewModel.customIconRemoved.observe(viewLifecycleOwner) { iconCustomRemoved ->
if (!iconCustomRemoved.error) {
iconCustomRemoved?.iconCustom?.let { icon ->
iconPickerAdapter.removeIcon(icon)
iconCustomRemoved.iconCustom = null
}
}
}
}
override fun onIconClickListener(icon: IconImageCustom) {
if (iconActionSelectionMode) {
// Same long click behavior after each single click
onIconLongClickListener(icon)
} else {
iconPickerViewModel.pickCustomIcon(icon)
}
}
override fun onIconLongClickListener(icon: IconImageCustom) {
// Select or deselect item if already selected
icon.selected = !icon.selected
iconPickerAdapter.updateIcon(icon)
iconActionSelectionMode = iconPickerAdapter.containsAnySelectedIcon()
iconPickerViewModel.selectCustomIcons(iconPickerAdapter.getSelectedIcons())
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2021 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.fragments
import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishFragment
import com.kunzisoft.keepass.adapters.IconPickerAdapter
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.icon.IconImageDraw
import com.kunzisoft.keepass.viewmodels.IconPickerViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
abstract class IconFragment<T: IconImageDraw> : StylishFragment(),
IconPickerAdapter.IconPickerListener<T> {
protected lateinit var iconsGridView: RecyclerView
protected lateinit var iconPickerAdapter: IconPickerAdapter<T>
protected var iconActionSelectionMode = false
protected var mDatabase: Database? = null
protected val iconPickerViewModel: IconPickerViewModel by activityViewModels()
abstract fun retrieveMainLayoutId(): Int
abstract fun defineIconList()
override fun onAttach(context: Context) {
super.onAttach(context)
mDatabase = Database.getInstance()
// Retrieve the textColor to tint the icon
val ta = contextThemed?.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
val tintColor = ta?.getColor(0, Color.BLACK) ?: Color.BLACK
ta?.recycle()
iconPickerAdapter = IconPickerAdapter<T>(context, tintColor).apply {
iconDrawableFactory = mDatabase?.iconDrawableFactory
}
CoroutineScope(Dispatchers.IO).launch {
val populateList = launch {
iconPickerAdapter.clear()
defineIconList()
}
withContext(Dispatchers.Main) {
populateList.join()
iconPickerAdapter.notifyDataSetChanged()
}
}
}
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View {
val root = inflater.inflate(retrieveMainLayoutId(), container, false)
iconsGridView = root.findViewById(R.id.icons_grid_view)
iconsGridView.adapter = iconPickerAdapter
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
iconPickerAdapter.iconPickerListener = this
}
fun onIconDeleteClicked() {
iconActionSelectionMode = false
}
}

View File

@@ -0,0 +1,77 @@
package com.kunzisoft.keepass.activities.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishFragment
import com.kunzisoft.keepass.adapters.IconPickerPagerAdapter
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.viewmodels.IconPickerViewModel
class IconPickerFragment : StylishFragment() {
private var iconPickerPagerAdapter: IconPickerPagerAdapter? = null
private lateinit var viewPager: ViewPager2
private val iconPickerViewModel: IconPickerViewModel by activityViewModels()
private var mDatabase: Database? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_icon_picker, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mDatabase = Database.getInstance()
viewPager = view.findViewById(R.id.icon_picker_pager)
val tabLayout = view.findViewById<TabLayout>(R.id.icon_picker_tabs)
iconPickerPagerAdapter = IconPickerPagerAdapter(this,
if (mDatabase?.allowCustomIcons == true) 2 else 1)
viewPager.adapter = iconPickerPagerAdapter
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = when (position) {
1 -> getString(R.string.icon_section_custom)
else -> getString(R.string.icon_section_standard)
}
}.attach()
arguments?.apply {
if (containsKey(ICON_TAB_ARG)) {
viewPager.currentItem = getInt(ICON_TAB_ARG)
}
remove(ICON_TAB_ARG)
}
iconPickerViewModel.customIconAdded.observe(viewLifecycleOwner) { _ ->
viewPager.currentItem = 1
}
}
enum class IconTab {
STANDARD, CUSTOM
}
companion object {
private const val ICON_TAB_ARG = "ICON_TAB_ARG"
fun getInstance(iconTab: IconTab): IconPickerFragment {
val fragment = IconPickerFragment()
fragment.arguments = Bundle().apply {
putInt(ICON_TAB_ARG, iconTab.ordinal)
}
return fragment
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2021 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.fragments
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
class IconStandardFragment : IconFragment<IconImageStandard>() {
override fun retrieveMainLayoutId(): Int {
return R.layout.fragment_icon_grid
}
override fun defineIconList() {
mDatabase?.doForEachStandardIcons { standardIcon ->
iconPickerAdapter.addIcon(standardIcon, false)
}
}
override fun onIconClickListener(icon: IconImageStandard) {
iconPickerViewModel.pickStandardIcon(icon)
}
override fun onIconLongClickListener(icon: IconImageStandard) {}
}

View File

@@ -0,0 +1,490 @@
/*
* 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.fragments
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.*
import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.EntryEditActivity
import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.activities.stylish.StylishFragment
import com.kunzisoft.keepass.adapters.NodeAdapter
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.SortNodeEnum
import com.kunzisoft.keepass.database.element.node.Node
import com.kunzisoft.keepass.database.element.node.Type
import com.kunzisoft.keepass.settings.PreferencesUtil
import java.util.*
class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionListener {
private var nodeClickListener: NodeClickListener? = null
private var onScrollListener: OnScrollListener? = null
private var mNodesRecyclerView: RecyclerView? = null
var mainGroup: Group? = null
private set
private var mAdapter: NodeAdapter? = null
var nodeActionSelectionMode = false
private set
var nodeActionPasteMode: PasteMode = PasteMode.UNDEFINED
private set
private val listActionNodes = LinkedList<Node>()
private val listPasteNodes = LinkedList<Node>()
private var notFoundView: View? = null
private var isASearchResult: Boolean = false
private var readOnly: Boolean = false
private var specialMode: SpecialMode = SpecialMode.DEFAULT
val isEmpty: Boolean
get() = mAdapter == null || mAdapter?.itemCount?:0 <= 0
override fun onAttach(context: Context) {
super.onAttach(context)
try {
nodeClickListener = context as NodeClickListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + NodeAdapter.NodeClickCallback::class.java.name)
}
try {
onScrollListener = context as OnScrollListener
} catch (e: ClassCastException) {
onScrollListener = null
// Context menu can be omit
Log.w(TAG, context.toString()
+ " must implement " + RecyclerView.OnScrollListener::class.java.name)
}
}
override fun onDetach() {
nodeClickListener = null
onScrollListener = null
super.onDetach()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrArguments(savedInstanceState, arguments)
arguments?.let { args ->
// Contains all the group in element
if (args.containsKey(GROUP_KEY)) {
mainGroup = args.getParcelable(GROUP_KEY)
}
if (args.containsKey(IS_SEARCH)) {
isASearchResult = args.getBoolean(IS_SEARCH)
}
}
contextThemed?.let { context ->
mAdapter = NodeAdapter(context)
mAdapter?.apply {
setOnNodeClickListener(object : NodeAdapter.NodeClickCallback {
override fun onNodeClick(node: Node) {
if (nodeActionSelectionMode) {
if (listActionNodes.contains(node)) {
// Remove selected item if already selected
listActionNodes.remove(node)
} else {
// Add selected item if not already selected
listActionNodes.add(node)
}
nodeClickListener?.onNodeSelected(listActionNodes)
setActionNodes(listActionNodes)
notifyNodeChanged(node)
} else {
nodeClickListener?.onNodeClick(node)
}
}
override fun onNodeLongClick(node: Node): Boolean {
if (nodeActionPasteMode == PasteMode.UNDEFINED) {
// Select the first item after a long click
if (!listActionNodes.contains(node))
listActionNodes.add(node)
nodeClickListener?.onNodeSelected(listActionNodes)
setActionNodes(listActionNodes)
notifyNodeChanged(node)
}
return true
}
})
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
super.onSaveInstanceState(outState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
// To apply theme
val rootView = inflater.cloneInContext(contextThemed)
.inflate(R.layout.fragment_list_nodes, container, false)
mNodesRecyclerView = rootView.findViewById(R.id.nodes_list)
notFoundView = rootView.findViewById(R.id.not_found_container)
mNodesRecyclerView?.apply {
scrollBarStyle = View.SCROLLBARS_INSIDE_INSET
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
}
onScrollListener?.let { onScrollListener ->
mNodesRecyclerView?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
onScrollListener.onScrolled(dy)
}
})
}
return rootView
}
override fun onResume() {
super.onResume()
activity?.intent?.let {
specialMode = EntrySelectionHelper.retrieveSpecialModeFromIntent(it)
}
// Refresh data
try {
rebuildList()
} catch (e: Exception) {
Log.e(TAG, "Unable to rebuild the list during resume")
e.printStackTrace()
}
if (isASearchResult && mAdapter!= null && mAdapter!!.isEmpty) {
// To show the " no search entry found "
mNodesRecyclerView?.visibility = View.GONE
notFoundView?.visibility = View.VISIBLE
} else {
mNodesRecyclerView?.visibility = View.VISIBLE
notFoundView?.visibility = View.GONE
}
}
@Throws(IllegalArgumentException::class)
fun rebuildList() {
// Add elements to the list
mainGroup?.let { mainGroup ->
mAdapter?.apply {
// Thrown an exception when sort cannot be performed
rebuildList(mainGroup)
// To visually change the elements
if (PreferencesUtil.APPEARANCE_CHANGED) {
notifyDataSetChanged()
PreferencesUtil.APPEARANCE_CHANGED = false
}
}
}
}
override fun onSortSelected(sortNodeEnum: SortNodeEnum,
sortNodeParameters: SortNodeEnum.SortNodeParameters) {
// Save setting
context?.let {
PreferencesUtil.saveNodeSort(it, sortNodeEnum, sortNodeParameters)
}
// Tell the adapter to refresh it's list
try {
mAdapter?.notifyChangeSort(sortNodeEnum, sortNodeParameters)
rebuildList()
} catch (e:Exception) {
Log.e(TAG, "Unable to rebuild the list with the sort")
e.printStackTrace()
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.tree, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_sort -> {
context?.let { context ->
val sortDialogFragment: SortDialogFragment =
if (Database.getInstance().isRecycleBinEnabled) {
SortDialogFragment.getInstance(
PreferencesUtil.getListSort(context),
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context),
PreferencesUtil.getRecycleBinBottomSort(context))
} else {
SortDialogFragment.getInstance(
PreferencesUtil.getListSort(context),
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context))
}
sortDialogFragment.show(childFragmentManager, "sortDialog")
}
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
fun actionNodesCallback(nodes: List<Node>,
menuListener: NodesActionMenuListener?,
actionModeCallback: ActionMode.Callback) : ActionMode.Callback {
return object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
nodeActionSelectionMode = false
nodeActionPasteMode = PasteMode.UNDEFINED
return actionModeCallback.onCreateActionMode(mode, menu)
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menu?.clear()
if (nodeActionPasteMode != PasteMode.UNDEFINED) {
mode?.menuInflater?.inflate(R.menu.node_paste_menu, menu)
} else {
nodeActionSelectionMode = true
mode?.menuInflater?.inflate(R.menu.node_menu, menu)
val database = Database.getInstance()
// Open and Edit for a single item
if (nodes.size == 1) {
// Edition
if (readOnly
|| (database.isRecycleBinEnabled && nodes[0] == database.recycleBin)) {
menu?.removeItem(R.id.menu_edit)
}
} else {
menu?.removeItem(R.id.menu_open)
menu?.removeItem(R.id.menu_edit)
}
// Move
if (readOnly
|| isASearchResult) {
menu?.removeItem(R.id.menu_move)
}
// Copy (not allowed for group)
if (readOnly
|| isASearchResult
|| nodes.any { it.type == Type.GROUP }) {
menu?.removeItem(R.id.menu_copy)
}
// Deletion
if (readOnly
|| (database.isRecycleBinEnabled && nodes.any { it == database.recycleBin })) {
menu?.removeItem(R.id.menu_delete)
}
}
// Add the number of items selected in title
mode?.title = nodes.size.toString()
return actionModeCallback.onPrepareActionMode(mode, menu)
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
if (menuListener == null)
return false
return when (item?.itemId) {
R.id.menu_open -> menuListener.onOpenMenuClick(nodes[0])
R.id.menu_edit -> menuListener.onEditMenuClick(nodes[0])
R.id.menu_copy -> {
nodeActionPasteMode = PasteMode.PASTE_FROM_COPY
mAdapter?.unselectActionNodes()
val returnValue = menuListener.onCopyMenuClick(nodes)
nodeActionSelectionMode = false
returnValue
}
R.id.menu_move -> {
nodeActionPasteMode = PasteMode.PASTE_FROM_MOVE
mAdapter?.unselectActionNodes()
val returnValue = menuListener.onMoveMenuClick(nodes)
nodeActionSelectionMode = false
returnValue
}
R.id.menu_delete -> menuListener.onDeleteMenuClick(nodes)
R.id.menu_paste -> {
val returnValue = menuListener.onPasteMenuClick(nodeActionPasteMode, nodes)
nodeActionPasteMode = PasteMode.UNDEFINED
nodeActionSelectionMode = false
returnValue
}
else -> actionModeCallback.onActionItemClicked(mode, item)
}
}
override fun onDestroyActionMode(mode: ActionMode?) {
listActionNodes.clear()
listPasteNodes.clear()
mAdapter?.unselectActionNodes()
nodeActionPasteMode = PasteMode.UNDEFINED
nodeActionSelectionMode = false
actionModeCallback.onDestroyActionMode(mode)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE -> {
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE
|| resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) {
data?.getParcelableExtra<Node>(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY)?.let { changedNode ->
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE)
addNode(changedNode)
if (resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE)
mAdapter?.notifyDataSetChanged()
} ?: Log.e(this.javaClass.name, "New node can be retrieve in Activity Result")
}
}
}
}
fun contains(node: Node): Boolean {
return mAdapter?.contains(node) ?: false
}
fun addNode(newNode: Node) {
mAdapter?.addNode(newNode)
}
fun addNodes(newNodes: List<Node>) {
mAdapter?.addNodes(newNodes)
}
fun updateNode(oldNode: Node, newNode: Node? = null) {
mAdapter?.updateNode(oldNode, newNode ?: oldNode)
}
fun updateNodes(oldNodes: List<Node>, newNodes: List<Node>) {
mAdapter?.updateNodes(oldNodes, newNodes)
}
fun removeNode(pwNode: Node) {
mAdapter?.removeNode(pwNode)
}
fun removeNodes(nodes: List<Node>) {
mAdapter?.removeNodes(nodes)
}
fun removeNodeAt(position: Int) {
mAdapter?.removeNodeAt(position)
}
fun removeNodesAt(positions: IntArray) {
mAdapter?.removeNodesAt(positions)
}
/**
* Callback listener to redefine to do an action when a node is click
*/
interface NodeClickListener {
fun onNodeClick(node: Node)
fun onNodeSelected(nodes: List<Node>): Boolean
}
/**
* Menu listener to redefine to do an action in menu
*/
interface NodesActionMenuListener {
fun onOpenMenuClick(node: Node): Boolean
fun onEditMenuClick(node: Node): Boolean
fun onCopyMenuClick(nodes: List<Node>): Boolean
fun onMoveMenuClick(nodes: List<Node>): Boolean
fun onDeleteMenuClick(nodes: List<Node>): Boolean
fun onPasteMenuClick(pasteMode: PasteMode?, nodes: List<Node>): Boolean
}
enum class PasteMode {
UNDEFINED, PASTE_FROM_COPY, PASTE_FROM_MOVE
}
interface OnScrollListener {
/**
* Callback method to be invoked when the RecyclerView has been scrolled. This will be
* called after the scroll has completed.
*
* @param dy The amount of vertical scroll.
*/
fun onScrolled(dy: Int)
}
companion object {
private val TAG = ListNodesFragment::class.java.name
private const val GROUP_KEY = "GROUP_KEY"
private const val IS_SEARCH = "IS_SEARCH"
fun newInstance(group: Group?, readOnly: Boolean, isASearch: Boolean): ListNodesFragment {
val bundle = Bundle()
if (group != null) {
bundle.putParcelable(GROUP_KEY, group)
}
bundle.putBoolean(IS_SEARCH, isASearch)
ReadOnlyHelper.putReadOnlyInBundle(bundle, readOnly)
val listNodesFragment = ListNodesFragment()
listNodesFragment.arguments = bundle
return listNodesFragment
}
}
}

View File

@@ -1,51 +1,209 @@
/*
* 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.helpers
import android.app.Activity
import android.app.assist.AssistStructure
import android.content.Context
import android.content.Intent
import android.os.Build
import com.kunzisoft.keepass.autofill.AutofillComponent
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.model.RegisterInfo
import com.kunzisoft.keepass.model.SearchInfo
import java.io.Serializable
object EntrySelectionHelper {
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 KEY_SPECIAL_MODE = "com.kunzisoft.keepass.extra.SPECIAL_MODE"
private const val KEY_TYPE_MODE = "com.kunzisoft.keepass.extra.TYPE_MODE"
private const val KEY_SEARCH_INFO = "com.kunzisoft.keepass.extra.SEARCH_INFO"
private const val KEY_REGISTER_INFO = "com.kunzisoft.keepass.extra.REGISTER_INFO"
fun startActivityForEntrySelection(activity: Activity, intent: Intent) {
addEntrySelectionModeExtraInIntent(intent)
// only to avoid visible flickering when redirecting
activity.startActivity(intent)
fun startActivityForSearchModeResult(context: Context,
intent: Intent,
searchInfo: SearchInfo) {
addSpecialModeInIntent(intent, SpecialMode.SEARCH)
addSearchInfoInIntent(intent, searchInfo)
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent)
}
fun addEntrySelectionModeExtraInIntent(intent: Intent) {
intent.putExtra(EXTRA_ENTRY_SELECTION_MODE, true)
fun startActivityForSaveModeResult(context: Context,
intent: Intent,
searchInfo: SearchInfo) {
addSpecialModeInIntent(intent, SpecialMode.SAVE)
addTypeModeInIntent(intent, TypeMode.DEFAULT)
addSearchInfoInIntent(intent, searchInfo)
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent)
}
fun removeEntrySelectionModeFromIntent(intent: Intent) {
intent.removeExtra(EXTRA_ENTRY_SELECTION_MODE)
fun startActivityForKeyboardSelectionModeResult(context: Context,
intent: Intent,
searchInfo: SearchInfo?) {
addSpecialModeInIntent(intent, SpecialMode.SELECTION)
addTypeModeInIntent(intent, TypeMode.MAGIKEYBOARD)
addSearchInfoInIntent(intent, searchInfo)
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent)
}
fun retrieveEntrySelectionModeFromIntent(intent: Intent): Boolean {
return intent.getBooleanExtra(EXTRA_ENTRY_SELECTION_MODE, DEFAULT_ENTRY_SELECTION_MODE)
fun startActivityForRegistrationModeResult(context: Context,
intent: Intent,
registerInfo: RegisterInfo?) {
addSpecialModeInIntent(intent, SpecialMode.REGISTRATION)
// At the moment, only autofill for registration
addTypeModeInIntent(intent, TypeMode.AUTOFILL)
addRegisterInfoInIntent(intent, registerInfo)
intent.flags = intent.flags or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent)
}
fun doEntrySelectionAction(intent: Intent,
standardAction: () -> Unit,
keyboardAction: () -> Unit,
autofillAction: (assistStructure: AssistStructure) -> Unit) {
var assistStructureInit = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AutofillHelper.retrieveAssistStructure(intent)?.let { assistStructure ->
autofillAction.invoke(assistStructure)
assistStructureInit = true
}
fun addSearchInfoInIntent(intent: Intent, searchInfo: SearchInfo?) {
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
if (!assistStructureInit) {
if (intent.getBooleanExtra(EXTRA_ENTRY_SELECTION_MODE, DEFAULT_ENTRY_SELECTION_MODE)) {
intent.removeExtra(EXTRA_ENTRY_SELECTION_MODE)
keyboardAction.invoke()
} else {
standardAction.invoke()
}
fun retrieveSearchInfoFromIntent(intent: Intent): SearchInfo? {
return intent.getParcelableExtra(KEY_SEARCH_INFO)
}
fun addRegisterInfoInIntent(intent: Intent, registerInfo: RegisterInfo?) {
registerInfo?.let {
intent.putExtra(KEY_REGISTER_INFO, it)
}
}
fun retrieveRegisterInfoFromIntent(intent: Intent): RegisterInfo? {
return intent.getParcelableExtra(KEY_REGISTER_INFO)
}
fun removeInfoFromIntent(intent: Intent) {
intent.removeExtra(KEY_SEARCH_INFO)
intent.removeExtra(KEY_REGISTER_INFO)
}
fun addSpecialModeInIntent(intent: Intent, specialMode: SpecialMode) {
intent.putExtra(KEY_SPECIAL_MODE, specialMode as Serializable)
}
fun retrieveSpecialModeFromIntent(intent: Intent): SpecialMode {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (AutofillHelper.retrieveAutofillComponent(intent) != null)
return SpecialMode.SELECTION
}
return intent.getSerializableExtra(KEY_SPECIAL_MODE) as SpecialMode?
?: SpecialMode.DEFAULT
}
fun addTypeModeInIntent(intent: Intent, typeMode: TypeMode) {
intent.putExtra(KEY_TYPE_MODE, typeMode as Serializable)
}
fun retrieveTypeModeFromIntent(intent: Intent): TypeMode {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (AutofillHelper.retrieveAutofillComponent(intent) != null)
return TypeMode.AUTOFILL
}
return intent.getSerializableExtra(KEY_TYPE_MODE) as TypeMode? ?: TypeMode.DEFAULT
}
fun removeModesFromIntent(intent: Intent) {
intent.removeExtra(KEY_SPECIAL_MODE)
intent.removeExtra(KEY_TYPE_MODE)
}
fun doSpecialAction(intent: Intent,
defaultAction: () -> Unit,
searchAction: (searchInfo: SearchInfo) -> Unit,
saveAction: (searchInfo: SearchInfo) -> Unit,
keyboardSelectionAction: (searchInfo: SearchInfo?) -> Unit,
autofillSelectionAction: (searchInfo: SearchInfo?,
autofillComponent: AutofillComponent) -> Unit,
autofillRegistrationAction: (registerInfo: RegisterInfo?) -> Unit) {
when (retrieveSpecialModeFromIntent(intent)) {
SpecialMode.DEFAULT -> {
removeModesFromIntent(intent)
removeInfoFromIntent(intent)
defaultAction.invoke()
}
SpecialMode.SEARCH -> {
val searchInfo = retrieveSearchInfoFromIntent(intent)
removeModesFromIntent(intent)
removeInfoFromIntent(intent)
if (searchInfo != null)
searchAction.invoke(searchInfo)
else {
defaultAction.invoke()
}
}
SpecialMode.SAVE -> {
val searchInfo = retrieveSearchInfoFromIntent(intent)
removeModesFromIntent(intent)
removeInfoFromIntent(intent)
if (searchInfo != null)
saveAction.invoke(searchInfo)
else {
defaultAction.invoke()
}
}
SpecialMode.SELECTION -> {
val searchInfo: SearchInfo? = retrieveSearchInfoFromIntent(intent)
var autofillComponentInit = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AutofillHelper.retrieveAutofillComponent(intent)?.let { autofillComponent ->
autofillSelectionAction.invoke(searchInfo, autofillComponent)
autofillComponentInit = true
}
}
if (!autofillComponentInit) {
if (intent.getSerializableExtra(KEY_SPECIAL_MODE) != null) {
when (retrieveTypeModeFromIntent(intent)) {
TypeMode.DEFAULT -> {
removeModesFromIntent(intent)
if (searchInfo != null)
searchAction.invoke(searchInfo)
else
defaultAction.invoke()
}
TypeMode.MAGIKEYBOARD -> keyboardSelectionAction.invoke(searchInfo)
else -> {
// In this case, error
removeModesFromIntent(intent)
removeInfoFromIntent(intent)
}
}
} else {
if (searchInfo != null)
searchAction.invoke(searchInfo)
else
defaultAction.invoke()
}
}
}
SpecialMode.REGISTRATION -> {
val registerInfo: RegisterInfo? = retrieveRegisterInfoFromIntent(intent)
removeModesFromIntent(intent)
removeInfoFromIntent(intent)
autofillRegistrationAction.invoke(registerInfo)
}
}
}

View File

@@ -0,0 +1,254 @@
/*
* 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.helpers
import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.util.Log
import android.view.View
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.kunzisoft.keepass.activities.dialogs.FileManagerDialogFragment
import com.kunzisoft.keepass.utils.UriUtil
class ExternalFileHelper {
private var activity: FragmentActivity? = null
private var fragment: Fragment? = null
constructor(context: FragmentActivity) {
this.activity = context
this.fragment = null
}
constructor(context: Fragment) {
this.activity = context.activity
this.fragment = context
}
fun openDocument(getContent: Boolean = false,
typeString: String = "*/*") {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
if (getContent) {
openActivityWithActionGetContent(typeString)
} else {
openActivityWithActionOpenDocument(typeString)
}
} catch (e: Exception) {
Log.e(TAG, "Unable to open document", e)
showFileManagerDialogFragment()
}
} else {
showFileManagerDialogFragment()
}
}
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun openActivityWithActionOpenDocument(typeString: String) {
val intentOpenDocument = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = typeString
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
}
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
if (fragment != null)
fragment?.startActivityForResult(intentOpenDocument, OPEN_DOC)
else
activity?.startActivityForResult(intentOpenDocument, OPEN_DOC)
}
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun openActivityWithActionGetContent(typeString: String) {
val intentGetContent = Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = typeString
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
}
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
if (fragment != null)
fragment?.startActivityForResult(intentGetContent, GET_CONTENT)
else
activity?.startActivityForResult(intentGetContent, GET_CONTENT)
}
/**
* To use in onActivityResultCallback in Fragment or Activity
* @param onFileSelected Callback retrieve from data
* @return true if requestCode was captured, false elsewhere
*/
fun onOpenDocumentResult(requestCode: Int, resultCode: Int, data: Intent?,
onFileSelected: ((uri: Uri?) -> Unit)?): Boolean {
when (requestCode) {
FILE_BROWSE -> {
if (resultCode == RESULT_OK) {
val filename = data?.dataString
var keyUri: Uri? = null
if (filename != null) {
keyUri = UriUtil.parse(filename)
}
onFileSelected?.invoke(keyUri)
}
return true
}
GET_CONTENT, OPEN_DOC -> {
if (resultCode == RESULT_OK) {
if (data != null) {
val uri = data.data
if (uri != null) {
try {
// try to persist read and write permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity?.contentResolver?.apply {
takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
}
} catch (e: Exception) {
// nop
}
onFileSelected?.invoke(uri)
}
}
}
return true
}
}
return false
}
/**
* Show Browser dialog to select file picker app
*/
private fun showFileManagerDialogFragment() {
try {
if (fragment != null) {
fragment?.parentFragmentManager
} else {
activity?.supportFragmentManager
}?.let { fragmentManager ->
FileManagerDialogFragment().show(fragmentManager, "browserDialog")
}
} catch (e: Exception) {
Log.e(TAG, "Can't open BrowserDialog", e)
}
}
fun createDocument(titleString: String,
typeString: String = "application/octet-stream"): Int? {
val idCode = getUnusedCreateFileRequestCode()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = typeString
putExtra(Intent.EXTRA_TITLE, titleString)
}
if (fragment != null)
fragment?.startActivityForResult(intent, idCode)
else
activity?.startActivityForResult(intent, idCode)
return idCode
} catch (e: Exception) {
Log.e(TAG, "Unable to create document", e)
showFileManagerDialogFragment()
}
} else {
showFileManagerDialogFragment()
}
return null
}
/**
* To use in onActivityResultCallback in Fragment or Activity
* @param onFileCreated Callback retrieve from data
* @return true if requestCode was captured, false elsewhere
*/
fun onCreateDocumentResult(requestCode: Int, resultCode: Int, data: Intent?,
onFileCreated: (fileCreated: Uri?)->Unit) {
// Retrieve the created URI from the file manager
if (fileRequestCodes.contains(requestCode) && resultCode == RESULT_OK) {
onFileCreated.invoke(data?.data)
fileRequestCodes.remove(requestCode)
}
}
companion object {
private const val TAG = "OpenFileHelper"
private const val GET_CONTENT = 25745
private const val OPEN_DOC = 25845
private const val FILE_BROWSE = 25645
private var CREATE_FILE_REQUEST_CODE_DEFAULT = 3853
private var fileRequestCodes = ArrayList<Int>()
private fun getUnusedCreateFileRequestCode(): Int {
val newCreateFileRequestCode = CREATE_FILE_REQUEST_CODE_DEFAULT++
fileRequestCodes.add(newCreateFileRequestCode)
return newCreateFileRequestCode
}
@SuppressLint("InlinedApi")
fun allowCreateDocumentByStorageAccessFramework(packageManager: PackageManager,
typeString: String = "application/octet-stream"): Boolean {
return when {
// To check if a custom file manager can manage the ACTION_CREATE_DOCUMENT
Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT -> {
packageManager.queryIntentActivities(Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = typeString
}, PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty()
}
else -> true
}
}
}
}
fun View.setOpenDocumentClickListener(externalFileHelper: ExternalFileHelper?) {
externalFileHelper?.let { fileHelper ->
setOnClickListener {
fileHelper.openDocument()
}
setOnLongClickListener {
fileHelper.openDocument(true)
true
}
} ?: kotlin.run {
setOnClickListener(null)
setOnLongClickListener(null)
}
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.helpers
import android.app.Activity
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import android.util.Log
import android.view.View
import com.kunzisoft.keepass.activities.dialogs.BrowserDialogFragment
import com.kunzisoft.keepass.utils.UriUtil
class OpenFileHelper {
private var activity: Activity? = null
private var fragment: Fragment? = null
val openFileOnClickViewListener: OpenFileOnClickViewListener
get() = OpenFileOnClickViewListener(null)
constructor(context: Activity) {
this.activity = context
this.fragment = null
}
constructor(context: Fragment) {
this.activity = context.activity
this.fragment = context
}
inner class OpenFileOnClickViewListener(private val dataUri: (() -> Uri?)?) : View.OnClickListener {
override fun onClick(v: View) {
try {
try {
openActivityWithActionOpenDocument()
} catch(e: Exception) {
openActivityWithActionGetContent()
}
} catch (e: Exception) {
Log.e(TAG, "Enable to start the file picker activity", e)
// Open File picker if can't open activity
if (lookForOpenIntentsFilePicker(dataUri?.invoke()))
showBrowserDialog()
}
}
}
private fun openActivityWithActionOpenDocument() {
val i = Intent(ACTION_OPEN_DOCUMENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "*/*"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
i.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
} else {
i.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
}
if (fragment != null)
fragment?.startActivityForResult(i, OPEN_DOC)
else
activity?.startActivityForResult(i, OPEN_DOC)
}
private fun openActivityWithActionGetContent() {
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "*/*"
if (fragment != null)
fragment?.startActivityForResult(i, GET_CONTENT)
else
activity?.startActivityForResult(i, GET_CONTENT)
}
fun getOpenFileOnClickViewListener(dataUri: () -> Uri?): OpenFileOnClickViewListener {
return OpenFileOnClickViewListener(dataUri)
}
private fun lookForOpenIntentsFilePicker(dataUri: Uri?): Boolean {
var showBrowser = false
try {
if (isIntentAvailable(activity!!, OPEN_INTENTS_FILE_BROWSE)) {
val intent = Intent(OPEN_INTENTS_FILE_BROWSE)
// Get file path parent if possible
if (dataUri != null
&& dataUri.toString().isNotEmpty()
&& dataUri.scheme == "file") {
intent.data = dataUri
} else {
Log.w(javaClass.name, "Unable to read the URI")
}
if (fragment != null)
fragment?.startActivityForResult(intent, FILE_BROWSE)
else
activity?.startActivityForResult(intent, FILE_BROWSE)
} else {
showBrowser = true
}
} catch (e: Exception) {
Log.w(TAG, "Enable to start OPEN_INTENTS_FILE_BROWSE", e)
showBrowser = true
}
return showBrowser
}
/**
* Indicates whether the specified action can be used as an intent. This
* method queries the package manager for installed packages that can
* respond to an intent with the specified action. If no suitable package is
* found, this method returns false.
*
* @param context The application's environment.
* @param action The Intent action to check for availability.
*
* @return True if an Intent with the specified action can be sent and
* responded to, false otherwise.
*/
private fun isIntentAvailable(context: Context, action: String): Boolean {
val packageManager = context.packageManager
val intent = Intent(action)
val list = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY)
return list.size > 0
}
/**
* Show Browser dialog to select file picker app
*/
private fun showBrowserDialog() {
try {
val browserDialogFragment = BrowserDialogFragment()
if (fragment != null && fragment!!.fragmentManager != null)
browserDialogFragment.show(fragment!!.fragmentManager!!, "browserDialog")
else
browserDialogFragment.show((activity as FragmentActivity).supportFragmentManager, "browserDialog")
} catch (e: Exception) {
Log.e(TAG, "Can't open BrowserDialog", e)
}
}
/**
* To use in onActivityResultCallback in Fragment or Activity
* @param keyFileCallback Callback retrieve from data
* @return true if requestCode was captured, false elsechere
*/
fun onActivityResultCallback(
requestCode: Int,
resultCode: Int,
data: Intent?,
keyFileCallback: ((uri: Uri?) -> Unit)?): Boolean {
when (requestCode) {
FILE_BROWSE -> {
if (resultCode == RESULT_OK) {
val filename = data?.dataString
var keyUri: Uri? = null
if (filename != null) {
keyUri = UriUtil.parse(filename)
}
keyFileCallback?.invoke(keyUri)
}
return true
}
GET_CONTENT, OPEN_DOC -> {
if (resultCode == RESULT_OK) {
if (data != null) {
var uri = data.data
if (uri != null) {
try {
// try to persist read and write permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity?.contentResolver?.apply {
takePersistableUriPermission(uri!!, Intent.FLAG_GRANT_READ_URI_PERMISSION)
takePersistableUriPermission(uri!!, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
}
} catch (e: Exception) {
// nop
}
if (requestCode == GET_CONTENT) {
uri = UriUtil.translateUri(activity!!, uri)
}
keyFileCallback?.invoke(uri)
}
}
}
return true
}
}
return false
}
companion object {
private const val TAG = "OpenFileHelper"
private var ACTION_OPEN_DOCUMENT: String
init {
ACTION_OPEN_DOCUMENT = try {
val openDocument = Intent::class.java.getField("ACTION_OPEN_DOCUMENT")
openDocument.get(null) as String
} catch (e: Exception) {
"android.intent.action.OPEN_DOCUMENT"
}
}
const val OPEN_INTENTS_FILE_BROWSE = "org.openintents.action.PICK_FILE"
private const val GET_CONTENT = 25745
private const val OPEN_DOC = 25845
private const val FILE_BROWSE = 25645
}
}

View File

@@ -1,3 +1,22 @@
/*
* 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.helpers
import android.content.Context

View File

@@ -0,0 +1,9 @@
package com.kunzisoft.keepass.activities.helpers
enum class SpecialMode {
DEFAULT,
SEARCH,
SAVE,
SELECTION,
REGISTRATION;
}

View File

@@ -0,0 +1,5 @@
package com.kunzisoft.keepass.activities.helpers
enum class TypeMode {
DEFAULT, MAGIKEYBOARD, AUTOFILL
}

View File

@@ -1,55 +1,44 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.lock
import android.app.Activity
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
import com.kunzisoft.keepass.database.action.ProgressDatabaseTaskProvider
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.LOCK_ACTION
import com.kunzisoft.keepass.utils.*
abstract class LockingActivity : StylishActivity() {
companion object {
private const val TAG = "LockingActivity"
const val RESULT_EXIT_LOCK = 1450
const val TIMEOUT_ENABLE_KEY = "TIMEOUT_ENABLE_KEY"
const val TIMEOUT_ENABLE_KEY_DEFAULT = true
}
abstract class LockingActivity : SpecialModeActivity() {
protected var mTimeoutEnable: Boolean = true
@@ -57,13 +46,23 @@ abstract class LockingActivity : StylishActivity() {
private var mExitLock: Boolean = false
// Force readOnly if Entry Selection mode
protected var mReadOnly: Boolean = false
protected var mReadOnly: Boolean
get() {
return field || mSelectionMode
return mReadOnlyToSave
}
protected var mSelectionMode: Boolean = false
set(value) {
mReadOnlyToSave = value
}
private var mReadOnlyToSave: Boolean = false
protected var mAutoSaveEnable: Boolean = true
var mProgressDatabaseTaskProvider: ProgressDatabaseTaskProvider? = null
private set
override fun onCreate(savedInstanceState: Bundle?) {
mProgressDatabaseTaskProvider = ProgressDatabaseTaskProvider(this)
super.onCreate(savedInstanceState)
if (savedInstanceState != null
@@ -75,16 +74,19 @@ abstract class LockingActivity : StylishActivity() {
}
if (mTimeoutEnable) {
mLockReceiver = LockReceiver()
val intentFilter = IntentFilter().apply {
addAction(Intent.ACTION_SCREEN_OFF)
addAction(LOCK_ACTION)
mLockReceiver = LockReceiver {
closeDatabase()
if (LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == null)
LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK = LOCKING_ACTIVITY_UI_VISIBLE
// Add onActivityForResult response
setResult(RESULT_EXIT_LOCK)
closeOptionsMenu()
finish()
}
registerReceiver(mLockReceiver, intentFilter)
registerLockReceiver(mLockReceiver)
}
mExitLock = false
mReadOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrIntent(savedInstanceState, intent)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -100,8 +102,22 @@ abstract class LockingActivity : StylishActivity() {
override fun onResume() {
super.onResume()
// If in ave or registration mode, don't allow read only
if ((mSpecialMode == SpecialMode.SAVE
|| mSpecialMode == SpecialMode.REGISTRATION)
&& mReadOnly) {
Toast.makeText(this, R.string.error_registration_read_only , Toast.LENGTH_LONG).show()
EntrySelectionHelper.removeModesFromIntent(intent)
finish()
}
mProgressDatabaseTaskProvider?.registerProgressTask()
// To refresh when back to normal workflow from selection workflow
mSelectionMode = EntrySelectionHelper.retrieveEntrySelectionModeFromIntent(intent)
mReadOnlyToSave = ReadOnlyHelper.retrieveReadOnlyFromIntent(intent)
mAutoSaveEnable = PreferencesUtil.isAutoSaveDatabaseEnabled(this)
invalidateOptionsMenu()
if (mTimeoutEnable) {
// End activity if database not loaded
@@ -119,16 +135,19 @@ abstract class LockingActivity : StylishActivity() {
TimeoutHelper.recordTime(this)
}
invalidateOptionsMenu()
LOCKING_ACTIVITY_UI_VISIBLE = true
}
override fun onSaveInstanceState(outState: Bundle) {
ReadOnlyHelper.onSaveInstanceState(outState, mReadOnly)
outState.putBoolean(TIMEOUT_ENABLE_KEY, mTimeoutEnable)
super.onSaveInstanceState(outState)
}
override fun onPause() {
LOCKING_ACTIVITY_UI_VISIBLE = false
mProgressDatabaseTaskProvider?.unregisterProgressTask()
super.onPause()
if (mTimeoutEnable) {
@@ -138,49 +157,12 @@ abstract class LockingActivity : StylishActivity() {
}
override fun onDestroy() {
unregisterLockReceiver(mLockReceiver)
super.onDestroy()
if (mLockReceiver != null)
unregisterReceiver(mLockReceiver)
}
inner class LockReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// If allowed, lock and exit
if (!TimeoutHelper.temporarilyDisableTimeout) {
intent.action?.let {
when (it) {
Intent.ACTION_SCREEN_OFF -> if (PreferencesUtil.isLockDatabaseWhenScreenShutOffEnable(this@LockingActivity)) {
lockAndExit()
}
LOCK_ACTION -> lockAndExit()
}
}
}
}
}
protected fun lockAndExit() {
lock()
}
/**
* To reset the app timeout when a view is focused or changed
*/
protected fun resetAppTimeoutWhenViewFocusedOrChanged(vararg views: View?) {
views.forEach {
it?.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
Log.d(TAG, "View focused, reset app timeout")
TimeoutHelper.checkTimeAndLockIfTimeoutOrResetTimeout(this)
}
}
if (it is ViewGroup) {
for (i in 0..it.childCount) {
resetAppTimeoutWhenViewFocusedOrChanged(it.getChildAt(i))
}
}
}
sendBroadcast(Intent(LOCK_ACTION))
}
override fun onBackPressed() {
@@ -192,21 +174,42 @@ abstract class LockingActivity : StylishActivity() {
super.onBackPressed()
}
}
}
fun Activity.lock() {
// Stop the Magikeyboard service
stopService(Intent(this, KeyboardEntryNotificationService::class.java))
MagikIME.removeEntry(this)
companion object {
Log.i(Activity::class.java.name, "Shutdown " + localClassName +
" after inactivity or manual lock")
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).apply {
cancelAll()
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
}
}
/**
* To reset the app timeout when a view is focused or changed
*/
@SuppressLint("ClickableViewAccessibility")
fun View.resetAppTimeoutWhenViewFocusedOrChanged(context: Context) {
setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//Log.d(LockingActivity.TAG, "View touched, try to reset app timeout")
TimeoutHelper.checkTimeAndLockIfTimeoutOrResetTimeout(context)
}
}
false
}
setOnFocusChangeListener { _, _ ->
//Log.d(LockingActivity.TAG, "View focused, try to reset app timeout")
TimeoutHelper.checkTimeAndLockIfTimeoutOrResetTimeout(context)
}
if (this is ViewGroup) {
for (i in 0..childCount) {
getChildAt(i)?.resetAppTimeoutWhenViewFocusedOrChanged(context)
}
}
// Clear data
Database.getInstance().closeAndClear(applicationContext.filesDir)
// Add onActivityForResult response
setResult(LockingActivity.RESULT_EXIT_LOCK)
finish()
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX 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.
*
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.lock
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.view.WindowManager
/**
* Locking Hide Activity that sets FLAG_SECURE to prevent screenshots, and from
* appearing in the recent app preview
*/
abstract class LockingHideActivity : LockingActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Several gingerbread devices have problems with FLAG_SECURE
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
}
/* (non-Javadoc) Workaround for HTC Linkify issues
* @see android.app.Activity#startActivity(android.content.Intent)
*/
override fun startActivity(intent: Intent) {
try {
if (intent.component != null && intent.component!!.shortClassName == ".HtcLinkifyDispatcherActivity") {
intent.component = null
}
super.startActivity(intent)
} catch (e: ActivityNotFoundException) {
/* Catch the bad HTC implementation case */
super.startActivity(Intent.createChooser(intent, null))
}
}
}

View File

@@ -0,0 +1,185 @@
package com.kunzisoft.keepass.activities.selection
import android.os.Bundle
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.helpers.SpecialMode
import com.kunzisoft.keepass.activities.helpers.TypeMode
import com.kunzisoft.keepass.activities.stylish.StylishActivity
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 mSpecialMode: SpecialMode = SpecialMode.DEFAULT
private var mTypeMode: TypeMode = TypeMode.DEFAULT
private var mSpecialModeView: SpecialModeView? = null
override fun onBackPressed() {
if (mSpecialMode != SpecialMode.DEFAULT)
onCancelSpecialMode()
else
super.onBackPressed()
}
/**
* To call the regular onBackPressed() method in special mode
*/
protected fun onRegularBackPressed() {
super.onBackPressed()
}
/**
* Intent sender uses special retains data in callback
*/
private fun isIntentSender(): Boolean {
return (mSpecialMode == SpecialMode.SELECTION
&& mTypeMode == TypeMode.AUTOFILL)
/* TODO Registration callback #765
|| (mSpecialMode == SpecialMode.REGISTRATION
&& mTypeMode == TypeMode.AUTOFILL
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
*/
}
fun onLaunchActivitySpecialMode() {
if (!isIntentSender()) {
EntrySelectionHelper.removeModesFromIntent(intent)
EntrySelectionHelper.removeInfoFromIntent(intent)
finish()
}
}
open fun onValidateSpecialMode() {
if (isIntentSender()) {
super.finish()
} else {
EntrySelectionHelper.removeModesFromIntent(intent)
EntrySelectionHelper.removeInfoFromIntent(intent)
if (mSpecialMode != SpecialMode.DEFAULT) {
// To move the app in background
moveTaskToBack(true)
}
}
}
open fun onCancelSpecialMode() {
if (isIntentSender()) {
// To get the app caller, only for IntentSender
super.onBackPressed()
} else {
EntrySelectionHelper.removeModesFromIntent(intent)
EntrySelectionHelper.removeInfoFromIntent(intent)
if (mSpecialMode != SpecialMode.DEFAULT) {
// To move the app in background
moveTaskToBack(true)
}
}
}
protected fun backToTheAppCaller() {
if (isIntentSender()) {
// To get the app caller, only for IntentSender
super.onBackPressed()
} else {
// To move the app in background
moveTaskToBack(true)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mSpecialMode = EntrySelectionHelper.retrieveSpecialModeFromIntent(intent)
mTypeMode = EntrySelectionHelper.retrieveTypeModeFromIntent(intent)
}
override fun onResume() {
super.onResume()
mSpecialMode = EntrySelectionHelper.retrieveSpecialModeFromIntent(intent)
mTypeMode = EntrySelectionHelper.retrieveTypeModeFromIntent(intent)
val searchInfo: SearchInfo? = EntrySelectionHelper.retrieveRegisterInfoFromIntent(intent)?.searchInfo
?: EntrySelectionHelper.retrieveSearchInfoFromIntent(intent)
// To show the selection mode
mSpecialModeView = findViewById(R.id.special_mode_view)
mSpecialModeView?.apply {
// Populate title
val selectionModeStringId = when (mSpecialMode) {
SpecialMode.DEFAULT, // Not important because hidden
SpecialMode.SEARCH -> R.string.search_mode
SpecialMode.SAVE -> R.string.save_mode
SpecialMode.SELECTION -> R.string.selection_mode
SpecialMode.REGISTRATION -> R.string.registration_mode
}
val typeModeStringId = when (mTypeMode) {
TypeMode.DEFAULT, // Not important because hidden
TypeMode.MAGIKEYBOARD -> R.string.magic_keyboard_title
TypeMode.AUTOFILL -> R.string.autofill
}
title = getString(selectionModeStringId)
if (mTypeMode != TypeMode.DEFAULT)
title = "$title (${getString(typeModeStringId)})"
// Populate subtitle
subtitle = searchInfo?.getName(resources)
// Show the toolbar or not
visible = when (mSpecialMode) {
SpecialMode.DEFAULT -> false
SpecialMode.SEARCH -> true
SpecialMode.SAVE -> true
SpecialMode.SELECTION -> true
SpecialMode.REGISTRATION -> true
}
// Add back listener
onCancelButtonClickListener = View.OnClickListener {
onCancelSpecialMode()
}
// Create menu
menu.clear()
if (mTypeMode == TypeMode.AUTOFILL) {
menuInflater.inflate(R.menu.autofill, menu)
setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.menu_block_autofill -> {
blockAutofill(searchInfo)
}
}
true
}
}
}
// To hide home button from the regular toolbar in special mode
if (mSpecialMode != SpecialMode.DEFAULT) {
supportActionBar?.setDisplayHomeAsUpEnabled(false)
supportActionBar?.setDisplayShowHomeEnabled(false)
}
}
private 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

@@ -1,30 +1,30 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.stylish
import android.content.Context
import androidx.annotation.StyleRes
import androidx.preference.PreferenceManager
import android.content.res.Configuration
import android.util.Log
import androidx.annotation.StyleRes
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.PreferencesUtil
/**
* Class that provides functions to retrieve and assign a theme to a module
@@ -37,18 +37,63 @@ object Stylish {
* Initialize the class with a theme preference
* @param context Context to retrieve the theme preference
*/
fun init(context: Context) {
val stylishPrefKey = context.getString(R.string.setting_style_key)
fun load(context: Context) {
Log.d(Stylish::class.java.name, "Attatching to " + context.packageName)
themeString = PreferenceManager.getDefaultSharedPreferences(context).getString(stylishPrefKey, context.getString(R.string.list_style_name_light))
themeString = PreferencesUtil.getStyle(context)
}
fun retrieveEquivalentSystemStyle(context: Context, styleString: String): String {
val systemNightMode = when (PreferencesUtil.getStyleBrightness(context)) {
context.getString(R.string.list_style_brightness_light) -> false
context.getString(R.string.list_style_brightness_night) -> true
else -> {
when (context.resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) {
Configuration.UI_MODE_NIGHT_YES -> true
else -> false
}
}
}
return if (systemNightMode) {
retrieveEquivalentNightStyle(context, styleString)
} else {
retrieveEquivalentLightStyle(context, styleString)
}
}
fun retrieveEquivalentLightStyle(context: Context, styleString: String): String {
return when (styleString) {
context.getString(R.string.list_style_name_night) -> context.getString(R.string.list_style_name_light)
context.getString(R.string.list_style_name_black) -> context.getString(R.string.list_style_name_white)
context.getString(R.string.list_style_name_dark) -> context.getString(R.string.list_style_name_clear)
context.getString(R.string.list_style_name_blue_night) -> context.getString(R.string.list_style_name_blue)
context.getString(R.string.list_style_name_red_night) -> context.getString(R.string.list_style_name_red)
context.getString(R.string.list_style_name_purple_dark) -> context.getString(R.string.list_style_name_purple)
else -> styleString
}
}
private fun retrieveEquivalentNightStyle(context: Context, styleString: String): String {
return when (styleString) {
context.getString(R.string.list_style_name_light) -> context.getString(R.string.list_style_name_night)
context.getString(R.string.list_style_name_white) -> context.getString(R.string.list_style_name_black)
context.getString(R.string.list_style_name_clear) -> context.getString(R.string.list_style_name_dark)
context.getString(R.string.list_style_name_blue) -> context.getString(R.string.list_style_name_blue_night)
context.getString(R.string.list_style_name_red) -> context.getString(R.string.list_style_name_red_night)
context.getString(R.string.list_style_name_purple) -> context.getString(R.string.list_style_name_purple_dark)
else -> styleString
}
}
fun defaultStyle(context: Context): String {
return context.getString(R.string.list_style_name_light)
}
/**
* Assign the style to the class attribute
* @param styleString Style id String
*/
fun assignStyle(styleString: String) {
themeString = styleString
fun assignStyle(context: Context, styleString: String) {
PreferencesUtil.setStyle(context, styleString)
}
/**
@@ -58,13 +103,18 @@ object Stylish {
*/
@StyleRes
fun getThemeId(context: Context): Int {
return when (themeString) {
return when (retrieveEquivalentSystemStyle(context, themeString ?: context.getString(R.string.list_style_name_light))) {
context.getString(R.string.list_style_name_night) -> R.style.KeepassDXStyle_Night
context.getString(R.string.list_style_name_white) -> R.style.KeepassDXStyle_White
context.getString(R.string.list_style_name_black) -> R.style.KeepassDXStyle_Black
context.getString(R.string.list_style_name_clear) -> R.style.KeepassDXStyle_Clear
context.getString(R.string.list_style_name_dark) -> R.style.KeepassDXStyle_Dark
context.getString(R.string.list_style_name_blue) -> R.style.KeepassDXStyle_Blue
context.getString(R.string.list_style_name_blue_night) -> R.style.KeepassDXStyle_Blue_Night
context.getString(R.string.list_style_name_red) -> R.style.KeepassDXStyle_Red
context.getString(R.string.list_style_name_red_night) -> R.style.KeepassDXStyle_Red_Night
context.getString(R.string.list_style_name_purple) -> R.style.KeepassDXStyle_Purple
context.getString(R.string.list_style_name_purple_dark) -> R.style.KeepassDXStyle_Purple_Dark
else -> R.style.KeepassDXStyle_Light
}
}

View File

@@ -1,38 +1,64 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.stylish
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatActivity
import android.util.Log
import android.view.WindowManager
/**
* Stylish Hide Activity that apply a dynamic style and sets FLAG_SECURE to prevent screenshots / from
* appearing in the recent app preview
*/
abstract class StylishActivity : AppCompatActivity() {
@StyleRes
private var themeId: Int = 0
/* (non-Javadoc) Workaround for HTC Linkify issues
* @see android.app.Activity#startActivity(android.content.Intent)
*/
override fun startActivity(intent: Intent) {
try {
intent.component?.let {
if (it.shortClassName == ".HtcLinkifyDispatcherActivity")
intent.component = null
}
super.startActivity(intent)
} catch (e: ActivityNotFoundException) {
/* Catch the bad HTC implementation case */
super.startActivity(Intent.createChooser(intent, null))
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
this.themeId = Stylish.getThemeId(this)
setTheme(themeId)
// Several gingerbread devices have problems with FLAG_SECURE
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
}
override fun onResume() {

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities.stylish
@@ -42,18 +42,33 @@ abstract class StylishFragment : Fragment() {
contextThemed = ContextThemeWrapper(context, themeId)
}
@Suppress("DEPRECATION")
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// To fix status bar color
if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window = activity!!.window
val attrColorPrimaryDark = intArrayOf(android.R.attr.colorPrimaryDark)
val taColorPrimaryDark = contextThemed?.theme?.obtainStyledAttributes(attrColorPrimaryDark)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window = requireActivity().window
val defaultColor = Color.BLACK
window.statusBarColor = taColorPrimaryDark?.getColor(0, defaultColor) ?: defaultColor
taColorPrimaryDark?.recycle()
}
try {
val taStatusBarColor = contextThemed?.theme?.obtainStyledAttributes(intArrayOf(android.R.attr.statusBarColor))
window.statusBarColor = taStatusBarColor?.getColor(0, defaultColor) ?: defaultColor
taStatusBarColor?.recycle()
} catch (e: Exception) {}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
val taWindowStatusLight = contextThemed?.theme?.obtainStyledAttributes(intArrayOf(android.R.attr.windowLightStatusBar))
if (taWindowStatusLight?.getBoolean(0, false) == true) {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
taWindowStatusLight?.recycle()
} catch (e: Exception) {}
}
try {
val taNavigationBarColor = contextThemed?.theme?.obtainStyledAttributes(intArrayOf(android.R.attr.navigationBarColor))
window.navigationBarColor = taNavigationBarColor?.getColor(0, defaultColor) ?: defaultColor
taNavigationBarColor?.recycle()
} catch (e: Exception) {}
}
return super.onCreateView(inflater, container, savedInstanceState)
}

View File

@@ -0,0 +1,128 @@
package com.kunzisoft.keepass.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.view.collapse
abstract class AnimatedItemsAdapter<Item, T: RecyclerView.ViewHolder>(val context: Context)
: RecyclerView.Adapter<T>() {
protected val inflater: LayoutInflater = LayoutInflater.from(context)
var itemsList: MutableList<Item> = ArrayList()
private set
var onDeleteButtonClickListener: ((item: Item)->Unit)? = null
private var mItemToRemove: Item? = null
var onListSizeChangedListener: ((previousSize: Int, newSize: Int)->Unit)? = null
override fun getItemCount(): Int {
return itemsList.size
}
open fun assignItems(items: List<Item>) {
val previousSize = itemsList.size
itemsList.apply {
clear()
addAll(items)
}
notifyDataSetChanged()
onListSizeChangedListener?.invoke(previousSize, itemsList.size)
}
open fun isEmpty(): Boolean {
return itemsList.isEmpty()
}
open fun contains(item: Item): Boolean {
return itemsList.contains(item)
}
open fun indexOf(item: Item): Int {
return itemsList.indexOf(item)
}
open fun putItem(item: Item) {
val previousSize = itemsList.size
if (itemsList.contains(item)) {
val index = itemsList.indexOf(item)
itemsList.removeAt(index)
itemsList.add(index, item)
notifyItemChanged(index)
} else {
itemsList.add(item)
notifyItemInserted(itemsList.indexOf(item))
}
onListSizeChangedListener?.invoke(previousSize, itemsList.size)
}
/**
* Only replace [oldItem] by [newItem] if [oldItem] exists
*/
open fun replaceItem(oldItem: Item, newItem: Item) {
if (itemsList.contains(oldItem)) {
val index = itemsList.indexOf(oldItem)
itemsList.removeAt(index)
itemsList.add(index, newItem)
notifyItemChanged(index)
}
}
/**
* Only remove [item] if doesn't exists
*/
open fun removeItem(item: Item) {
if (itemsList.contains(item)) {
mItemToRemove = item
notifyItemChanged(itemsList.indexOf(item))
}
}
protected fun performDeletion(holder: T, item: Item): Boolean {
val effectivelyDeletionPerformed = mItemToRemove == item
if (effectivelyDeletionPerformed) {
holder.itemView.collapse(true) {
deleteItem(item)
}
}
return effectivelyDeletionPerformed
}
protected fun onBindDeleteButton(holder: T, deleteButton: View, item: Item, position: Int) {
deleteButton.apply {
visibility = View.VISIBLE
if (performDeletion(holder, item)) {
setOnClickListener(null)
} else {
setOnClickListener {
onDeleteButtonClickListener?.invoke(item)
mItemToRemove = item
notifyItemChanged(position)
}
}
}
}
private fun deleteItem(item: Item) {
val previousSize = itemsList.size
val position = itemsList.indexOf(item)
if (position >= 0) {
itemsList.removeAt(position)
notifyItemRemoved(position)
mItemToRemove = null
for (i in 0 until itemsList.size) {
notifyItemChanged(i)
}
}
onListSizeChangedListener?.invoke(previousSize, itemsList.size)
}
fun clear() {
if (itemsList.size > 0) {
itemsList.clear()
notifyDataSetChanged()
}
}
}

View File

@@ -0,0 +1,206 @@
/*
* 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.adapters
import android.content.Context
import android.content.res.TypedArray
import android.graphics.Color
import android.text.format.Formatter
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.ImageViewerActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
import com.kunzisoft.keepass.model.AttachmentState
import com.kunzisoft.keepass.model.EntryAttachmentState
import com.kunzisoft.keepass.model.StreamDirection
import com.kunzisoft.keepass.tasks.BinaryDatabaseManager
import com.kunzisoft.keepass.view.expand
import kotlin.math.max
class EntryAttachmentsItemsAdapter(context: Context)
: AnimatedItemsAdapter<EntryAttachmentState, EntryAttachmentsItemsAdapter.EntryBinariesViewHolder>(context) {
var database: Database? = null
var onItemClickListener: ((item: EntryAttachmentState)->Unit)? = null
var onBinaryPreviewLoaded: ((item: EntryAttachmentState) -> Unit)? = null
// Approximately
private val mImagePreviewMaxWidth = max(
context.resources.displayMetrics.widthPixels,
context.resources.getDimensionPixelSize(R.dimen.item_file_info_height)
)
private var mTitleColor: Int
init {
// Get the primary text color of the theme
val typedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true)
val typedArray: TypedArray = context.obtainStyledAttributes(typedValue.data, intArrayOf(
android.R.attr.textColor))
mTitleColor = typedArray.getColor(0, -1)
typedArray.recycle()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EntryBinariesViewHolder {
return EntryBinariesViewHolder(inflater.inflate(R.layout.item_attachment, parent, false))
}
override fun onBindViewHolder(holder: EntryBinariesViewHolder, position: Int) {
val entryAttachmentState = itemsList[position]
holder.itemView.visibility = View.VISIBLE
holder.binaryFileThumbnail.apply {
// Perform image loading only if upload is finished
if (entryAttachmentState.downloadState != AttachmentState.START
&& entryAttachmentState.downloadState != AttachmentState.IN_PROGRESS) {
// Show the bitmap image if loaded
if (entryAttachmentState.previewState == AttachmentState.NULL) {
entryAttachmentState.previewState = AttachmentState.IN_PROGRESS
// Load the bitmap image
database?.let { database ->
BinaryDatabaseManager.loadBitmap(
database,
entryAttachmentState.attachment.binaryData,
mImagePreviewMaxWidth
) { imageLoaded ->
if (imageLoaded == null) {
entryAttachmentState.previewState = AttachmentState.ERROR
visibility = View.GONE
onBinaryPreviewLoaded?.invoke(entryAttachmentState)
} else {
entryAttachmentState.previewState = AttachmentState.COMPLETE
setImageBitmap(imageLoaded)
if (visibility != View.VISIBLE) {
expand(true, resources.getDimensionPixelSize(R.dimen.item_file_info_height)) {
onBinaryPreviewLoaded?.invoke(entryAttachmentState)
}
}
}
}
}
}
} else {
visibility = View.GONE
}
this.setOnClickListener {
ImageViewerActivity.getInstance(context, entryAttachmentState.attachment)
}
}
holder.binaryFileBroken.apply {
setColorFilter(Color.RED)
visibility = if (entryAttachmentState.attachment.binaryData.isCorrupted) {
View.VISIBLE
} else {
View.GONE
}
}
holder.binaryFileTitle.text = entryAttachmentState.attachment.name
if (entryAttachmentState.attachment.binaryData.isCorrupted) {
holder.binaryFileTitle.setTextColor(Color.RED)
} else {
holder.binaryFileTitle.setTextColor(mTitleColor)
}
val size = entryAttachmentState.attachment.binaryData.getSize()
holder.binaryFileSize.text = Formatter.formatFileSize(context, size)
holder.binaryFileCompression.apply {
if (entryAttachmentState.attachment.binaryData.isCompressed) {
text = CompressionAlgorithm.GZip.getName(context.resources)
visibility = View.VISIBLE
} else {
text = ""
visibility = View.GONE
}
}
when (entryAttachmentState.streamDirection) {
StreamDirection.UPLOAD -> {
holder.binaryFileProgressIcon.isActivated = true
when (entryAttachmentState.downloadState) {
AttachmentState.START,
AttachmentState.IN_PROGRESS -> {
holder.binaryFileProgressContainer.visibility = View.VISIBLE
holder.binaryFileProgress.apply {
visibility = View.VISIBLE
progress = entryAttachmentState.downloadProgression
}
holder.binaryFileDeleteButton.apply {
visibility = View.GONE
setOnClickListener(null)
}
}
AttachmentState.NULL,
AttachmentState.ERROR,
AttachmentState.CANCELED,
AttachmentState.COMPLETE -> {
holder.binaryFileProgressContainer.visibility = View.GONE
holder.binaryFileProgress.visibility = View.GONE
holder.binaryFileDeleteButton.apply {
visibility = View.VISIBLE
onBindDeleteButton(holder, this, entryAttachmentState, position)
}
}
}
holder.binaryFileInfo.setOnClickListener(null)
}
StreamDirection.DOWNLOAD -> {
holder.binaryFileProgressIcon.isActivated = false
holder.binaryFileProgressContainer.visibility = View.VISIBLE
holder.binaryFileDeleteButton.visibility = View.GONE
holder.binaryFileProgress.apply {
visibility = when (entryAttachmentState.downloadState) {
AttachmentState.NULL,
AttachmentState.COMPLETE,
AttachmentState.CANCELED,
AttachmentState.ERROR -> View.GONE
AttachmentState.START,
AttachmentState.IN_PROGRESS -> View.VISIBLE
}
progress = entryAttachmentState.downloadProgression
}
holder.binaryFileInfo.setOnClickListener {
onItemClickListener?.invoke(entryAttachmentState)
}
}
}
}
class EntryBinariesViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var binaryFileThumbnail: ImageView = itemView.findViewById(R.id.item_attachment_thumbnail)
var binaryFileInfo: View = itemView.findViewById(R.id.item_attachment_info)
var binaryFileBroken: ImageView = itemView.findViewById(R.id.item_attachment_broken)
var binaryFileTitle: TextView = itemView.findViewById(R.id.item_attachment_title)
var binaryFileSize: TextView = itemView.findViewById(R.id.item_attachment_size)
var binaryFileCompression: TextView = itemView.findViewById(R.id.item_attachment_compression)
var binaryFileProgressContainer: View = itemView.findViewById(R.id.item_attachment_progress_container)
var binaryFileProgressIcon: ImageView = itemView.findViewById(R.id.item_attachment_icon)
var binaryFileProgress: ProgressBar = itemView.findViewById(R.id.item_attachment_progress)
var binaryFileDeleteButton: View = itemView.findViewById(R.id.item_attachment_delete_button)
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Entry
class EntryHistoryAdapter(val context: Context) : RecyclerView.Adapter<EntryHistoryAdapter.EntryHistoryViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
var entryHistoryList: MutableList<Entry> = ArrayList()
var onItemClickListener: ((item: Entry, position: Int)->Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EntryHistoryViewHolder {
return EntryHistoryViewHolder(inflater.inflate(R.layout.item_list_entry_history, parent, false))
}
override fun onBindViewHolder(holder: EntryHistoryViewHolder, position: Int) {
val entryHistory = entryHistoryList[position]
holder.lastModifiedView.text = entryHistory.lastModificationTime.getDateTimeString(context.resources)
holder.titleView.text = entryHistory.title
holder.usernameView.text = entryHistory.username
holder.urlView.text = entryHistory.url
holder.itemView.setOnClickListener {
onItemClickListener?.invoke(entryHistory, position)
}
}
override fun getItemCount(): Int {
return entryHistoryList.size
}
fun clear() {
entryHistoryList.clear()
}
inner class EntryHistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var lastModifiedView: TextView = itemView.findViewById(R.id.entry_history_last_modified)
var titleView: TextView = itemView.findViewById(R.id.entry_history_title)
var usernameView: TextView = itemView.findViewById(R.id.entry_history_username)
var urlView: TextView = itemView.findViewById(R.id.entry_history_url)
}
}

View File

@@ -1,3 +1,22 @@
/*
* 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.adapters
import android.content.Context
@@ -15,10 +34,9 @@ import java.util.ArrayList
class FieldsAdapter(context: Context) : RecyclerView.Adapter<FieldsAdapter.FieldViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
var fields: MutableList<Field> = ArrayList()
private var fields: MutableList<Field> = ArrayList()
var onItemClickListener: OnItemClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FieldViewHolder {
val view = inflater.inflate(R.layout.keyboard_popup_fields_item, parent, false)
return FieldViewHolder(view)
@@ -34,6 +52,11 @@ class FieldsAdapter(context: Context) : RecyclerView.Adapter<FieldsAdapter.Field
return fields.size
}
fun setFields(fieldsToAdd: List<Field>) {
fields.clear()
fields.addAll(fieldsToAdd)
}
fun clear() {
fields.clear()
}

View File

@@ -1,50 +1,54 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.adapters
import android.content.Context
import android.graphics.Color
import android.graphics.PorterDuff
import android.net.Uri
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.annotation.ColorInt
import androidx.recyclerview.widget.RecyclerView
import android.util.TypedValue
import android.view.*
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.ViewSwitcher
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryEntity
import com.kunzisoft.keepass.utils.FileDatabaseInfo
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.model.DatabaseFile
import com.kunzisoft.keepass.view.collapse
import com.kunzisoft.keepass.view.expand
class FileDatabaseHistoryAdapter(private val context: Context)
class FileDatabaseHistoryAdapter(context: Context)
: RecyclerView.Adapter<FileDatabaseHistoryAdapter.FileDatabaseHistoryViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
private var fileItemOpenListener: ((FileDatabaseHistoryEntity)->Unit)? = null
private var fileSelectClearListener: ((FileDatabaseHistoryEntity)->Boolean)? = null
private var saveAliasListener: ((FileDatabaseHistoryEntity)->Unit)? = null
private var defaultDatabaseListener: ((DatabaseFile?) -> Unit)? = null
private var fileItemOpenListener: ((DatabaseFile)->Unit)? = null
private var fileSelectClearListener: ((DatabaseFile)->Boolean)? = null
private var saveAliasListener: ((DatabaseFile)->Unit)? = null
private val listDatabaseFiles = ArrayList<FileDatabaseHistoryEntity>()
private val listDatabaseFiles = ArrayList<DatabaseFile>()
private var mExpandedPosition = -1
private var mPreviousExpandedPosition = -1
private var mDefaultDatabaseFile: DatabaseFile? = null
private var mExpandedDatabaseFile: DatabaseFile? = null
private var mPreviousExpandedDatabaseFile: DatabaseFile? = null
@ColorInt
private val defaultColor: Int
@@ -61,47 +65,74 @@ class FileDatabaseHistoryAdapter(private val context: Context)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileDatabaseHistoryViewHolder {
val view = inflater.inflate(R.layout.item_file_row, parent, false)
val view = inflater.inflate(R.layout.item_file_info, parent, false)
return FileDatabaseHistoryViewHolder(view)
}
override fun onBindViewHolder(holder: FileDatabaseHistoryViewHolder, position: Int) {
// Get info from position
val fileHistoryEntity = listDatabaseFiles[position]
val fileDatabaseInfo = FileDatabaseInfo(context, fileHistoryEntity.databaseUri)
val databaseFile = listDatabaseFiles[position]
// Click item to open file
if (fileItemOpenListener != null)
holder.fileContainer.setOnClickListener {
fileItemOpenListener?.invoke(fileHistoryEntity)
holder.fileContainer.setOnClickListener {
fileItemOpenListener?.invoke(databaseFile)
}
// Default database
holder.defaultFileButton.apply {
this.isChecked = mDefaultDatabaseFile == databaseFile
setOnClickListener {
defaultDatabaseListener?.invoke(if (isChecked) databaseFile else null)
}
}
// File alias
holder.fileAlias.text = fileDatabaseInfo.retrieveDatabaseAlias(fileHistoryEntity.databaseAlias)
holder.fileAlias.text = databaseFile.databaseAlias
// File path
holder.filePath.text = UriUtil.decode(fileDatabaseInfo.fileUri?.toString())
holder.filePath.text = databaseFile.databaseDecodedPath
holder.filePreciseInfoContainer.visibility = if (fileDatabaseInfo.found()) {
// Modification
holder.fileModification.text = fileDatabaseInfo.getModificationString()
// Size
holder.fileSize.text = fileDatabaseInfo.getSizeString()
if (databaseFile.databaseFileExists) {
holder.fileInformationButton.clearColorFilter()
} else {
holder.fileInformationButton.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)
}
View.VISIBLE
} else
View.GONE
// Modification
databaseFile.databaseLastModified?.let {
holder.fileModification.text = it
holder.fileModificationContainer.visibility = View.VISIBLE
} ?: run {
holder.fileModificationContainer.visibility = View.GONE
}
// Size
databaseFile.databaseSize?.let {
holder.fileSize.text = it
holder.fileSize.visibility = View.VISIBLE
} ?: run {
holder.fileSize.visibility = View.GONE
}
// Click on information
val isExpanded = position == mExpandedPosition
//This line hides or shows the layout in question
holder.fileExpandContainer.visibility = if (isExpanded) View.VISIBLE else View.GONE
val isExpanded = databaseFile == mExpandedDatabaseFile
// Hides or shows info
holder.fileExpandContainer.apply {
if (isExpanded) {
if (visibility != View.VISIBLE) {
visibility = View.VISIBLE
expand(true, resources.getDimensionPixelSize(R.dimen.item_file_info_height))
}
} else {
collapse(true)
}
}
// Save alias modification
holder.fileAliasCloseButton.setOnClickListener {
// Change the alias
fileHistoryEntity.databaseAlias = holder.fileAliasEdit.text.toString()
saveAliasListener?.invoke(fileHistoryEntity)
databaseFile.databaseAlias = holder.fileAliasEdit.text.toString()
saveAliasListener?.invoke(databaseFile)
// Finish save mode
holder.fileMainSwitcher.showPrevious()
@@ -116,20 +147,22 @@ class FileDatabaseHistoryAdapter(private val context: Context)
}
holder.fileDeleteButton.setOnClickListener {
fileSelectClearListener?.invoke(fileHistoryEntity)
fileSelectClearListener?.invoke(databaseFile)
}
if (isExpanded) {
mPreviousExpandedPosition = position
mPreviousExpandedDatabaseFile = databaseFile
}
holder.fileInformation.setOnClickListener {
mExpandedPosition = if (isExpanded) -1 else position
// Notify change
if (mPreviousExpandedPosition < itemCount)
notifyItemChanged(mPreviousExpandedPosition)
notifyItemChanged(position)
holder.fileInformationButton.apply {
animate().rotation(if (isExpanded) 180F else 0F).start()
setOnClickListener {
mExpandedDatabaseFile = if (isExpanded) null else databaseFile
// Notify change
val previousExpandedPosition = listDatabaseFiles.indexOf(mPreviousExpandedDatabaseFile)
notifyItemChanged(previousExpandedPosition)
val expandedPosition = listDatabaseFiles.indexOf(mExpandedDatabaseFile)
notifyItemChanged(expandedPosition)
}
}
// Refresh View / Close alias modification if not contains fileAlias
@@ -142,33 +175,72 @@ class FileDatabaseHistoryAdapter(private val context: Context)
return listDatabaseFiles.size
}
fun addDatabaseFileHistoryList(listFileDatabaseHistoryToAdd: List<FileDatabaseHistoryEntity>) {
fun clearDatabaseFileHistoryList() {
listDatabaseFiles.clear()
listDatabaseFiles.addAll(listFileDatabaseHistoryToAdd)
}
fun deleteDatabaseFileHistory(fileDatabaseHistoryToDelete: FileDatabaseHistoryEntity) {
listDatabaseFiles.remove(fileDatabaseHistoryToDelete)
fun addDatabaseFileHistory(fileDatabaseHistoryToAdd: DatabaseFile) {
listDatabaseFiles.add(0, fileDatabaseHistoryToAdd)
notifyItemInserted(0)
}
fun setOnFileDatabaseHistoryOpenListener(listener : ((FileDatabaseHistoryEntity)->Unit)?) {
fun updateDatabaseFileHistory(fileDatabaseHistoryToUpdate: DatabaseFile) {
val index = listDatabaseFiles.indexOf(fileDatabaseHistoryToUpdate)
if (listDatabaseFiles.remove(fileDatabaseHistoryToUpdate)) {
listDatabaseFiles.add(index, fileDatabaseHistoryToUpdate)
notifyItemChanged(index)
}
}
fun deleteDatabaseFileHistory(fileDatabaseHistoryToDelete: DatabaseFile) {
val index = listDatabaseFiles.indexOf(fileDatabaseHistoryToDelete)
if (listDatabaseFiles.remove(fileDatabaseHistoryToDelete)) {
notifyItemRemoved(index)
}
}
fun replaceAllDatabaseFileHistoryList(listFileDatabaseHistoryToAdd: List<DatabaseFile>) {
if (listDatabaseFiles.isEmpty()) {
listFileDatabaseHistoryToAdd.forEach {
listDatabaseFiles.add(it)
notifyItemInserted(listDatabaseFiles.size)
}
} else {
listDatabaseFiles.clear()
listDatabaseFiles.addAll(listFileDatabaseHistoryToAdd)
notifyDataSetChanged()
}
}
fun setDefaultDatabase(databaseUri: Uri?) {
val defaultDatabaseFile = listDatabaseFiles.firstOrNull { it.databaseUri == databaseUri }
mDefaultDatabaseFile = defaultDatabaseFile
notifyDataSetChanged()
}
fun setOnDefaultDatabaseListener(listener: ((DatabaseFile?) -> Unit)?) {
this.defaultDatabaseListener = listener
}
fun setOnFileDatabaseHistoryOpenListener(listener : ((DatabaseFile)->Unit)?) {
this.fileItemOpenListener = listener
}
fun setOnFileDatabaseHistoryDeleteListener(listener : ((FileDatabaseHistoryEntity)->Boolean)?) {
fun setOnFileDatabaseHistoryDeleteListener(listener : ((DatabaseFile)->Boolean)?) {
this.fileSelectClearListener = listener
}
fun setOnSaveAliasListener(listener : ((FileDatabaseHistoryEntity)->Unit)?) {
fun setOnSaveAliasListener(listener : ((DatabaseFile)->Unit)?) {
this.saveAliasListener = listener
}
inner class FileDatabaseHistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
class FileDatabaseHistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var fileContainer: ViewGroup = itemView.findViewById(R.id.file_container_basic_info)
var defaultFileButton: CompoundButton = itemView.findViewById(R.id.default_file_button)
var fileAlias: TextView = itemView.findViewById(R.id.file_alias)
var fileInformation: ImageView = itemView.findViewById(R.id.file_information)
var fileInformationButton: ImageView = itemView.findViewById(R.id.file_information_button)
var fileMainSwitcher: ViewSwitcher = itemView.findViewById(R.id.file_main_switcher)
var fileAliasEdit: EditText = itemView.findViewById(R.id.file_alias_edit)
@@ -178,7 +250,7 @@ class FileDatabaseHistoryAdapter(private val context: Context)
var fileModifyButton: ImageView = itemView.findViewById(R.id.file_modify_button)
var fileDeleteButton: ImageView = itemView.findViewById(R.id.file_delete_button)
var filePath: TextView = itemView.findViewById(R.id.file_path)
var filePreciseInfoContainer: ViewGroup = itemView.findViewById(R.id.file_precise_info_container)
var fileModificationContainer: ViewGroup = itemView.findViewById(R.id.file_modification_container)
var fileModification: TextView = itemView.findViewById(R.id.file_modification)
var fileSize: TextView = itemView.findViewById(R.id.file_size)
}

View File

@@ -0,0 +1,129 @@
package com.kunzisoft.keepass.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.icon.IconImageDraw
import com.kunzisoft.keepass.icons.IconDrawableFactory
class IconPickerAdapter<I: IconImageDraw>(val context: Context, private val tintIcon: Int)
: RecyclerView.Adapter<IconPickerAdapter<I>.CustomIconViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
private val iconList = ArrayList<I>()
var iconDrawableFactory: IconDrawableFactory? = null
var iconPickerListener: IconPickerListener<I>? = null
val lastPosition: Int
get() = iconList.lastIndex
fun addIcon(icon: I, notify: Boolean = true) {
if (!iconList.contains(icon)) {
iconList.add(icon)
if (notify) {
notifyItemInserted(iconList.indexOf(icon))
}
}
}
fun updateIcon(icon: I) {
val index = iconList.indexOf(icon)
if (index != -1) {
iconList[index] = icon
notifyItemChanged(index)
}
}
fun updateIconSelectedState(icons: List<I>) {
icons.forEach { icon ->
val index = iconList.indexOf(icon)
if (index != -1
&& iconList[index].selected != icon.selected) {
iconList[index] = icon
notifyItemChanged(index)
}
}
}
fun removeIcon(icon: I) {
if (iconList.contains(icon)) {
val position = iconList.indexOf(icon)
iconList.remove(icon)
notifyItemRemoved(position)
}
}
fun containsAnySelectedIcon(): Boolean {
return iconList.firstOrNull { it.selected } != null
}
fun deselectAllIcons() {
iconList.forEachIndexed { index, icon ->
if (icon.selected) {
icon.selected = false
notifyItemChanged(index)
}
}
}
fun getSelectedIcons(): List<I> {
return iconList.filter { it.selected }
}
fun clear() {
iconList.clear()
}
fun setList(icons: List<I>) {
iconList.clear()
icons.forEach { iconImage ->
iconList.add(iconImage)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomIconViewHolder {
val view = inflater.inflate(R.layout.item_icon, parent, false)
return CustomIconViewHolder(view)
}
override fun onBindViewHolder(holder: CustomIconViewHolder, position: Int) {
val icon = iconList[position]
iconDrawableFactory?.assignDatabaseIcon(holder.iconImageView, icon, tintIcon)
icon.getIconImageToDraw().custom.name.let { iconName ->
holder.iconTextView.apply {
text = iconName
visibility = if (iconName.isNotEmpty()) View.VISIBLE else View.GONE
}
}
holder.iconContainerView.isSelected = icon.selected
holder.itemView.setOnClickListener {
iconPickerListener?.onIconClickListener(icon)
}
holder.itemView.setOnLongClickListener {
iconPickerListener?.onIconLongClickListener(icon)
true
}
}
override fun getItemCount(): Int {
return iconList.size
}
interface IconPickerListener<I: IconImageDraw> {
fun onIconClickListener(icon: I)
fun onIconLongClickListener(icon: I)
}
inner class CustomIconViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var iconContainerView: ViewGroup = itemView.findViewById(R.id.icon_container)
var iconImageView: ImageView = itemView.findViewById(R.id.icon_image)
var iconTextView: TextView = itemView.findViewById(R.id.icon_name)
}
}

View File

@@ -0,0 +1,24 @@
package com.kunzisoft.keepass.adapters
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.kunzisoft.keepass.activities.fragments.IconCustomFragment
import com.kunzisoft.keepass.activities.fragments.IconStandardFragment
class IconPickerPagerAdapter(fragment: Fragment, val size: Int)
: FragmentStateAdapter(fragment) {
private val iconStandardFragment = IconStandardFragment()
private val iconCustomFragment = IconCustomFragment()
override fun getItemCount(): Int {
return size
}
override fun createFragment(position: Int): Fragment {
return when (position) {
1 -> iconCustomFragment
else -> iconStandardFragment
}
}
}

View File

@@ -1,188 +1,218 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.adapters
import android.content.Context
import android.graphics.Color
import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedListAdapterCallback
import android.util.Log
import android.util.TypedValue
import android.view.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.SortedListAdapterCallback
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.SortNodeEnum
import com.kunzisoft.keepass.database.element.*
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.SortNodeEnum
import com.kunzisoft.keepass.database.element.node.Node
import com.kunzisoft.keepass.database.element.node.NodeVersionedInterface
import com.kunzisoft.keepass.database.element.node.Type
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.view.setTextSize
import com.kunzisoft.keepass.view.strikeOut
import java.util.*
class NodeAdapter
/**
* Create node list adapter with contextMenu or not
* @param context Context to use
*/
(private val context: Context, private val menuInflater: MenuInflater)
class NodeAdapter (private val context: Context)
: RecyclerView.Adapter<NodeAdapter.NodeViewHolder>() {
private val nodeSortedList: SortedList<NodeVersioned>
private val inflater: LayoutInflater = LayoutInflater.from(context)
private var mNodeComparator: Comparator<NodeVersionedInterface<Group>>? = null
private val mNodeSortedListCallback: NodeSortedListCallback
private val mNodeSortedList: SortedList<Node>
private val mInflater: LayoutInflater = LayoutInflater.from(context)
private var calculateViewTypeTextSize = Array(2) { true} // number of view type
private var textSizeUnit: Int = TypedValue.COMPLEX_UNIT_PX
private var prefTextSize: Float = 0F
private var subtextSize: Float = 0F
private var infoTextSize: Float = 0F
private var numberChildrenTextSize: Float = 0F
private var iconSize: Float = 0F
private var listSort: SortNodeEnum = SortNodeEnum.DB
private var ascendingSort: Boolean = true
private var groupsBeforeSort: Boolean = true
private var recycleBinBottomSort: Boolean = true
private var showUserNames: Boolean = true
private var showNumberEntries: Boolean = true
private var mCalculateViewTypeTextSize = Array(2) { true } // number of view type
private var mTextSizeUnit: Int = TypedValue.COMPLEX_UNIT_PX
private var mPrefSizeMultiplier: Float = 0F
private var mSubtextDefaultDimension: Float = 0F
private var mInfoTextDefaultDimension: Float = 0F
private var mNumberChildrenTextDefaultDimension: Float = 0F
private var mIconDefaultDimension: Float = 0F
private var nodeClickCallback: NodeClickCallback? = null
private var nodeMenuListener: NodeMenuListener? = null
private var activateContextMenu: Boolean = false
private var readOnly: Boolean = false
private var isASearchResult: Boolean = false
private var mShowUserNames: Boolean = true
private var mShowNumberEntries: Boolean = true
private var mEntryFilters = arrayOf<Group.ChildFilter>()
private var mActionNodesList = LinkedList<Node>()
private var mNodeClickCallback: NodeClickCallback? = null
private val mDatabase: Database
private val iconGroupColor: Int
private val iconEntryColor: Int
@ColorInt
private val mContentSelectionColor: Int
@ColorInt
private val mIconGroupColor: Int
@ColorInt
private val mIconEntryColor: Int
/**
* Determine if the adapter contains or not any element
* @return true if the list is empty
*/
val isEmpty: Boolean
get() = nodeSortedList.size() <= 0
get() = mNodeSortedList.size() <= 0
init {
this.mIconDefaultDimension = context.resources.getDimension(R.dimen.list_icon_size_default)
assignPreferences()
this.activateContextMenu = false
this.readOnly = false
this.isASearchResult = false
this.nodeSortedList = SortedList(NodeVersioned::class.java, object : SortedListAdapterCallback<NodeVersioned>(this) {
override fun compare(item1: NodeVersioned, item2: NodeVersioned): Int {
return listSort.getNodeComparator(ascendingSort, groupsBeforeSort, recycleBinBottomSort).compare(item1, item2)
}
override fun areContentsTheSame(oldItem: NodeVersioned, newItem: NodeVersioned): Boolean {
return oldItem.type == newItem.type
&& oldItem.title == newItem.title
&& oldItem.icon == newItem.icon
}
override fun areItemsTheSame(item1: NodeVersioned, item2: NodeVersioned): Boolean {
return item1 == item2
}
})
this.mNodeSortedListCallback = NodeSortedListCallback()
this.mNodeSortedList = SortedList(Node::class.java, mNodeSortedListCallback)
// Database
this.mDatabase = Database.getInstance()
// Color of content selection
this.mContentSelectionColor = ContextCompat.getColor(context, R.color.white)
// Retrieve the color to tint the icon
val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
this.iconGroupColor = taTextColorPrimary.getColor(0, Color.BLACK)
this.mIconGroupColor = taTextColorPrimary.getColor(0, Color.BLACK)
taTextColorPrimary.recycle()
// In two times to fix bug compilation
val taTextColor = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
this.iconEntryColor = taTextColor.getColor(0, Color.BLACK)
this.mIconEntryColor = taTextColor.getColor(0, Color.BLACK)
taTextColor.recycle()
}
fun setReadOnly(readOnly: Boolean) {
this.readOnly = readOnly
}
fun assignPreferences() {
this.mPrefSizeMultiplier = PreferencesUtil.getListTextSize(context)
fun setIsASearchResult(isASearchResult: Boolean) {
this.isASearchResult = isASearchResult
}
notifyChangeSort(
PreferencesUtil.getListSort(context),
SortNodeEnum.SortNodeParameters(
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context),
PreferencesUtil.getRecycleBinBottomSort(context)
)
)
fun setActivateContextMenu(activate: Boolean) {
this.activateContextMenu = activate
}
this.mShowUserNames = PreferencesUtil.showUsernamesListEntries(context)
this.mShowNumberEntries = PreferencesUtil.showNumberEntries(context)
private fun assignPreferences() {
this.prefTextSize = PreferencesUtil.getListTextSize(context)
this.infoTextSize = context.resources.getDimension(R.dimen.list_medium_size_default) * prefTextSize
this.subtextSize = context.resources.getDimension(R.dimen.list_small_size_default) * prefTextSize
this.numberChildrenTextSize = context.resources.getDimension(R.dimen.list_tiny_size_default) * prefTextSize
this.iconSize = context.resources.getDimension(R.dimen.list_icon_size_default) * prefTextSize
this.listSort = PreferencesUtil.getListSort(context)
this.ascendingSort = PreferencesUtil.getAscendingSort(context)
this.groupsBeforeSort = PreferencesUtil.getGroupsBeforeSort(context)
this.recycleBinBottomSort = PreferencesUtil.getRecycleBinBottomSort(context)
this.showUserNames = PreferencesUtil.showUsernamesListEntries(context)
this.showNumberEntries = PreferencesUtil.showNumberEntries(context)
this.mEntryFilters = Group.ChildFilter.getDefaults(context)
// Reinit textSize for all view type
calculateViewTypeTextSize.forEachIndexed { index, _ -> calculateViewTypeTextSize[index] = true }
mCalculateViewTypeTextSize.forEachIndexed { index, _ -> mCalculateViewTypeTextSize[index] = true }
}
/**
* Rebuild the list by clear and build children from the group
*/
fun rebuildList(group: GroupVersioned) {
this.nodeSortedList.clear()
fun rebuildList(group: Group) {
assignPreferences()
try {
this.nodeSortedList.addAll(group.getChildren())
} catch (e: Exception) {
Log.e(TAG, "Can't add node elements to the list", e)
Toast.makeText(context, "Can't add node elements to the list : " + e.message, Toast.LENGTH_LONG).show()
mNodeSortedList.replaceAll(group.getFilteredChildren(mEntryFilters))
}
private inner class NodeSortedListCallback: SortedListAdapterCallback<Node>(this) {
override fun compare(item1: Node, item2: Node): Int {
return mNodeComparator!!.compare(item1, item2)
}
override fun areContentsTheSame(oldItem: Node, newItem: Node): Boolean {
return oldItem.type == newItem.type
&& oldItem.title == newItem.title
&& oldItem.icon == newItem.icon
}
override fun areItemsTheSame(item1: Node, item2: Node): Boolean {
return item1 == item2
}
}
fun contains(node: NodeVersioned): Boolean {
return nodeSortedList.indexOf(node) != SortedList.INVALID_POSITION
fun contains(node: Node): Boolean {
return mNodeSortedList.indexOf(node) != SortedList.INVALID_POSITION
}
/**
* Add a node to the list
* @param node Node to add
*/
fun addNode(node: NodeVersioned) {
nodeSortedList.add(node)
fun addNode(node: Node) {
mNodeSortedList.add(node)
}
/**
* Add nodes to the list
* @param nodes Nodes to add
*/
fun addNodes(nodes: List<Node>) {
mNodeSortedList.addAll(nodes)
}
/**
* Remove a node in the list
* @param node Node to delete
*/
fun removeNode(node: NodeVersioned) {
nodeSortedList.remove(node)
fun removeNode(node: Node) {
mNodeSortedList.remove(node)
}
/**
* Remove nodes in the list
* @param nodes Nodes to delete
*/
fun removeNodes(nodes: List<Node>) {
nodes.forEach { node ->
mNodeSortedList.remove(node)
}
}
/**
* Remove a node at [position] in the list
*/
fun removeNodeAt(position: Int) {
nodeSortedList.removeItemAt(position)
mNodeSortedList.removeItemAt(position)
// Refresh all the next items
notifyItemRangeChanged(position, mNodeSortedList.size() - position)
}
/**
* Remove nodes in the list by [positions]
* Note : algorithm remove the higher position at each iteration
*/
fun removeNodesAt(positions: IntArray) {
val positionsSortDescending = positions.toMutableList()
positionsSortDescending.sortDescending()
positionsSortDescending.forEach {
removeNodeAt(it)
}
}
/**
@@ -190,215 +220,182 @@ class NodeAdapter
* @param oldNode Node before the update
* @param newNode Node after the update
*/
fun updateNode(oldNode: NodeVersioned, newNode: NodeVersioned) {
nodeSortedList.beginBatchedUpdates()
nodeSortedList.remove(oldNode)
nodeSortedList.add(newNode)
nodeSortedList.endBatchedUpdates()
fun updateNode(oldNode: Node, newNode: Node) {
mNodeSortedList.beginBatchedUpdates()
mNodeSortedList.remove(oldNode)
mNodeSortedList.add(newNode)
mNodeSortedList.endBatchedUpdates()
}
/**
* Update nodes in the list
* @param oldNodes Nodes before the update
* @param newNodes Node after the update
*/
fun updateNodes(oldNodes: List<Node>, newNodes: List<Node>) {
mNodeSortedList.beginBatchedUpdates()
oldNodes.forEach { oldNode ->
mNodeSortedList.remove(oldNode)
}
mNodeSortedList.addAll(newNodes)
mNodeSortedList.endBatchedUpdates()
}
fun notifyNodeChanged(node: Node) {
notifyItemChanged(mNodeSortedList.indexOf(node))
}
fun setActionNodes(actionNodes: List<Node>) {
this.mActionNodesList.apply {
clear()
addAll(actionNodes)
}
}
fun unselectActionNodes() {
mActionNodesList.forEach {
notifyItemChanged(mNodeSortedList.indexOf(it))
}
this.mActionNodesList.apply {
clear()
}
}
/**
* Notify a change sort of the list
*/
fun notifyChangeSort(sortNodeEnum: SortNodeEnum, ascending: Boolean, groupsBefore: Boolean) {
this.listSort = sortNodeEnum
this.ascendingSort = ascending
this.groupsBeforeSort = groupsBefore
fun notifyChangeSort(sortNodeEnum: SortNodeEnum,
sortNodeParameters: SortNodeEnum.SortNodeParameters) {
this.mNodeComparator = sortNodeEnum.getNodeComparator(sortNodeParameters)
}
override fun getItemViewType(position: Int): Int {
return nodeSortedList.get(position).type.ordinal
return mNodeSortedList.get(position).type.ordinal
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NodeViewHolder {
val view: View = if (viewType == Type.GROUP.ordinal) {
inflater.inflate(R.layout.item_list_nodes_group, parent, false)
mInflater.inflate(R.layout.item_list_nodes_group, parent, false)
} else {
inflater.inflate(R.layout.item_list_nodes_entry, parent, false)
mInflater.inflate(R.layout.item_list_nodes_entry, parent, false)
}
return NodeViewHolder(view)
val nodeViewHolder = NodeViewHolder(view)
mInfoTextDefaultDimension = nodeViewHolder.text.textSize
mSubtextDefaultDimension = nodeViewHolder.subText.textSize
nodeViewHolder.numberChildren?.let {
mNumberChildrenTextDefaultDimension = it.textSize
}
return nodeViewHolder
}
override fun onBindViewHolder(holder: NodeViewHolder, position: Int) {
val subNode = nodeSortedList.get(position)
val subNode = mNodeSortedList.get(position)
// Node selection
holder.container.isSelected = mActionNodesList.contains(subNode)
// Assign image
val iconColor = when (subNode.type) {
Type.GROUP -> iconGroupColor
Type.ENTRY -> iconEntryColor
val iconColor = if (holder.container.isSelected)
mContentSelectionColor
else when (subNode.type) {
Type.GROUP -> mIconGroupColor
Type.ENTRY -> mIconEntryColor
}
holder.imageIdentifier?.setColorFilter(iconColor)
holder.icon.apply {
assignDatabaseIcon(mDatabase.drawFactory, subNode.icon, iconColor)
mDatabase.iconDrawableFactory.assignDatabaseIcon(this, subNode.icon, iconColor)
// Relative size of the icon
layoutParams?.apply {
height = iconSize.toInt()
width = iconSize.toInt()
height = (mIconDefaultDimension * mPrefSizeMultiplier).toInt()
width = (mIconDefaultDimension * mPrefSizeMultiplier).toInt()
}
}
// Assign text
holder.text.apply {
text = subNode.title
setTextSize(textSizeUnit, infoTextSize)
setTextSize(mTextSizeUnit, mInfoTextDefaultDimension, mPrefSizeMultiplier)
strikeOut(subNode.isCurrentlyExpires)
}
// Assign click
holder.container.setOnClickListener { nodeClickCallback?.onNodeClick(subNode) }
// Context menu
if (activateContextMenu) {
holder.container.setOnCreateContextMenuListener(
ContextMenuBuilder(menuInflater, subNode, readOnly, isASearchResult, nodeMenuListener))
}
// Add subText with username
holder.subText.apply {
text = ""
strikeOut(subNode.isCurrentlyExpires)
visibility = View.GONE
if (subNode.type == Type.ENTRY) {
val entry = subNode as EntryVersioned
}
mDatabase.startManageEntry(entry)
holder.text.text = entry.getVisualTitle()
// Specific elements for entry
if (subNode.type == Type.ENTRY) {
val entry = subNode as Entry
mDatabase.startManageEntry(entry)
holder.text.text = entry.getVisualTitle()
holder.subText.apply {
val username = entry.username
if (showUserNames && username.isNotEmpty()) {
if (mShowUserNames && username.isNotEmpty()) {
visibility = View.VISIBLE
text = username
setTextSize(textSizeUnit, subtextSize)
setTextSize(mTextSizeUnit, mSubtextDefaultDimension, mPrefSizeMultiplier)
}
mDatabase.stopManageEntry(entry)
}
holder.attachmentIcon?.visibility =
if (entry.containsAttachment()) View.VISIBLE else View.GONE
mDatabase.stopManageEntry(entry)
}
// Add number of entries in groups
if (subNode.type == Type.GROUP) {
if (showNumberEntries) {
if (mShowNumberEntries) {
holder.numberChildren?.apply {
text = (subNode as GroupVersioned).getChildEntries(true).size.toString()
setTextSize(textSizeUnit, numberChildrenTextSize)
text = (subNode as Group)
.getNumberOfChildEntries(mEntryFilters)
.toString()
setTextSize(mTextSizeUnit, mNumberChildrenTextDefaultDimension, mPrefSizeMultiplier)
visibility = View.VISIBLE
}
} else {
holder.numberChildren?.visibility = View.GONE
}
}
}
// Assign click
holder.container.setOnClickListener {
mNodeClickCallback?.onNodeClick(subNode)
}
holder.container.setOnLongClickListener {
mNodeClickCallback?.onNodeLongClick(subNode) ?: false
}
}
override fun getItemCount(): Int {
return nodeSortedList.size()
return mNodeSortedList.size()
}
/**
* Assign a listener when a node is clicked
*/
fun setOnNodeClickListener(nodeClickCallback: NodeClickCallback?) {
this.nodeClickCallback = nodeClickCallback
}
/**
* Assign a listener when an element of menu is clicked
*/
fun setNodeMenuListener(nodeMenuListener: NodeMenuListener?) {
this.nodeMenuListener = nodeMenuListener
this.mNodeClickCallback = nodeClickCallback
}
/**
* Callback listener to redefine to do an action when a node is click
*/
interface NodeClickCallback {
fun onNodeClick(node: NodeVersioned)
}
/**
* Menu listener to redefine to do an action in menu
*/
interface NodeMenuListener {
fun onOpenMenuClick(node: NodeVersioned): Boolean
fun onEditMenuClick(node: NodeVersioned): Boolean
fun onCopyMenuClick(node: NodeVersioned): Boolean
fun onMoveMenuClick(node: NodeVersioned): Boolean
fun onDeleteMenuClick(node: NodeVersioned): Boolean
}
/**
* Utility class for menu listener
*/
private class ContextMenuBuilder(val menuInflater: MenuInflater,
val node: NodeVersioned,
val readOnly: Boolean,
val isASearchResult: Boolean,
val menuListener: NodeMenuListener?)
: View.OnCreateContextMenuListener {
private val mOnMyActionClickListener = MenuItem.OnMenuItemClickListener { item ->
if (menuListener == null)
return@OnMenuItemClickListener false
when (item.itemId) {
R.id.menu_open -> menuListener.onOpenMenuClick(node)
R.id.menu_edit -> menuListener.onEditMenuClick(node)
R.id.menu_copy -> menuListener.onCopyMenuClick(node)
R.id.menu_move -> menuListener.onMoveMenuClick(node)
R.id.menu_delete -> menuListener.onDeleteMenuClick(node)
else -> false
}
}
override fun onCreateContextMenu(contextMenu: ContextMenu?,
view: View?,
contextMenuInfo: ContextMenu.ContextMenuInfo?) {
menuInflater.inflate(R.menu.node_menu, contextMenu)
// Opening
var menuItem = contextMenu?.findItem(R.id.menu_open)
menuItem?.setOnMenuItemClickListener(mOnMyActionClickListener)
val database = Database.getInstance()
// Edition
if (readOnly || node == database.recycleBin) {
contextMenu?.removeItem(R.id.menu_edit)
} else {
menuItem = contextMenu?.findItem(R.id.menu_edit)
menuItem?.setOnMenuItemClickListener(mOnMyActionClickListener)
}
// Copy (not for group)
if (readOnly
|| isASearchResult
|| node == database.recycleBin
|| node.type == Type.GROUP) {
// TODO COPY For Group
contextMenu?.removeItem(R.id.menu_copy)
} else {
menuItem = contextMenu?.findItem(R.id.menu_copy)
menuItem?.setOnMenuItemClickListener(mOnMyActionClickListener)
}
// Move
if (readOnly
|| isASearchResult
|| node == database.recycleBin) {
contextMenu?.removeItem(R.id.menu_move)
} else {
menuItem = contextMenu?.findItem(R.id.menu_move)
menuItem?.setOnMenuItemClickListener(mOnMyActionClickListener)
}
// Deletion
if (readOnly || node == database.recycleBin) {
contextMenu?.removeItem(R.id.menu_delete)
} else {
menuItem = contextMenu?.findItem(R.id.menu_delete)
menuItem?.setOnMenuItemClickListener(mOnMyActionClickListener)
}
}
fun onNodeClick(node: Node)
fun onNodeLongClick(node: Node): Boolean
}
class NodeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var container: View = itemView.findViewById(R.id.node_container)
var imageIdentifier: ImageView? = itemView.findViewById(R.id.node_image_identifier)
var icon: ImageView = itemView.findViewById(R.id.node_icon)
var text: TextView = itemView.findViewById(R.id.node_text)
var subText: TextView = itemView.findViewById(R.id.node_subtext)
var numberChildren: TextView? = itemView.findViewById(R.id.node_child_numbers)
var attachmentIcon: ImageView? = itemView.findViewById(R.id.node_attachment_icon)
}
companion object {

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.adapters
@@ -22,27 +22,31 @@ package com.kunzisoft.keepass.adapters
import android.content.Context
import android.database.Cursor
import android.graphics.Color
import androidx.cursoradapter.widget.CursorAdapter
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.database.cursor.EntryCursor
import com.kunzisoft.keepass.database.cursor.EntryCursorKDB
import com.kunzisoft.keepass.database.cursor.EntryCursorKDBX
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.EntryVersioned
import com.kunzisoft.keepass.database.element.PwIcon
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.settings.PreferencesUtil
import java.util.*
import com.kunzisoft.keepass.view.strikeOut
class SearchEntryCursorAdapter(context: Context, private val database: Database)
class SearchEntryCursorAdapter(private val context: Context,
private val database: Database)
: androidx.cursoradapter.widget.CursorAdapter(context, null, FLAG_REGISTER_CONTENT_OBSERVER) {
private val cursorInflater: LayoutInflater = context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
private var displayUsername: Boolean = false
private val cursorInflater: LayoutInflater? = context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
private var mDisplayUsername: Boolean = false
private var mOmitBackup: Boolean = true
private val iconColor: Int
init {
@@ -55,12 +59,13 @@ class SearchEntryCursorAdapter(context: Context, private val database: Database)
}
fun reInit(context: Context) {
this.displayUsername = PreferencesUtil.showUsernamesListEntries(context)
this.mDisplayUsername = PreferencesUtil.showUsernamesListEntries(context)
this.mOmitBackup = PreferencesUtil.omitBackup(context)
}
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
val view = cursorInflater.inflate(R.layout.item_search_entry, parent, false)
val view = cursorInflater!!.inflate(R.layout.item_search_entry, parent, false)
val viewHolder = ViewHolder()
viewHolder.imageViewIcon = view.findViewById(R.id.entry_icon)
viewHolder.textViewTitle = view.findViewById(R.id.entry_text)
@@ -71,56 +76,105 @@ class SearchEntryCursorAdapter(context: Context, private val database: Database)
}
override fun bindView(view: View, context: Context, cursor: Cursor) {
getEntryFrom(cursor)?.let { currentEntry ->
val viewHolder = view.tag as ViewHolder
// Retrieve elements from cursor
val uuid = UUID(cursor.getLong(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_UUID_MOST_SIGNIFICANT_BITS)),
cursor.getLong(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_UUID_LEAST_SIGNIFICANT_BITS)))
val iconFactory = database.iconFactory
var icon: PwIcon = iconFactory.getIcon(
UUID(cursor.getLong(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_ICON_CUSTOM_UUID_MOST_SIGNIFICANT_BITS)),
cursor.getLong(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_ICON_CUSTOM_UUID_LEAST_SIGNIFICANT_BITS))))
if (icon.isUnknown) {
icon = iconFactory.getIcon(cursor.getInt(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_ICON_STANDARD)))
if (icon.isUnknown)
icon = iconFactory.keyIcon
}
val title = cursor.getString(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_TITLE))
val username = cursor.getString(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_USERNAME))
val url = cursor.getString(cursor.getColumnIndex(EntryCursor.COLUMN_INDEX_URL))
// Assign image
viewHolder.imageViewIcon?.let { iconView ->
database.iconDrawableFactory.assignDatabaseIcon(iconView, currentEntry.icon, iconColor)
}
val viewHolder = view.tag as ViewHolder
// Assign title
viewHolder.textViewTitle?.apply {
text = currentEntry.getVisualTitle()
strikeOut(currentEntry.isCurrentlyExpires)
}
// Assign image
viewHolder.imageViewIcon?.assignDatabaseIcon(database.drawFactory, icon, iconColor)
// Assign title
val showTitle = EntryVersioned.getVisualTitle(false, title, username, url, uuid.toString())
viewHolder.textViewTitle?.text = showTitle
if (displayUsername && username.isNotEmpty()) {
viewHolder.textViewSubTitle?.text = String.format("(%s)", username)
} else {
viewHolder.textViewSubTitle?.text = ""
// Assign subtitle
viewHolder.textViewSubTitle?.apply {
val entryUsername = currentEntry.username
text = if (mDisplayUsername && entryUsername.isNotEmpty()) {
String.format("(%s)", entryUsername)
} else {
""
}
visibility = if (text.isEmpty()) View.GONE else View.VISIBLE
strikeOut(currentEntry.isCurrentlyExpires)
}
}
}
private class ViewHolder {
internal var imageViewIcon: ImageView? = null
internal var textViewTitle: TextView? = null
internal var textViewSubTitle: TextView? = null
private fun getEntryFrom(cursor: Cursor): Entry? {
return database.createEntry()?.apply {
entryKDB?.let { entryKDB ->
(cursor as EntryCursorKDB).populateEntry(entryKDB,
{ standardIconId ->
database.getStandardIcon(standardIconId)
},
{ customIconId ->
database.getCustomIcon(customIconId)
}
)
}
entryKDBX?.let { entryKDBX ->
(cursor as EntryCursorKDBX).populateEntry(entryKDBX,
{ standardIconId ->
database.getStandardIcon(standardIconId)
},
{ customIconId ->
database.getCustomIcon(customIconId)
}
)
}
}
}
override fun runQueryOnBackgroundThread(constraint: CharSequence): Cursor? {
return database.searchEntries(constraint.toString())
return searchEntries(context, constraint.toString())
}
fun getEntryFromPosition(position: Int): EntryVersioned? {
var pwEntry: EntryVersioned? = null
private fun searchEntries(context: Context, query: String): Cursor? {
var cursorKDB: EntryCursorKDB? = null
var cursorKDBX: EntryCursorKDBX? = null
if (database.type == DatabaseKDB.TYPE)
cursorKDB = EntryCursorKDB()
if (database.type == DatabaseKDBX.TYPE)
cursorKDBX = EntryCursorKDBX()
val searchGroup = database.createVirtualGroupFromSearch(query,
mOmitBackup,
SearchHelper.MAX_SEARCH_ENTRY)
if (searchGroup != null) {
// Search in hide entries but not meta-stream
for (entry in searchGroup.getFilteredChildEntries(Group.ChildFilter.getDefaults(context))) {
database.startManageEntry(entry)
entry.entryKDB?.let {
cursorKDB?.addEntry(it)
}
entry.entryKDBX?.let {
cursorKDBX?.addEntry(it)
}
database.stopManageEntry(entry)
}
}
return cursorKDB ?: cursorKDBX
}
fun getEntryFromPosition(position: Int): Entry? {
var pwEntry: Entry? = null
val cursor = this.cursor
if (cursor.moveToFirst() && cursor.move(position)) {
pwEntry = database.getEntryFrom(cursor)
pwEntry = getEntryFrom(cursor)
}
return pwEntry
}
private class ViewHolder {
var imageViewIcon: ImageView? = null
var textViewTitle: TextView? = null
var textViewSubTitle: TextView? = null
}
}

View File

@@ -1,20 +1,20 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
* This file is part of KeePassDX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* 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.
*
* KeePass DX is distributed in the hope that it will be useful,
* 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.app
@@ -22,18 +22,19 @@ package com.kunzisoft.keepass.app
import androidx.multidex.MultiDexApplication
import com.kunzisoft.keepass.activities.stylish.Stylish
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.utils.UriUtil
class App : MultiDexApplication() {
override fun onCreate() {
super.onCreate()
Stylish.init(this)
Stylish.load(this)
PRNGFixes.apply()
}
override fun onTerminate() {
Database.getInstance().closeAndClear(applicationContext.filesDir)
Database.getInstance().clearAndClose(UriUtil.getBinaryDir(this))
super.onTerminate()
}
}

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