Compare commits

..

103 Commits

Author SHA1 Message Date
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
117 changed files with 2657 additions and 1324 deletions

View File

@@ -1,3 +1,16 @@
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) KeePassDX(2.5beta28)
* Fix read only database * Fix read only database
* Upgrade to Android SDK 29 * Upgrade to Android SDK 29

View File

@@ -30,7 +30,7 @@ KeePassDX is a **free open source password manager for Android**, which helps yo
Yes, KeePassDX 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. Yes, KeePassDX 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.* *Note : If you access the application from a store, visual styles may not be available to encourage contribution to the work of open source projects. These optional styles are accessible after a contribution (and a 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 ## Contributions

View File

@@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass" applicationId "com.kunzisoft.keepass"
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 29 targetSdkVersion 29
versionCode = 28 versionCode = 30
versionName = "2.5beta28" versionName = "2.5beta30"
multiDexEnabled true multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests" testApplicationId = "com.kunzisoft.keepass.tests"
@@ -86,7 +86,7 @@ android {
} }
def spongycastleVersion = "1.58.0.0" def spongycastleVersion = "1.58.0.0"
def room_version = "2.2.4" def room_version = "2.2.5"
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View File

@@ -541,12 +541,10 @@ class EntryActivity : LockingActivity() {
override fun finish() { override fun finish() {
// Transit data in previous Activity after an update // Transit data in previous Activity after an update
/* Intent().apply {
TODO Slowdown when add entry as result putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry)
Intent intent = new Intent(); setResult(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, this)
intent.putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry); }
onFinish(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, intent);
*/
super.finish() super.finish()
} }

View File

@@ -19,6 +19,8 @@
package com.kunzisoft.keepass.activities package com.kunzisoft.keepass.activities
import android.app.Activity import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@@ -26,13 +28,15 @@ import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.ScrollView import android.widget.DatePicker
import android.widget.TimePicker
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.widget.NestedScrollView
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.GeneratePasswordDialogFragment import com.kunzisoft.keepass.activities.dialogs.*
import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment
import com.kunzisoft.keepass.activities.dialogs.SetOTPDialogFragment
import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.DateInstant import com.kunzisoft.keepass.database.element.DateInstant
@@ -52,12 +56,15 @@ import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.MenuUtil import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.EntryEditContentsView import com.kunzisoft.keepass.view.EntryEditContentsView
import com.kunzisoft.keepass.view.showActionError import com.kunzisoft.keepass.view.showActionError
import org.joda.time.DateTime
import java.util.* import java.util.*
class EntryEditActivity : LockingActivity(), class EntryEditActivity : LockingActivity(),
IconPickerDialogFragment.IconPickerListener, IconPickerDialogFragment.IconPickerListener,
GeneratePasswordDialogFragment.GeneratePasswordListener, GeneratePasswordDialogFragment.GeneratePasswordListener,
SetOTPDialogFragment.CreateOtpListener { SetOTPDialogFragment.CreateOtpListener,
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener {
private var mDatabase: Database? = null private var mDatabase: Database? = null
@@ -70,8 +77,9 @@ class EntryEditActivity : LockingActivity(),
// Views // Views
private var coordinatorLayout: CoordinatorLayout? = null private var coordinatorLayout: CoordinatorLayout? = null
private var scrollView: ScrollView? = null private var scrollView: NestedScrollView? = null
private var entryEditContentsView: EntryEditContentsView? = null private var entryEditContentsView: EntryEditContentsView? = null
private var entryEditAddToolBar: ActionMenuView? = null
private var saveView: View? = null private var saveView: View? = null
// Education // Education
@@ -94,6 +102,16 @@ class EntryEditActivity : LockingActivity(),
entryEditContentsView = findViewById(R.id.entry_edit_contents) entryEditContentsView = findViewById(R.id.entry_edit_contents)
entryEditContentsView?.applyFontVisibilityToFields(PreferencesUtil.fieldFontIsInVisibility(this)) entryEditContentsView?.applyFontVisibilityToFields(PreferencesUtil.fieldFontIsInVisibility(this))
entryEditContentsView?.onDateClickListener = View.OnClickListener {
entryEditContentsView?.expiresDate?.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(supportFragmentManager, "DatePickerFragment")
}
}
// Focus view to reinitialize timeout // Focus view to reinitialize timeout
resetAppTimeoutWhenViewFocusedOrChanged(entryEditContentsView) resetAppTimeoutWhenViewFocusedOrChanged(entryEditContentsView)
@@ -167,17 +185,46 @@ class EntryEditActivity : LockingActivity(),
// Add listener to the icon // Add listener to the icon
entryEditContentsView?.setOnIconViewClickListener { IconPickerDialogFragment.launch(this@EntryEditActivity) } entryEditContentsView?.setOnIconViewClickListener { IconPickerDialogFragment.launch(this@EntryEditActivity) }
// Generate password button // Bottom Bar
entryEditContentsView?.setOnPasswordGeneratorClickListener { openPasswordGenerator() } entryEditAddToolBar = findViewById(R.id.entry_edit_bottom_bar)
entryEditAddToolBar?.apply {
menuInflater.inflate(R.menu.entry_edit, menu)
menu.findItem(R.id.menu_add_field).apply {
val allowCustomField = mNewEntry?.allowCustomFields() == true
isEnabled = allowCustomField
isVisible = allowCustomField
}
menu.findItem(R.id.menu_add_otp).apply {
val allowOTP = mDatabase?.allowOTP == true
isEnabled = allowOTP
isVisible = allowOTP
}
setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.menu_generate_password -> {
openPasswordGenerator()
true
}
R.id.menu_add_field -> {
addNewCustomField()
true
}
R.id.menu_add_otp -> {
setupOTP()
true
}
else -> true
}
}
}
// Save button // Save button
saveView = findViewById(R.id.entry_edit_save) saveView = findViewById(R.id.entry_edit_validate)
saveView?.setOnClickListener { saveEntry() } saveView?.setOnClickListener { saveEntry() }
entryEditContentsView?.allowCustomField(mNewEntry?.allowCustomFields() == true) {
addNewCustomField()
}
// Verify the education views // Verify the education views
entryEditActivityEducation = EntryEditActivityEducation(this) entryEditActivityEducation = EntryEditActivityEducation(this)
@@ -207,6 +254,9 @@ class EntryEditActivity : LockingActivity(),
username = if (newEntry.username.isEmpty()) mDatabase?.defaultUsername ?:"" else newEntry.username username = if (newEntry.username.isEmpty()) mDatabase?.defaultUsername ?:"" else newEntry.username
url = newEntry.url url = newEntry.url
password = newEntry.password password = newEntry.password
expires = newEntry.expires
if (expires)
expiresDate = newEntry.expiryTime
notes = newEntry.notes notes = newEntry.notes
for (entry in newEntry.customFields.entries) { for (entry in newEntry.customFields.entries) {
post { post {
@@ -228,7 +278,11 @@ class EntryEditActivity : LockingActivity(),
username = entryView.username username = entryView.username
url = entryView.url url = entryView.url
password = entryView.password password = entryView.password
notes = entryView.notes expires = entryView.expires
if (entryView.expires) {
expiryTime = entryView.expiresDate
}
notes = entryView. notes
entryView.customFields.forEach { customField -> entryView.customFields.forEach { customField ->
putExtraField(customField.name, customField.protectedValue) putExtraField(customField.name, customField.protectedValue)
} }
@@ -259,6 +313,13 @@ class EntryEditActivity : LockingActivity(),
entryEditContentsView?.addEmptyCustomField() entryEditContentsView?.addEmptyCustomField()
} }
private fun setupOTP() {
// Retrieve the current otpElement if exists
// and open the dialog to set up the OTP
SetOTPDialogFragment.build(mEntry?.getOtpElement()?.otpModel)
.show(supportFragmentManager, "addOTPDialog")
}
/** /**
* Saves the new entry or update an existing entry in the database * Saves the new entry or update an existing entry in the database
*/ */
@@ -307,8 +368,6 @@ class EntryEditActivity : LockingActivity(),
// Save database not needed here // Save database not needed here
menu.findItem(R.id.menu_save_database)?.isVisible = false menu.findItem(R.id.menu_save_database)?.isVisible = false
MenuUtil.contributionMenuInflater(inflater, menu) MenuUtil.contributionMenuInflater(inflater, menu)
if (mDatabase?.allowOTP == true)
inflater.inflate(R.menu.entry_otp, menu)
entryEditActivityEducation?.let { entryEditActivityEducation?.let {
Handler().post { performedNextEducation(it) } Handler().post { performedNextEducation(it) }
@@ -318,12 +377,10 @@ class EntryEditActivity : LockingActivity(),
} }
private fun performedNextEducation(entryEditActivityEducation: EntryEditActivityEducation) { private fun performedNextEducation(entryEditActivityEducation: EntryEditActivityEducation) {
val passwordView = entryEditContentsView?.generatePasswordView val passwordGeneratorView: View? = entryEditAddToolBar?.findViewById(R.id.menu_generate_password)
val addNewFieldView = entryEditContentsView?.addNewFieldButton val generatePasswordEducationPerformed = passwordGeneratorView != null
val generatePasswordEducationPerformed = passwordView != null
&& entryEditActivityEducation.checkAndPerformedGeneratePasswordEducation( && entryEditActivityEducation.checkAndPerformedGeneratePasswordEducation(
passwordView, passwordGeneratorView,
{ {
openPasswordGenerator() openPasswordGenerator()
}, },
@@ -332,14 +389,28 @@ class EntryEditActivity : LockingActivity(),
} }
) )
if (!generatePasswordEducationPerformed) { if (!generatePasswordEducationPerformed) {
// entryNewFieldEducationPerformed val addNewFieldView: View? = entryEditAddToolBar?.findViewById(R.id.menu_add_field)
mNewEntry != null && mNewEntry!!.allowCustomFields() && mNewEntry!!.customFields.isEmpty() val addNewFieldEducationPerformed = mNewEntry != null
&& mNewEntry!!.allowCustomFields() && mNewEntry!!.customFields.isEmpty()
&& addNewFieldView != null && addNewFieldView.visibility == View.VISIBLE && addNewFieldView != null && addNewFieldView.visibility == View.VISIBLE
&& entryEditActivityEducation.checkAndPerformedEntryNewFieldEducation( && entryEditActivityEducation.checkAndPerformedEntryNewFieldEducation(
addNewFieldView, addNewFieldView,
{ {
addNewCustomField() addNewCustomField()
}) },
{
performedNextEducation(entryEditActivityEducation)
}
)
if (!addNewFieldEducationPerformed) {
val setupOtpView: View? = entryEditAddToolBar?.findViewById(R.id.menu_add_otp)
setupOtpView != null && setupOtpView.visibility == View.VISIBLE
&& entryEditActivityEducation.checkAndPerformedSetUpOTPEducation(
setupOtpView,
{
setupOTP()
})
}
} }
} }
@@ -356,14 +427,9 @@ class EntryEditActivity : LockingActivity(),
MenuUtil.onContributionItemSelected(this) MenuUtil.onContributionItemSelected(this)
return true return true
} }
R.id.menu_add_otp -> { android.R.id.home -> {
// Retrieve the current otpElement if exists onBackPressed()
// and open the dialog to set up the OTP
SetOTPDialogFragment.build(mEntry?.getOtpElement()?.otpModel)
.show(supportFragmentManager, "addOTPDialog")
return true
} }
android.R.id.home -> finish()
} }
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
@@ -383,6 +449,39 @@ class EntryEditActivity : LockingActivity(),
} }
} }
override fun onDateSet(datePicker: DatePicker?, year: Int, month: Int, day: Int) {
// To fix android 4.4 issue
// https://stackoverflow.com/questions/12436073/datepicker-ondatechangedlistener-called-twice
if (datePicker?.isShown == true) {
entryEditContentsView?.expiresDate?.date?.let { expiresDate ->
// Save the date
entryEditContentsView?.expiresDate =
DateInstant(DateTime(expiresDate)
.withYear(year)
.withMonthOfYear(month + 1)
.withDayOfMonth(day)
.toDate())
// Launch the time picker
val dateTime = DateTime(expiresDate)
val defaultHour = dateTime.hourOfDay
val defaultMinute = dateTime.minuteOfHour
TimePickerFragment.getInstance(defaultHour, defaultMinute)
.show(supportFragmentManager, "TimePickerFragment")
}
}
}
override fun onTimeSet(timePicker: TimePicker?, hours: Int, minutes: Int) {
entryEditContentsView?.expiresDate?.date?.let { expiresDate ->
// Save the date
entryEditContentsView?.expiresDate =
DateInstant(DateTime(expiresDate)
.withHourOfDay(hours)
.withMinuteOfHour(minutes)
.toDate())
}
}
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
mNewEntry?.let { mNewEntry?.let {
populateEntryWithViews(it) populateEntryWithViews(it)
@@ -406,6 +505,15 @@ class EntryEditActivity : LockingActivity(),
// Do nothing here // Do nothing here
} }
override fun onBackPressed() {
AlertDialog.Builder(this)
.setMessage(R.string.discard_changes)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.discard) { _, _ ->
super@EntryEditActivity.onBackPressed()
}.create().show()
}
override fun finish() { override fun finish() {
// Assign entry callback as a result in all case // Assign entry callback as a result in all case
try { try {

View File

@@ -35,6 +35,7 @@ import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator import androidx.recyclerview.widget.SimpleItemAnimator
@@ -61,6 +62,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
AssignMasterKeyDialogFragment.AssignPasswordDialogListener { AssignMasterKeyDialogFragment.AssignPasswordDialogListener {
// Views // Views
private var coordinatorLayout: CoordinatorLayout? = null
private var fileListContainer: View? = null private var fileListContainer: View? = null
private var createButtonView: View? = null private var createButtonView: View? = null
private var openDatabaseButtonView: View? = null private var openDatabaseButtonView: View? = null
@@ -82,6 +84,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(applicationContext) mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(applicationContext)
setContentView(R.layout.activity_file_selection) setContentView(R.layout.activity_file_selection)
coordinatorLayout = findViewById(R.id.activity_file_selection_coordinator_layout)
fileListContainer = findViewById(R.id.container_file_list) fileListContainer = findViewById(R.id.container_file_list)
val toolbar = findViewById<Toolbar>(R.id.toolbar) val toolbar = findViewById<Toolbar>(R.id.toolbar)
@@ -161,9 +164,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
onActionFinish = { actionTask, _ -> onActionFinish = { actionTask, _ ->
when (actionTask) { when (actionTask) {
ACTION_DATABASE_CREATE_TASK -> { ACTION_DATABASE_CREATE_TASK -> {
// TODO Check
// mAdapterDatabaseHistory?.notifyDataSetChanged()
// updateFileListVisibility()
GroupActivity.launch(this@FileDatabaseSelectActivity) GroupActivity.launch(this@FileDatabaseSelectActivity)
} }
} }
@@ -182,7 +182,9 @@ class FileDatabaseSelectActivity : StylishActivity(),
private fun fileNoFoundAction(e: FileNotFoundException) { private fun fileNoFoundAction(e: FileNotFoundException) {
val error = getString(R.string.file_not_found_content) val error = getString(R.string.file_not_found_content)
Snackbar.make(activity_file_selection_coordinator_layout, error, Snackbar.LENGTH_LONG).asError().show() coordinatorLayout?.let {
Snackbar.make(it, error, Snackbar.LENGTH_LONG).asError().show()
}
Log.e(TAG, error, e) Log.e(TAG, error, e)
} }
@@ -281,9 +283,8 @@ class FileDatabaseSelectActivity : StylishActivity(),
// Show only uri accessible // Show only uri accessible
historyList.filter { historyList.filter {
if (hideBrokenLocations) { if (hideBrokenLocations) {
UriUtil.parse(it.databaseUri)?.let { historyUri -> FileDatabaseInfo(this@FileDatabaseSelectActivity,
UriUtil.isUriAccessible(contentResolver, historyUri) it.databaseUri).exists
} ?: false
} else } else
true true
}) })
@@ -372,10 +373,13 @@ class FileDatabaseSelectActivity : StylishActivity(),
if (mDatabaseFileUri != null) { if (mDatabaseFileUri != null) {
AssignMasterKeyDialogFragment.getInstance(true) AssignMasterKeyDialogFragment.getInstance(true)
.show(supportFragmentManager, "passwordDialog") .show(supportFragmentManager, "passwordDialog")
} else {
val error = getString(R.string.error_create_database)
coordinatorLayout?.let {
Snackbar.make(it, error, Snackbar.LENGTH_LONG).asError().show()
}
Log.e(TAG, error)
} }
// else {
// TODO Show error
// }
} }
} }

View File

@@ -439,8 +439,7 @@ class GroupActivity : LockingActivity(),
enableAddGroup(addGroupEnabled) enableAddGroup(addGroupEnabled)
enableAddEntry(addEntryEnabled) enableAddEntry(addEntryEnabled)
if (isEnable) showButton()
showButton()
} }
} }
@@ -504,6 +503,7 @@ class GroupActivity : LockingActivity(),
private fun finishNodeAction() { private fun finishNodeAction() {
actionNodeMode?.finish() actionNodeMode?.finish()
actionNodeMode = null actionNodeMode = null
addNodeButtonView?.showButton()
} }
override fun onNodeSelected(nodes: List<Node>): Boolean { override fun onNodeSelected(nodes: List<Node>): Boolean {
@@ -515,6 +515,7 @@ class GroupActivity : LockingActivity(),
} else { } else {
actionNodeMode?.invalidate() actionNodeMode?.invalidate()
} }
addNodeButtonView?.hideButton()
} else { } else {
finishNodeAction() finishNodeAction()
} }
@@ -664,13 +665,15 @@ class GroupActivity : LockingActivity(),
} }
// Get the SearchView and set the searchable configuration // Get the SearchView and set the searchable configuration
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager?
menu.findItem(R.id.menu_search)?.let { menu.findItem(R.id.menu_search)?.let {
val searchView = it.actionView as SearchView? val searchView = it.actionView as SearchView?
searchView?.apply { searchView?.apply {
setSearchableInfo(searchManager.getSearchableInfo( (searchManager?.getSearchableInfo(
ComponentName(this@GroupActivity, GroupActivity::class.java))) ComponentName(this@GroupActivity, GroupActivity::class.java)))?.let { searchableInfo ->
setSearchableInfo(searchableInfo)
}
setIconifiedByDefault(false) // Do not iconify the widget; expand it by default setIconifiedByDefault(false) // Do not iconify the widget; expand it by default
suggestionsAdapter = mSearchSuggestionAdapter suggestionsAdapter = mSearchSuggestionAdapter
setOnSuggestionListener(object : SearchView.OnSuggestionListener { setOnSuggestionListener(object : SearchView.OnSuggestionListener {
@@ -905,8 +908,8 @@ class GroupActivity : LockingActivity(),
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data) AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
} }
// Not directly get the entry from intent data but from database // Directly used the onActivityResult in fragment
mListNodesFragment?.rebuildList() mListNodesFragment?.onActivityResult(requestCode, resultCode, data)
} }
private fun removeSearchInIntent(intent: Intent) { private fun removeSearchInIntent(intent: Intent) {
@@ -953,19 +956,27 @@ class GroupActivity : LockingActivity(),
private const val SEARCH_FRAGMENT_TAG = "SEARCH_FRAGMENT_TAG" private const val SEARCH_FRAGMENT_TAG = "SEARCH_FRAGMENT_TAG"
private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY" private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY"
private fun buildAndLaunchIntent(context: Context, group: Group?, readOnly: Boolean, private fun buildIntent(context: Context, group: Group?, readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) { intentBuildLauncher: (Intent) -> Unit) {
val checkTime = if (context is Activity) val intent = Intent(context, GroupActivity::class.java)
TimeoutHelper.checkTimeAndLockIfTimeout(context) if (group != null) {
else intent.putExtra(GROUP_ID_KEY, group.nodeId)
TimeoutHelper.checkTime(context) }
if (checkTime) { ReadOnlyHelper.putReadOnlyInIntent(intent, readOnly)
val intent = Intent(context, GroupActivity::class.java) intentBuildLauncher.invoke(intent)
if (group != null) { }
intent.putExtra(GROUP_ID_KEY, group.nodeId)
} private fun checkTimeAndBuildIntent(activity: Activity, group: Group?, readOnly: Boolean,
ReadOnlyHelper.putReadOnlyInIntent(intent, readOnly) intentBuildLauncher: (Intent) -> Unit) {
intentBuildLauncher.invoke(intent) if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
buildIntent(activity, group, readOnly, intentBuildLauncher)
}
}
private fun checkTimeAndBuildIntent(context: Context, group: Group?, readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTime(context)) {
buildIntent(context, group, readOnly, intentBuildLauncher)
} }
} }
@@ -976,9 +987,9 @@ class GroupActivity : LockingActivity(),
*/ */
@JvmOverloads @JvmOverloads
fun launch(context: Context, readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) { fun launch(context: Context,
TimeoutHelper.recordTime(context) readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
buildAndLaunchIntent(context, null, readOnly) { intent -> checkTimeAndBuildIntent(context, null, readOnly) { intent ->
context.startActivity(intent) context.startActivity(intent)
} }
} }
@@ -990,9 +1001,9 @@ class GroupActivity : LockingActivity(),
*/ */
// TODO implement pre search to directly open the direct group // TODO implement pre search to directly open the direct group
fun launchForKeyboardSelection(context: Context, readOnly: Boolean) { fun launchForKeyboardSelection(context: Context,
TimeoutHelper.recordTime(context) readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
buildAndLaunchIntent(context, null, readOnly) { intent -> checkTimeAndBuildIntent(context, null, readOnly) { intent ->
EntrySelectionHelper.startActivityForEntrySelection(context, intent) EntrySelectionHelper.startActivityForEntrySelection(context, intent)
} }
} }
@@ -1005,9 +1016,10 @@ class GroupActivity : LockingActivity(),
// TODO implement pre search to directly open the direct group // TODO implement pre search to directly open the direct group
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity, assistStructure: AssistStructure, readOnly: Boolean) { fun launchForAutofillResult(activity: Activity,
TimeoutHelper.recordTime(activity) assistStructure: AssistStructure,
buildAndLaunchIntent(activity, null, readOnly) { intent -> readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(activity)) {
checkTimeAndBuildIntent(activity, null, readOnly) { intent ->
AutofillHelper.startActivityForAutofillResult(activity, intent, assistStructure) AutofillHelper.startActivityForAutofillResult(activity, intent, assistStructure)
} }
} }

View File

@@ -369,13 +369,11 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE -> { EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE -> {
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE
|| resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) { || resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) {
data?.getParcelableExtra<Node>(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY)?.let { newNode -> data?.getParcelableExtra<Node>(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY)?.let { changedNode ->
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE) if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE)
mAdapter?.addNode(newNode) addNode(changedNode)
if (resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) { if (resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE)
//mAdapter.updateLastNodeRegister(newNode); mAdapter?.notifyDataSetChanged()
rebuildList()
}
} ?: Log.e(this.javaClass.name, "New node can be retrieve in Activity Result") } ?: Log.e(this.javaClass.name, "New node can be retrieve in Activity Result")
} }
} }

View File

@@ -111,8 +111,6 @@ open class PasswordActivity : StylishActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
setContentView(R.layout.activity_password) setContentView(R.layout.activity_password)
toolbar = findViewById(R.id.toolbar) toolbar = findViewById(R.id.toolbar)
@@ -165,6 +163,12 @@ open class PasswordActivity : StylishActivity() {
enableOrNotTheConfirmationButton() enableOrNotTheConfirmationButton()
} }
// If is a view intent
getUriFromIntent(intent)
if (savedInstanceState?.containsKey(KEY_KEYFILE) == true) {
mDatabaseKeyFileUri = UriUtil.parse(savedInstanceState.getString(KEY_KEYFILE))
}
mProgressDialogThread = ProgressDialogThread(this).apply { mProgressDialogThread = ProgressDialogThread(this).apply {
onActionFinish = { actionTask, result -> onActionFinish = { actionTask, result ->
when (actionTask) { when (actionTask) {
@@ -177,11 +181,9 @@ open class PasswordActivity : StylishActivity() {
} }
} }
// Remove the password in view in all cases
removePassword()
if (result.isSuccess) { if (result.isSuccess) {
setEmptyViews() mDatabaseKeyFileUri = null
clearCredentialsViews(true)
launchGroupActivity() launchGroupActivity()
} else { } else {
var resultError = "" var resultError = ""
@@ -237,6 +239,24 @@ open class PasswordActivity : StylishActivity() {
} }
} }
private fun getUriFromIntent(intent: Intent?) {
// If is a view intent
val action = intent?.action
if (action != null
&& action == VIEW_INTENT) {
mDatabaseFileUri = intent.data
mDatabaseKeyFileUri = UriUtil.getUriFromIntent(intent, KEY_KEYFILE)
} else {
mDatabaseFileUri = intent?.getParcelableExtra(KEY_FILENAME)
mDatabaseKeyFileUri = intent?.getParcelableExtra(KEY_KEYFILE)
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
getUriFromIntent(intent)
}
private fun launchGroupActivity() { private fun launchGroupActivity() {
EntrySelectionHelper.doEntrySelectionAction(intent, EntrySelectionHelper.doEntrySelectionAction(intent,
{ {
@@ -265,13 +285,15 @@ open class PasswordActivity : StylishActivity() {
} }
override fun onResume() { override fun onResume() {
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
if (Database.getInstance().loaded) if (Database.getInstance().loaded)
launchGroupActivity() launchGroupActivity()
// If the database isn't accessible make sure to clear the password field, if it // If the database isn't accessible make sure to clear the password field, if it
// was saved in the instance state // was saved in the instance state
if (Database.getInstance().loaded) { if (Database.getInstance().loaded) {
setEmptyViews() clearCredentialsViews()
} }
// For check shutdown // For check shutdown
@@ -283,46 +305,37 @@ open class PasswordActivity : StylishActivity() {
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
mDatabaseKeyFileUri?.let {
outState.putString(KEY_KEYFILE, it.toString())
}
ReadOnlyHelper.onSaveInstanceState(outState, readOnly) ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
} }
private fun initUriFromIntent() { private fun initUriFromIntent() {
/*
val databaseUri: Uri? // "canXrite" doesn't work with Google Drive, don't really know why?
val keyFileUri: Uri? mForceReadOnly = mDatabaseFileUri?.let {
!FileDatabaseInfo(this, it).canWrite
// If is a view intent } ?: false
val action = intent.action */
if (action != null mForceReadOnly = false
&& action == VIEW_INTENT) {
databaseUri = intent.data
keyFileUri = UriUtil.getUriFromIntent(intent, KEY_KEYFILE)
} else {
databaseUri = intent.getParcelableExtra(KEY_FILENAME)
keyFileUri = intent.getParcelableExtra(KEY_KEYFILE)
}
mForceReadOnly = !UriUtil.isUriWritable(contentResolver, databaseUri)
// Post init uri with KeyFile if needed // Post init uri with KeyFile if needed
if (mRememberKeyFile && (keyFileUri == null || keyFileUri.toString().isEmpty())) { if (mRememberKeyFile && (mDatabaseKeyFileUri == null || mDatabaseKeyFileUri.toString().isEmpty())) {
// Retrieve KeyFile in a thread // Retrieve KeyFile in a thread
databaseUri?.let { databaseUriNotNull -> mDatabaseFileUri?.let { databaseUri ->
FileDatabaseHistoryAction.getInstance(applicationContext) FileDatabaseHistoryAction.getInstance(applicationContext)
.getKeyFileUriByDatabaseUri(databaseUriNotNull) { .getKeyFileUriByDatabaseUri(databaseUri) {
onPostInitUri(databaseUri, it) onPostInitUri(databaseUri, it)
} }
} }
} else { } else {
onPostInitUri(databaseUri, keyFileUri) onPostInitUri(mDatabaseFileUri, mDatabaseKeyFileUri)
} }
} }
private fun onPostInitUri(databaseFileUri: Uri?, keyFileUri: Uri?) { private fun onPostInitUri(databaseFileUri: Uri?, keyFileUri: Uri?) {
mDatabaseFileUri = databaseFileUri
mDatabaseKeyFileUri = keyFileUri
// Define title // Define title
databaseFileUri?.let { databaseFileUri?.let {
FileDatabaseInfo(this, it).retrieveDatabaseTitle { title -> FileDatabaseInfo(this, it).retrieveDatabaseTitle { title ->
@@ -331,9 +344,8 @@ open class PasswordActivity : StylishActivity() {
} }
// Define Key File text // Define Key File text
val keyUriString = keyFileUri?.toString() ?: "" if (mRememberKeyFile) {
if (keyUriString.isNotEmpty() && mRememberKeyFile) { // Bug KeepassDX #18 populateKeyFileTextView(keyFileUri?.toString())
populateKeyFileTextView(keyUriString)
} }
// Define listeners for default database checkbox and validate button // Define listeners for default database checkbox and validate button
@@ -428,10 +440,9 @@ open class PasswordActivity : StylishActivity() {
} }
} }
private fun setEmptyViews() { private fun clearCredentialsViews(clearKeyFile: Boolean = !mRememberKeyFile) {
populatePasswordTextView(null) populatePasswordTextView(null)
// Bug KeepassDX #18 if (clearKeyFile) {
if (!mRememberKeyFile) {
populateKeyFileTextView(null) populateKeyFileTextView(null)
} }
} }
@@ -497,18 +508,13 @@ open class PasswordActivity : StylishActivity() {
mDatabaseKeyFileUri = if (checkboxKeyFileView?.isChecked != true) null else keyFile mDatabaseKeyFileUri = if (checkboxKeyFileView?.isChecked != true) null else keyFile
} }
private fun removePassword() {
passwordView?.setText("")
checkboxPasswordView?.isChecked = false
}
private fun loadDatabase(databaseFileUri: Uri?, private fun loadDatabase(databaseFileUri: Uri?,
password: String?, password: String?,
keyFileUri: Uri?, keyFileUri: Uri?,
cipherDatabaseEntity: CipherDatabaseEntity? = null) { cipherDatabaseEntity: CipherDatabaseEntity? = null) {
if (PreferencesUtil.deletePasswordAfterConnexionAttempt(this)) { if (PreferencesUtil.deletePasswordAfterConnexionAttempt(this)) {
removePassword() clearCredentialsViews()
} }
databaseFileUri?.let { databaseUri -> databaseFileUri?.let { databaseUri ->
@@ -671,6 +677,7 @@ open class PasswordActivity : StylishActivity() {
keyFileResult = it.onActivityResultCallback(requestCode, resultCode, data keyFileResult = it.onActivityResultCallback(requestCode, resultCode, data
) { uri -> ) { uri ->
if (uri != null) { if (uri != null) {
mDatabaseKeyFileUri = uri
populateKeyFileTextView(uri.toString()) populateKeyFileTextView(uri.toString())
} }
} }
@@ -679,7 +686,7 @@ open class PasswordActivity : StylishActivity() {
// this block if not a key file response // this block if not a key file response
when (resultCode) { when (resultCode) {
LockingActivity.RESULT_EXIT_LOCK, Activity.RESULT_CANCELED -> { LockingActivity.RESULT_EXIT_LOCK, Activity.RESULT_CANCELED -> {
setEmptyViews() clearCredentialsViews()
Database.getInstance().closeAndClear(applicationContext.filesDir) Database.getInstance().closeAndClear(applicationContext.filesDir)
} }
} }

View File

@@ -0,0 +1,61 @@
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 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,57 @@
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 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

@@ -20,11 +20,7 @@
package com.kunzisoft.keepass.activities.lock package com.kunzisoft.keepass.activities.lock
import android.app.Activity import android.app.Activity
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
@@ -34,12 +30,9 @@ import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.stylish.StylishActivity import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.database.action.ProgressDialogThread import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.LOCK_ACTION import com.kunzisoft.keepass.utils.*
abstract class LockingActivity : StylishActivity() { abstract class LockingActivity : StylishActivity() {
@@ -81,12 +74,10 @@ abstract class LockingActivity : StylishActivity() {
} }
if (mTimeoutEnable) { if (mTimeoutEnable) {
mLockReceiver = LockReceiver() mLockReceiver = LockReceiver {
val intentFilter = IntentFilter().apply { lockAndExit()
addAction(Intent.ACTION_SCREEN_OFF)
addAction(LOCK_ACTION)
} }
registerReceiver(mLockReceiver, intentFilter) registerLockReceiver(mLockReceiver)
} }
mExitLock = false mExitLock = false
@@ -151,29 +142,12 @@ abstract class LockingActivity : StylishActivity() {
} }
override fun onDestroy() { override fun onDestroy() {
unregisterLockReceiver(mLockReceiver)
super.onDestroy() 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() { protected fun lockAndExit() {
sendBroadcast(Intent(LOCK_ACTION))
lock() lock()
} }
@@ -208,20 +182,8 @@ abstract class LockingActivity : StylishActivity() {
} }
fun Activity.lock() { fun Activity.lock() {
// Stop the Magikeyboard service closeDatabase()
stopService(Intent(this, KeyboardEntryNotificationService::class.java))
MagikIME.removeEntry(this)
// Stop the notification service
stopService(Intent(this, ClipboardEntryNotificationService::class.java))
Log.i(Activity::class.java.name, "Shutdown " + localClassName +
" after inactivity or manual lock")
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).apply {
cancelAll()
}
// Clear data
Database.getInstance().closeAndClear(applicationContext.filesDir)
// Add onActivityForResult response // Add onActivityForResult response
setResult(LockingActivity.RESULT_EXIT_LOCK) setResult(LockingActivity.RESULT_EXIT_LOCK)
finish() finish()

View File

@@ -84,24 +84,25 @@ class FileDatabaseHistoryAdapter(private val context: Context)
// File path // File path
holder.filePath.text = UriUtil.decode(fileDatabaseInfo.fileUri?.toString()) holder.filePath.text = UriUtil.decode(fileDatabaseInfo.fileUri?.toString())
if (fileDatabaseInfo.dataAccessible()) { if (fileDatabaseInfo.exists) {
holder.fileInformation.clearColorFilter() holder.fileInformation.clearColorFilter()
} else { } else {
holder.fileInformation.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY) holder.fileInformation.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)
} }
// Modification // Modification
if (fileDatabaseInfo.lastModificationAccessible()) { fileDatabaseInfo.getModificationString()?.let {
holder.fileModification.text = fileDatabaseInfo.getModificationString() holder.fileModification.text = it
holder.fileModification.visibility = View.VISIBLE holder.fileModification.visibility = View.VISIBLE
} else { } ?: run {
holder.fileModification.visibility = View.GONE holder.fileModification.visibility = View.GONE
} }
// Size // Size
if (fileDatabaseInfo.sizeAccessible()) { fileDatabaseInfo.getSizeString()?.let {
holder.fileSize.text = fileDatabaseInfo.getSizeString() holder.fileSize.text = it
holder.fileSize.visibility = View.VISIBLE holder.fileSize.visibility = View.VISIBLE
} else { } ?: run {
holder.fileSize.visibility = View.GONE holder.fileSize.visibility = View.GONE
} }

View File

@@ -38,8 +38,8 @@ class SearchEntryCursorAdapter(private val context: Context,
private val database: Database) private val database: Database)
: androidx.cursoradapter.widget.CursorAdapter(context, null, FLAG_REGISTER_CONTENT_OBSERVER) { : androidx.cursoradapter.widget.CursorAdapter(context, null, FLAG_REGISTER_CONTENT_OBSERVER) {
private val cursorInflater: LayoutInflater = context.getSystemService( private val cursorInflater: LayoutInflater? = context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
private var displayUsername: Boolean = false private var displayUsername: Boolean = false
private val iconColor: Int private val iconColor: Int
@@ -58,7 +58,7 @@ class SearchEntryCursorAdapter(private val context: Context,
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View { 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() val viewHolder = ViewHolder()
viewHolder.imageViewIcon = view.findViewById(R.id.entry_icon) viewHolder.imageViewIcon = view.findViewById(R.id.entry_icon)
viewHolder.textViewTitle = view.findViewById(R.id.entry_text) viewHolder.textViewTitle = view.findViewById(R.id.entry_text)

View File

@@ -112,6 +112,14 @@ class FileDatabaseHistoryAction(applicationContext: Context) {
).execute() ).execute()
} }
fun deleteKeyFileByDatabaseUri(databaseUri: Uri) {
ActionDatabaseAsyncTask(
{
databaseFileHistoryDao.deleteKeyFileByDatabaseUri(databaseUri.toString())
}
).execute()
}
fun deleteAllKeyFiles() { fun deleteAllKeyFiles() {
ActionDatabaseAsyncTask( ActionDatabaseAsyncTask(
{ {

View File

@@ -38,6 +38,9 @@ interface FileDatabaseHistoryDao {
@Delete @Delete
fun delete(fileDatabaseHistory: FileDatabaseHistoryEntity): Int fun delete(fileDatabaseHistory: FileDatabaseHistoryEntity): Int
@Query("UPDATE file_database_history SET keyfile_uri=null WHERE database_uri = :databaseUriString")
fun deleteKeyFileByDatabaseUri(databaseUriString: String)
@Query("UPDATE file_database_history SET keyfile_uri=null") @Query("UPDATE file_database_history SET keyfile_uri=null")
fun deleteAllKeyFiles() fun deleteAllKeyFiles()

View File

@@ -26,15 +26,14 @@ import android.content.Intent
import android.os.Build import android.os.Build
import android.service.autofill.Dataset import android.service.autofill.Dataset
import android.service.autofill.FillResponse import android.service.autofill.FillResponse
import androidx.annotation.RequiresApi
import android.util.Log import android.util.Log
import android.view.autofill.AutofillManager import android.view.autofill.AutofillManager
import android.view.autofill.AutofillValue import android.view.autofill.AutofillValue
import android.widget.RemoteViews import android.widget.RemoteViews
import androidx.annotation.RequiresApi
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.model.EntryInfo import com.kunzisoft.keepass.model.EntryInfo
import java.util.*
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
@@ -56,10 +55,10 @@ object AutofillHelper {
return String.format("%s (%s)", entryInfo.title, entryInfo.username) return String.format("%s (%s)", entryInfo.title, entryInfo.username)
if (entryInfo.title.isNotEmpty()) if (entryInfo.title.isNotEmpty())
return entryInfo.title return entryInfo.title
if (entryInfo.username.isNotEmpty())
return entryInfo.username
if (entryInfo.url.isNotEmpty()) if (entryInfo.url.isNotEmpty())
return entryInfo.url return entryInfo.url
if (entryInfo.username.isNotEmpty())
return entryInfo.username
return "" return ""
} }
@@ -71,12 +70,12 @@ object AutofillHelper {
val builder = Dataset.Builder(views) val builder = Dataset.Builder(views)
builder.setId(entryInfo.id) builder.setId(entryInfo.id)
struct.password.forEach { id -> builder.setValue(id, AutofillValue.forText(entryInfo.password)) } struct.usernameId?.let { usernameId ->
builder.setValue(usernameId, AutofillValue.forText(entryInfo.username))
val ids = ArrayList(struct.username) }
if (entryInfo.username.contains("@") || struct.username.isEmpty()) struct.passwordId?.let { password ->
ids.addAll(struct.email) builder.setValue(password, AutofillValue.forText(entryInfo.password))
ids.forEach { id -> builder.setValue(id, AutofillValue.forText(entryInfo.username)) } }
return try { return try {
builder.build() builder.build()

View File

@@ -31,7 +31,6 @@ import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity
import com.kunzisoft.keepass.activities.GroupActivity import com.kunzisoft.keepass.activities.GroupActivity
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
@@ -42,9 +41,11 @@ class AutofillLauncherActivity : AppCompatActivity() {
val assistStructure = AutofillHelper.retrieveAssistStructure(intent) val assistStructure = AutofillHelper.retrieveAssistStructure(intent)
if (assistStructure != null) { if (assistStructure != null) {
if (Database.getInstance().loaded && TimeoutHelper.checkTime(this)) if (Database.getInstance().loaded && TimeoutHelper.checkTime(this))
GroupActivity.launchForAutofillResult(this, assistStructure, PreferencesUtil.enableReadOnlyDatabase(this)) GroupActivity.launchForAutofillResult(this,
assistStructure)
else { else {
FileDatabaseSelectActivity.launchForAutofillResult(this, assistStructure) FileDatabaseSelectActivity.launchForAutofillResult(this,
assistStructure)
} }
} else { } else {
setResult(Activity.RESULT_CANCELED) setResult(Activity.RESULT_CANCELED)

View File

@@ -35,13 +35,13 @@ class KeeAutofillService : AutofillService() {
val fillContexts = request.fillContexts val fillContexts = request.fillContexts
val latestStructure = fillContexts[fillContexts.size - 1].structure val latestStructure = fillContexts[fillContexts.size - 1].structure
cancellationSignal.setOnCancelListener { Log.e(TAG, "Cancel autofill not implemented in this sample.") } cancellationSignal.setOnCancelListener { Log.w(TAG, "Cancel autofill.") }
val responseBuilder = FillResponse.Builder() val responseBuilder = FillResponse.Builder()
// Check user's settings for authenticating Responses and Datasets. // Check user's settings for authenticating Responses and Datasets.
val parseResult = StructureParser(latestStructure).parse() val parseResult = StructureParser(latestStructure).parse()
parseResult?.allAutofillIds()?.let { autofillIds -> parseResult?.allAutofillIds()?.let { autofillIds ->
if (listOf(*autofillIds).isNotEmpty()) { if (autofillIds.isNotEmpty()) {
// If the entire Autofill Response is authenticated, AuthActivity is used // If the entire Autofill Response is authenticated, AuthActivity is used
// to generate Response. // to generate Response.
val sender = AutofillLauncherActivity.getAuthIntentSenderForResponse(this) val sender = AutofillLauncherActivity.getAuthIntentSenderForResponse(this)

View File

@@ -21,7 +21,6 @@ package com.kunzisoft.keepass.autofill
import android.app.assist.AssistStructure import android.app.assist.AssistStructure
import android.os.Build import android.os.Build
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import android.text.InputType
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.view.autofill.AutofillId import android.view.autofill.AutofillId
@@ -40,69 +39,130 @@ internal class StructureParser(private val structure: AssistStructure) {
result = Result() result = Result()
result?.apply { result?.apply {
usernameCandidate = null usernameCandidate = null
for (i in 0 until structure.windowNodeCount) { mainLoop@ for (i in 0 until structure.windowNodeCount) {
val windowNode = structure.getWindowNodeAt(i) val windowNode = structure.getWindowNodeAt(i)
/*
title.add(windowNode.title) title.add(windowNode.title)
windowNode.rootViewNode.webDomain?.let { windowNode.rootViewNode.webDomain?.let {
webDomain.add(it) webDomain.add(it)
} }
parseViewNode(windowNode.rootViewNode) */
if (parseViewNode(windowNode.rootViewNode))
break@mainLoop
} }
// If not explicit username field found, add the field just before password field. // If not explicit username field found, add the field just before password field.
if (username.isEmpty() && email.isEmpty() if (usernameId == null && passwordId != null && usernameCandidate != null)
&& password.isNotEmpty() && usernameCandidate != null) usernameId = usernameCandidate
username.add(usernameCandidate!!)
} }
return result // Return the result only if password field is retrieved
return if (result?.passwordId != null)
result
else
null
} }
private fun parseViewNode(node: AssistStructure.ViewNode) { private fun parseViewNode(node: AssistStructure.ViewNode): Boolean {
val hints = node.autofillHints if (node.autofillId != null) {
val autofillId = node.autofillId val hints = node.autofillHints
if (autofillId != null) {
if (hints != null && hints.isNotEmpty()) { if (hints != null && hints.isNotEmpty()) {
when { if (parseNodeByAutofillHint(node))
Arrays.stream(hints).anyMatch { View.AUTOFILL_HINT_USERNAME == it } -> result?.username?.add(autofillId) return true
Arrays.stream(hints).anyMatch { View.AUTOFILL_HINT_EMAIL_ADDRESS == it } -> result?.email?.add(autofillId) } else {
Arrays.stream(hints).anyMatch { View.AUTOFILL_HINT_PASSWORD == it } -> result?.password?.add(autofillId) if (parseNodeByHtmlAttributes(node))
else -> Log.d(TAG, "unsupported hints") return true
}
}
// Recursive method to process each node
for (i in 0 until node.childCount) {
if (parseViewNode(node.getChildAt(i)))
return true
}
return false
}
private fun parseNodeByAutofillHint(node: AssistStructure.ViewNode): Boolean {
val autofillId = node.autofillId
node.autofillHints?.forEach {
when {
it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_USERNAME
|| it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_EMAIL_ADDRESS
|| it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_PHONE -> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username hint")
} }
} else if (node.autofillType == View.AUTOFILL_TYPE_TEXT) { it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_PASSWORD
val inputType = node.inputType || it.toLowerCase(Locale.ENGLISH).contains("password") -> {
when { result?.passwordId = autofillId
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS > 0 -> result?.email?.add(autofillId) Log.d(TAG, "Autofill password hint")
inputType and InputType.TYPE_TEXT_VARIATION_PASSWORD > 0 -> result?.password?.add(autofillId) return true
result?.password?.isEmpty() == true -> usernameCandidate = autofillId }
// Ignore autocomplete="off"
// https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
it.toLowerCase(Locale.ENGLISH) == "off" ||
it.toLowerCase(Locale.ENGLISH) == "on" -> {
Log.d(TAG, "Autofill web hint")
return parseNodeByHtmlAttributes(node)
}
else -> Log.d(TAG, "Autofill unsupported hint $it")
}
}
return false
}
private fun parseNodeByHtmlAttributes(node: AssistStructure.ViewNode): Boolean {
val autofillId = node.autofillId
val nodHtml = node.htmlInfo
when (nodHtml?.tag?.toLowerCase(Locale.ENGLISH)) {
"input" -> {
nodHtml.attributes?.forEach { pairAttribute ->
when (pairAttribute.first.toLowerCase(Locale.ENGLISH)) {
"type" -> {
when (pairAttribute.second.toLowerCase(Locale.ENGLISH)) {
"tel", "email" -> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
}
"text" -> {
usernameCandidate = autofillId
Log.d(TAG, "Autofill type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
}
"password" -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
return true
}
}
}
}
} }
} }
} }
return false
for (i in 0 until node.childCount)
parseViewNode(node.getChildAt(i))
} }
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
internal class Result { internal class Result {
val title: MutableList<CharSequence> var usernameId: AutofillId? = null
val webDomain: MutableList<String> set(value) {
val username: MutableList<AutofillId> if (field == null)
val email: MutableList<AutofillId> field = value
val password: MutableList<AutofillId> }
init { var passwordId: AutofillId? = null
title = ArrayList() set(value) {
webDomain = ArrayList() if (field == null)
username = ArrayList() field = value
email = ArrayList() }
password = ArrayList()
}
fun allAutofillIds(): Array<AutofillId> { fun allAutofillIds(): Array<AutofillId> {
val all = ArrayList<AutofillId>() val all = ArrayList<AutofillId>()
all.addAll(username) usernameId?.let {
all.addAll(email) all.add(it)
all.addAll(password) }
passwordId?.let {
all.add(it)
}
return all.toTypedArray() return all.toTypedArray()
} }
} }

View File

@@ -95,7 +95,7 @@ class BiometricUnlockDatabaseHelper(private val context: FragmentActivity) {
// really not much to do when no fingerprint support found // really not much to do when no fingerprint support found
isKeyManagerInit = false isKeyManagerInit = false
} else { } else {
this.keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager this.keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager?
try { try {
this.keyStore = KeyStore.getInstance(BIOMETRIC_KEYSTORE) this.keyStore = KeyStore.getInstance(BIOMETRIC_KEYSTORE)

View File

@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.database.action
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import com.kunzisoft.keepass.app.database.CipherDatabaseAction import com.kunzisoft.keepass.app.database.CipherDatabaseAction
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.utils.UriUtil import com.kunzisoft.keepass.utils.UriUtil
@@ -70,6 +71,9 @@ open class AssignPasswordInDatabaseRunnable (
// Erase the biometric // Erase the biometric
CipherDatabaseAction.getInstance(context) CipherDatabaseAction.getInstance(context)
.deleteByDatabaseUri(mDatabaseUri) .deleteByDatabaseUri(mDatabaseUri)
// Erase the register keyfile
FileDatabaseHistoryAction.getInstance(context)
.deleteKeyFileByDatabaseUri(mDatabaseUri)
if (!result.isSuccess) { if (!result.isSuccess) {
// Erase the current master key // Erase the current master key

View File

@@ -86,8 +86,11 @@ class LoadDatabaseRunnable(private val context: Context,
.addOrUpdateCipherDatabase(cipherDatabaseEntity) // return value not called .addOrUpdateCipherDatabase(cipherDatabaseEntity) // return value not called
} }
// Register the current time to init the lock timer
PreferencesUtil.saveCurrentTime(context)
// Start the opening notification // Start the opening notification
DatabaseOpenNotificationService.startIfAllowed(context) DatabaseOpenNotificationService.start(context)
} else { } else {
mDatabase.closeAndClear(cacheDirectory) mDatabase.closeAndClear(cacheDirectory)
} }

View File

@@ -27,6 +27,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
import com.kunzisoft.keepass.crypto.keyDerivation.KdfEngine import com.kunzisoft.keepass.crypto.keyDerivation.KdfEngine
import com.kunzisoft.keepass.database.element.* import com.kunzisoft.keepass.database.element.*
@@ -35,6 +36,7 @@ import com.kunzisoft.keepass.database.element.node.Node
import com.kunzisoft.keepass.database.element.node.NodeId import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.node.Type import com.kunzisoft.keepass.database.element.node.Type
import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm
import com.kunzisoft.keepass.notifications.DatabaseOpenNotificationService
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_ASSIGN_PASSWORD_TASK import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_ASSIGN_PASSWORD_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_COPY_NODES_TASK import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_COPY_NODES_TASK
@@ -85,12 +87,17 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
private val actionTaskListener = object: DatabaseTaskNotificationService.ActionTaskListener { private val actionTaskListener = object: DatabaseTaskNotificationService.ActionTaskListener {
override fun onStartAction(titleId: Int?, messageId: Int?, warningId: Int?) { override fun onStartAction(titleId: Int?, messageId: Int?, warningId: Int?) {
TimeoutHelper.temporarilyDisableTimeout(activity) TimeoutHelper.temporarilyDisableTimeout()
// Stop the opening notification
DatabaseOpenNotificationService.stop(activity)
startOrUpdateDialog(titleId, messageId, warningId) startOrUpdateDialog(titleId, messageId, warningId)
} }
override fun onUpdateAction(titleId: Int?, messageId: Int?, warningId: Int?) { override fun onUpdateAction(titleId: Int?, messageId: Int?, warningId: Int?) {
TimeoutHelper.temporarilyDisableTimeout(activity) TimeoutHelper.temporarilyDisableTimeout()
// Stop the opening notification
DatabaseOpenNotificationService.stop(activity)
startOrUpdateDialog(titleId, messageId, warningId) startOrUpdateDialog(titleId, messageId, warningId)
} }
@@ -98,7 +105,18 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
onActionFinish?.invoke(actionTask, result) onActionFinish?.invoke(actionTask, result)
// Remove the progress task // Remove the progress task
ProgressTaskDialogFragment.stop(activity) ProgressTaskDialogFragment.stop(activity)
TimeoutHelper.releaseTemporarilyDisableTimeoutAndLockIfTimeout(activity) TimeoutHelper.releaseTemporarilyDisableTimeout()
val inTime = if (activity is LockingActivity) {
TimeoutHelper.checkTimeAndLockIfTimeout(activity)
} else {
TimeoutHelper.checkTime(activity)
}
// Start the opening notification if in time
// (databaseOpenService is open manually in Action Open Task)
if (actionTask != ACTION_DATABASE_LOAD_TASK && inTime) {
DatabaseOpenNotificationService.start(activity)
}
} }
} }
@@ -126,7 +144,7 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
if (serviceConnection == null) { if (serviceConnection == null) {
serviceConnection = object : ServiceConnection { serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, serviceBinder: IBinder?) { override fun onServiceConnected(name: ComponentName?, serviceBinder: IBinder?) {
mBinder = (serviceBinder as DatabaseTaskNotificationService.ActionTaskBinder).apply { mBinder = (serviceBinder as DatabaseTaskNotificationService.ActionTaskBinder?)?.apply {
addActionTaskListener(actionTaskListener) addActionTaskListener(actionTaskListener)
getService().checkAction() getService().checkAction()
} }

View File

@@ -142,7 +142,7 @@ class DateInstant : Parcelable {
fun getDateTimeString(resources: Resources, date: Date): String { fun getDateTimeString(resources: Resources, date: Date): String {
return java.text.DateFormat.getDateTimeInstance( return java.text.DateFormat.getDateTimeInstance(
java.text.DateFormat.MEDIUM, java.text.DateFormat.MEDIUM,
java.text.DateFormat.MEDIUM, java.text.DateFormat.SHORT,
ConfigurationCompat.getLocales(resources.configuration)[0]) ConfigurationCompat.getLocales(resources.configuration)[0])
.format(date) .format(date)
} }

View File

@@ -90,6 +90,7 @@ class FieldReferencesEngine {
if (result != null) { if (result != null) {
val found = result.entry val found = result.entry
found?.stopToManageFieldReferences()
val wanted = result.wanted val wanted = result.wanted
var data: String? = null var data: String? = null
@@ -145,22 +146,15 @@ class FieldReferencesEngine {
searchParametersV4.setupNone() searchParametersV4.setupNone()
searchParametersV4.searchString = ref.substring(4) searchParametersV4.searchString = ref.substring(4)
if (scan == 'T') { when (scan) {
searchParametersV4.searchInTitles = true 'T' -> searchParametersV4.searchInTitles = true
} else if (scan == 'U') { 'U' -> searchParametersV4.searchInUserNames = true
searchParametersV4.searchInUserNames = true 'A' -> searchParametersV4.searchInUrls = true
} else if (scan == 'A') { 'P' -> searchParametersV4.searchInPasswords = true
searchParametersV4.searchInUrls = true 'N' -> searchParametersV4.searchInNotes = true
} else if (scan == 'P') { 'I' -> searchParametersV4.searchInUUIDs = true
searchParametersV4.searchInPasswords = true 'O' -> searchParametersV4.searchInOther = true
} else if (scan == 'N') { else -> return null
searchParametersV4.searchInNotes = true
} else if (scan == 'I') {
searchParametersV4.searchInUUIDs = true
} else if (scan == 'O') {
searchParametersV4.searchInOther = true
} else {
return null
} }
val list = ArrayList<EntryKDBX>() val list = ArrayList<EntryKDBX>()

View File

@@ -21,8 +21,7 @@ package com.kunzisoft.keepass.database.element.node
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import java.util.*
import java.util.UUID
class NodeIdUUID : NodeId<UUID> { class NodeIdUUID : NodeId<UUID> {

View File

@@ -94,7 +94,8 @@ open class Education(val activity: Activity) {
R.string.education_copy_username_key, R.string.education_copy_username_key,
R.string.education_entry_edit_key, R.string.education_entry_edit_key,
R.string.education_password_generator_key, R.string.education_password_generator_key,
R.string.education_entry_new_field_key) R.string.education_entry_new_field_key,
R.string.education_setup_OTP_key)
/** /**
@@ -271,6 +272,18 @@ open class Education(val activity: Activity) {
context.resources.getBoolean(R.bool.education_entry_new_field_default)) context.resources.getBoolean(R.bool.education_entry_new_field_default))
} }
/**
* Determines whether the explanatory view to setup OTP has already been displayed.
*
* @param context The context to open the SharedPreferences
* @return boolean value of education_setup_OTP_key key
*/
fun isEducationSetupOTPPerformed(context: Context): Boolean {
val prefs = getEducationSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.education_setup_OTP_key),
context.resources.getBoolean(R.bool.education_setup_OTP_default))
}
/** /**
* Defines if the reset education preference has been reclicked * Defines if the reset education preference has been reclicked
* *

View File

@@ -37,7 +37,7 @@ class EntryEditActivityEducation(activity: Activity)
activity.getString(R.string.education_generate_password_title), activity.getString(R.string.education_generate_password_title),
activity.getString(R.string.education_generate_password_summary)) activity.getString(R.string.education_generate_password_summary))
.textColorInt(Color.WHITE) .textColorInt(Color.WHITE)
.tintTarget(false) .tintTarget(true)
.cancelable(true), .cancelable(true),
object : TapTargetView.Listener() { object : TapTargetView.Listener() {
override fun onTargetClick(view: TapTargetView) { override fun onTargetClick(view: TapTargetView) {
@@ -66,7 +66,7 @@ class EntryEditActivityEducation(activity: Activity)
activity.getString(R.string.education_entry_new_field_title), activity.getString(R.string.education_entry_new_field_title),
activity.getString(R.string.education_entry_new_field_summary)) activity.getString(R.string.education_entry_new_field_summary))
.textColorInt(Color.WHITE) .textColorInt(Color.WHITE)
.tintTarget(false) .tintTarget(true)
.cancelable(true), .cancelable(true),
object : TapTargetView.Listener() { object : TapTargetView.Listener() {
override fun onTargetClick(view: TapTargetView) { override fun onTargetClick(view: TapTargetView) {
@@ -82,4 +82,33 @@ class EntryEditActivityEducation(activity: Activity)
}, },
R.string.education_entry_new_field_key) R.string.education_entry_new_field_key)
} }
/**
* Check and display learning views
* Displays the explanation to setup OTP
*/
fun checkAndPerformedSetUpOTPEducation(educationView: View,
onEducationViewClick: ((TapTargetView?) -> Unit)? = null,
onOuterViewClick: ((TapTargetView?) -> Unit)? = null): Boolean {
return checkAndPerformedEducation(!isEducationSetupOTPPerformed(activity),
TapTarget.forView(educationView,
activity.getString(R.string.education_setup_OTP_title),
activity.getString(R.string.education_setup_OTP_summary))
.textColorInt(Color.WHITE)
.tintTarget(true)
.cancelable(true),
object : TapTargetView.Listener() {
override fun onTargetClick(view: TapTargetView) {
super.onTargetClick(view)
onEducationViewClick?.invoke(view)
}
override fun onOuterCircleClick(view: TapTargetView?) {
super.onOuterCircleClick(view)
view?.dismiss(false)
onOuterViewClick?.invoke(view)
}
},
R.string.education_setup_OTP_key)
}
} }

View File

@@ -24,14 +24,13 @@ import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity
import com.kunzisoft.keepass.activities.GroupActivity import com.kunzisoft.keepass.activities.GroupActivity
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
class KeyboardLauncherActivity : AppCompatActivity() { class KeyboardLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
if (Database.getInstance().loaded && TimeoutHelper.checkTime(this)) if (Database.getInstance().loaded && TimeoutHelper.checkTime(this))
GroupActivity.launchForKeyboardSelection(this, PreferencesUtil.enableReadOnlyDatabase(this)) GroupActivity.launchForKeyboardSelection(this)
else { else {
// Pass extra to get entry // Pass extra to get entry
FileDatabaseSelectActivity.launchForKeyboardSelection(this) FileDatabaseSelectActivity.launchForKeyboardSelection(this)

View File

@@ -17,12 +17,12 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. * along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
@file:Suppress("DEPRECATION")
package com.kunzisoft.keepass.magikeyboard package com.kunzisoft.keepass.magikeyboard
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter
import android.inputmethodservice.InputMethodService import android.inputmethodservice.InputMethodService
import android.inputmethodservice.Keyboard import android.inputmethodservice.Keyboard
import android.inputmethodservice.KeyboardView import android.inputmethodservice.KeyboardView
@@ -42,8 +42,7 @@ import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.model.Field import com.kunzisoft.keepass.model.Field
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.LOCK_ACTION import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.utils.REMOVE_ENTRY_MAGIKEYBOARD_ACTION
class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener { class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
@@ -55,29 +54,18 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
private var fieldsAdapter: FieldsAdapter? = null private var fieldsAdapter: FieldsAdapter? = null
private var playSoundDuringCLick: Boolean = false private var playSoundDuringCLick: Boolean = false
private var lockBroadcastReceiver: BroadcastReceiver? = null private var lockReceiver: LockReceiver? = null
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
// Remove the entry and lock the keyboard when the lock signal is receive // Remove the entry and lock the keyboard when the lock signal is receive
lockBroadcastReceiver = object : BroadcastReceiver() { lockReceiver = LockReceiver {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
REMOVE_ENTRY_MAGIKEYBOARD_ACTION, LOCK_ACTION -> {
removeEntryInfo() removeEntryInfo()
assignKeyboardView() assignKeyboardView()
}
}
}
} }
registerReceiver(lockBroadcastReceiver, registerLockReceiver(lockReceiver, true)
IntentFilter().apply {
addAction(LOCK_ACTION)
addAction(REMOVE_ENTRY_MAGIKEYBOARD_ACTION)
}
)
} }
override fun onCreateInputView(): View { override fun onCreateInputView(): View {
@@ -187,12 +175,12 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
private fun switchToPreviousKeyboard() { private fun switchToPreviousKeyboard() {
var imeManager: InputMethodManager? = null var imeManager: InputMethodManager? = null
try { try {
imeManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imeManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switchToPreviousInputMethod() switchToPreviousInputMethod()
} else { } else {
window.window?.let { window -> window.window?.let { window ->
imeManager.switchToLastInputMethod(window.attributes.token) imeManager?.switchToLastInputMethod(window.attributes.token)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
@@ -214,8 +202,8 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
KEY_BACK_KEYBOARD -> switchToPreviousKeyboard() KEY_BACK_KEYBOARD -> switchToPreviousKeyboard()
KEY_CHANGE_KEYBOARD -> { KEY_CHANGE_KEYBOARD -> {
val imeManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?)
imeManager.showInputMethodPicker() ?.showInputMethodPicker()
} }
KEY_UNLOCK -> { KEY_UNLOCK -> {
} }
@@ -301,7 +289,7 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
override fun onDestroy() { override fun onDestroy() {
dismissCustomKeys() dismissCustomKeys()
unregisterReceiver(lockBroadcastReceiver) unregisterLockReceiver(lockReceiver)
super.onDestroy() super.onDestroy()
} }

View File

@@ -26,8 +26,9 @@ import android.os.Build
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.GroupActivity import com.kunzisoft.keepass.activities.GroupActivity
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.LOCK_ACTION import com.kunzisoft.keepass.utils.LOCK_ACTION
import com.kunzisoft.keepass.utils.closeDatabase
class DatabaseOpenNotificationService: LockNotificationService() { class DatabaseOpenNotificationService: LockNotificationService() {
@@ -36,8 +37,14 @@ class DatabaseOpenNotificationService: LockNotificationService() {
private fun stopNotificationAndSendLock() { private fun stopNotificationAndSendLock() {
// Send lock action // Send lock action
sendBroadcast(Intent(LOCK_ACTION)) sendBroadcast(Intent(LOCK_ACTION))
// Stop the service }
stopSelf()
override fun actionOnLock() {
closeDatabase()
// Remove the lock timer (no more needed if it exists)
TimeoutHelper.cancelLockTimer(this)
// Service is stopped after receive the broadcast
super.actionOnLock()
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@@ -60,13 +67,16 @@ class DatabaseOpenNotificationService: LockNotificationService() {
val database = Database.getInstance() val database = Database.getInstance()
if (database.loaded) { if (database.loaded) {
notificationManager?.notify(notificationId, buildNewNotification().apply { startForeground(notificationId, buildNewNotification().apply {
setSmallIcon(R.drawable.notification_ic_database_open) setSmallIcon(R.drawable.notification_ic_database_open)
setContentTitle(getString(R.string.database_opened)) setContentTitle(getString(R.string.database_opened))
setContentText(database.name + " (" + database.version + ")") setContentText(database.name + " (" + database.version + ")")
setAutoCancel(false) setAutoCancel(false)
setContentIntent(pendingDatabaseIntent) setContentIntent(pendingDatabaseIntent)
// Unfortunately swipe is disabled in lollipop+
setDeleteIntent(pendingDeleteIntent) setDeleteIntent(pendingDeleteIntent)
addAction(R.drawable.ic_lock_white_24dp, getString(R.string.lock),
pendingDeleteIntent)
}.build()) }.build())
} else { } else {
stopSelf() stopSelf()
@@ -80,9 +90,11 @@ class DatabaseOpenNotificationService: LockNotificationService() {
companion object { companion object {
const val ACTION_CLOSE_DATABASE = "ACTION_CLOSE_DATABASE" const val ACTION_CLOSE_DATABASE = "ACTION_CLOSE_DATABASE"
fun startIfAllowed(context: Context) { fun start(context: Context) {
if (PreferencesUtil.isPersistentNotificationEnable(context)) { // Start the opening notification, keep it active to receive lock
// Start the opening notification if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(Intent(context, DatabaseOpenNotificationService::class.java))
} else {
context.startService(Intent(context, DatabaseOpenNotificationService::class.java)) context.startService(Intent(context, DatabaseOpenNotificationService::class.java))
} }
} }

View File

@@ -19,31 +19,28 @@
*/ */
package com.kunzisoft.keepass.notifications package com.kunzisoft.keepass.notifications
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import com.kunzisoft.keepass.utils.LockReceiver
import com.kunzisoft.keepass.utils.LOCK_ACTION import com.kunzisoft.keepass.utils.registerLockReceiver
import com.kunzisoft.keepass.utils.unregisterLockReceiver
abstract class LockNotificationService : NotificationService() { abstract class LockNotificationService : NotificationService() {
private var lockBroadcastReceiver: BroadcastReceiver? = null private var mLockReceiver: LockReceiver? = null
protected open fun actionOnLock() {
// Stop the service in all cases
stopSelf()
}
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
// Register a lock receiver to stop notification service when lock on keyboard is performed // Register a lock receiver to stop notification service when lock on keyboard is performed
lockBroadcastReceiver = object : BroadcastReceiver() { mLockReceiver = LockReceiver {
override fun onReceive(context: Context?, intent: Intent?) { actionOnLock()
// Stop the service in all cases
stopSelf()
}
} }
registerReceiver(lockBroadcastReceiver, registerLockReceiver(mLockReceiver)
IntentFilter().apply {
addAction(LOCK_ACTION)
}
)
} }
protected fun stopTask(task: Thread?) { protected fun stopTask(task: Thread?) {
@@ -59,7 +56,7 @@ abstract class LockNotificationService : NotificationService() {
override fun onDestroy() { override fun onDestroy() {
unregisterReceiver(lockBroadcastReceiver) unregisterLockReceiver(mLockReceiver)
super.onDestroy() super.onDestroy()
} }

View File

@@ -248,13 +248,19 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
BiometricUnlockDatabaseHelper.deleteEntryKeyInKeystoreForBiometric( BiometricUnlockDatabaseHelper.deleteEntryKeyInKeystoreForBiometric(
activity, activity,
object : BiometricUnlockDatabaseHelper.BiometricUnlockErrorCallback { object : BiometricUnlockDatabaseHelper.BiometricUnlockErrorCallback {
override fun onInvalidKeyException(e: Exception) {} fun showException(e: Exception) {
override fun onBiometricException(e: Exception) {
Toast.makeText(context, Toast.makeText(context,
getString(R.string.biometric_scanning_error, e.localizedMessage), getString(R.string.biometric_scanning_error, e.localizedMessage),
Toast.LENGTH_SHORT).show() Toast.LENGTH_SHORT).show()
} }
override fun onInvalidKeyException(e: Exception) {
showException(e)
}
override fun onBiometricException(e: Exception) {
showException(e)
}
}) })
} }
CipherDatabaseAction.getInstance(context.applicationContext).deleteAll() CipherDatabaseAction.getInstance(context.applicationContext).deleteAll()

View File

@@ -31,15 +31,13 @@ object PreferencesUtil {
var APPEARANCE_CHANGED = false var APPEARANCE_CHANGED = false
private const val KEY_DEFAULT_DATABASE_PATH = "KEY_DEFAULT_DATABASE_PATH"
fun saveDefaultDatabasePath(context: Context, defaultDatabaseUri: Uri?) { fun saveDefaultDatabasePath(context: Context, defaultDatabaseUri: Uri?) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs?.edit()?.apply { prefs?.edit()?.apply {
defaultDatabaseUri?.let { defaultDatabaseUri?.let {
putString(KEY_DEFAULT_DATABASE_PATH, it.toString()) putString(context.getString(R.string.default_database_path_key), it.toString())
} ?: kotlin.run { } ?: kotlin.run {
remove(KEY_DEFAULT_DATABASE_PATH) remove(context.getString(R.string.default_database_path_key))
} }
apply() apply()
} }
@@ -47,7 +45,7 @@ object PreferencesUtil {
fun getDefaultDatabasePath(context: Context): String? { fun getDefaultDatabasePath(context: Context): String? {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getString(KEY_DEFAULT_DATABASE_PATH, "") return prefs.getString(context.getString(R.string.default_database_path_key), "")
} }
fun saveNodeSort(context: Context, fun saveNodeSort(context: Context,
@@ -207,12 +205,6 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.enable_auto_save_database_default)) context.resources.getBoolean(R.bool.enable_auto_save_database_default))
} }
fun isPersistentNotificationEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.persistent_notification_key),
context.resources.getBoolean(R.bool.persistent_notification_default))
}
fun isBiometricUnlockEnable(context: Context): Boolean { fun isBiometricUnlockEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.biometric_unlock_enable_key), return prefs.getBoolean(context.getString(R.string.biometric_unlock_enable_key),

View File

@@ -46,53 +46,63 @@ object TimeoutHelper {
private set private set
private fun getLockPendingIntent(context: Context): PendingIntent { private fun getLockPendingIntent(context: Context): PendingIntent {
return PendingIntent.getBroadcast(context, return PendingIntent.getBroadcast(context.applicationContext,
REQUEST_ID, REQUEST_ID,
Intent(LOCK_ACTION), Intent(LOCK_ACTION),
PendingIntent.FLAG_CANCEL_CURRENT) PendingIntent.FLAG_CANCEL_CURRENT)
} }
/** /**
* Record the current time to check it later with checkTime * Start the lock timer by creating an alarm,
* if the method is recalled with a previous lock timer pending, the previous one is deleted
*/ */
fun recordTime(context: Context) { private fun startLockTimer(context: Context) {
// Record timeout time in case timeout service is killed
PreferencesUtil.saveCurrentTime(context)
if (Database.getInstance().loaded) { if (Database.getInstance().loaded) {
val timeout = PreferencesUtil.getAppTimeout(context) val timeout = PreferencesUtil.getAppTimeout(context)
// No timeout don't start timeout service
if (timeout != NEVER) { if (timeout != NEVER) {
val triggerTime = System.currentTimeMillis() + timeout // No timeout don't start timeout service
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager (context.applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager?)?.let { alarmManager ->
Log.d(TAG, "TimeoutHelper start") val triggerTime = System.currentTimeMillis() + timeout
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Log.d(TAG, "TimeoutHelper start")
am.setExact(AlarmManager.RTC, triggerTime, getLockPendingIntent(context)) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
} else { alarmManager.setExact(AlarmManager.RTC, triggerTime, getLockPendingIntent(context))
am.set(AlarmManager.RTC, triggerTime, getLockPendingIntent(context)) } else {
alarmManager.set(AlarmManager.RTC, triggerTime, getLockPendingIntent(context))
}
} }
} }
} }
} }
/**
* Cancel the lock timer currently pending, useful if lock was triggered by another way
*/
fun cancelLockTimer(context: Context) {
(context.applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager?)?.let { alarmManager ->
Log.d(TAG, "TimeoutHelper cancel")
alarmManager.cancel(getLockPendingIntent(context))
}
}
/**
* Record the current time, to check it later with checkTime and start a new lock timer
*/
fun recordTime(context: Context) {
// Record timeout time in case timeout service is killed
PreferencesUtil.saveCurrentTime(context)
startLockTimer(context)
}
/** /**
* Check the time previously record with recordTime and do the [timeoutAction] if timeout * Check the time previously record with recordTime and do the [timeoutAction] if timeout
* if temporarilyDisableTimeout() is called, the function as no effect until releaseTemporarilyDisableTimeoutAndCheckTime() is called * if temporarilyDisableTimeout() is called, the function as no effect until releaseTemporarilyDisableTimeoutAndCheckTime() is called
* return 'false' if timeout, 'true' if in time * return 'false' and send broadcast lock action if timeout, 'true' if in time
*/ */
fun checkTime(context: Context, timeoutAction: (() -> Unit)? = null): Boolean { fun checkTime(context: Context, timeoutAction: (() -> Unit)? = null): Boolean {
// No effect if temporarily disable // No effect if temporarily disable
if (temporarilyDisableTimeout) if (temporarilyDisableTimeout)
return true return true
// Cancel the lock PendingIntent
if (Database.getInstance().loaded) {
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
Log.d(TAG, "TimeoutHelper cancel")
am.cancel(getLockPendingIntent(context))
}
// Check whether the timeout has expired // Check whether the timeout has expired
val currentTime = System.currentTimeMillis() val currentTime = System.currentTimeMillis()
@@ -115,6 +125,7 @@ object TimeoutHelper {
if (diff >= appTimeout) { if (diff >= appTimeout) {
// We have timed out // We have timed out
timeoutAction?.invoke() timeoutAction?.invoke()
context.sendBroadcast(Intent(LOCK_ACTION))
return false return false
} }
return true return true
@@ -142,27 +153,14 @@ object TimeoutHelper {
/** /**
* Temporarily disable timeout, checkTime() function always return true * Temporarily disable timeout, checkTime() function always return true
*/ */
fun temporarilyDisableTimeout(context: Context) { fun temporarilyDisableTimeout() {
temporarilyDisableTimeout = true temporarilyDisableTimeout = true
// Stop the opening notification
DatabaseOpenNotificationService.stop(context)
} }
/** /**
* Release the temporarily disable timeout and directly call checkTime() * Release the temporarily disable timeout
*/ */
fun releaseTemporarilyDisableTimeoutAndLockIfTimeout(context: Context): Boolean { fun releaseTemporarilyDisableTimeout() {
temporarilyDisableTimeout = false temporarilyDisableTimeout = false
val inTime = if (context is LockingActivity) {
checkTimeAndLockIfTimeout(context)
} else {
checkTime(context)
}
if (inTime) {
// Start the opening notification
DatabaseOpenNotificationService.startIfAllowed(context)
}
return inTime
} }
} }

View File

@@ -19,10 +19,110 @@
*/ */
package com.kunzisoft.keepass.utils package com.kunzisoft.keepass.utils
import android.app.AlarmManager
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.ALARM_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.util.Log
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
const val DATABASE_START_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_START_TASK_ACTION" const val DATABASE_START_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_START_TASK_ACTION"
const val DATABASE_STOP_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_STOP_TASK_ACTION" const val DATABASE_STOP_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_STOP_TASK_ACTION"
const val LOCK_ACTION = "com.kunzisoft.keepass.LOCK" const val LOCK_ACTION = "com.kunzisoft.keepass.LOCK"
const val REMOVE_ENTRY_MAGIKEYBOARD_ACTION = "com.kunzisoft.keepass.REMOVE_ENTRY_MAGIKEYBOARD" const val REMOVE_ENTRY_MAGIKEYBOARD_ACTION = "com.kunzisoft.keepass.REMOVE_ENTRY_MAGIKEYBOARD"
class LockReceiver(var lockAction: () -> Unit) : BroadcastReceiver() {
var mLockPendingIntent: PendingIntent? = null
override fun onReceive(context: Context, intent: Intent) {
// If allowed, lock and exit
if (!TimeoutHelper.temporarilyDisableTimeout) {
intent.action?.let {
when (it) {
Intent.ACTION_SCREEN_ON -> {
cancelLockPendingIntent(context)
}
Intent.ACTION_SCREEN_OFF -> {
if (PreferencesUtil.isLockDatabaseWhenScreenShutOffEnable(context)) {
mLockPendingIntent = PendingIntent.getBroadcast(context,
4575,
Intent(intent).apply {
action = LOCK_ACTION
},
0)
// Launch the effective action after a small time
val first: Long = System.currentTimeMillis() + context.getString(R.string.timeout_screen_off).toLong()
val alarmManager = context.getSystemService(ALARM_SERVICE) as AlarmManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager?.setExact(AlarmManager.RTC_WAKEUP, first, mLockPendingIntent)
} else {
alarmManager?.set(AlarmManager.RTC_WAKEUP, first, mLockPendingIntent)
}
} else {
cancelLockPendingIntent(context)
}
}
LOCK_ACTION,
REMOVE_ENTRY_MAGIKEYBOARD_ACTION -> lockAction.invoke()
else -> {}
}
}
}
}
private fun cancelLockPendingIntent(context: Context) {
mLockPendingIntent?.let {
val alarmManager = context.getSystemService(ALARM_SERVICE) as AlarmManager?
alarmManager?.cancel(mLockPendingIntent)
mLockPendingIntent = null
}
}
}
fun Context.registerLockReceiver(lockReceiver: LockReceiver?,
registerRemoveEntryMagikeyboard: Boolean = false) {
lockReceiver?.let {
registerReceiver(it, IntentFilter().apply {
addAction(Intent.ACTION_SCREEN_OFF)
addAction(Intent.ACTION_SCREEN_ON)
addAction(LOCK_ACTION)
if (registerRemoveEntryMagikeyboard)
addAction(REMOVE_ENTRY_MAGIKEYBOARD_ACTION)
})
}
}
fun Context.unregisterLockReceiver(lockReceiver: LockReceiver?) {
lockReceiver?.let {
unregisterReceiver(it)
}
}
fun Context.closeDatabase() {
// Stop the Magikeyboard service
stopService(Intent(this, KeyboardEntryNotificationService::class.java))
MagikIME.removeEntry(this)
// Stop the notification service
stopService(Intent(this, ClipboardEntryNotificationService::class.java))
Log.i(Context::class.java.name, "Shutdown after inactivity or manual lock")
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?)?.apply {
cancelAll()
}
// Clear data
Database.getInstance().closeAndClear(applicationContext.filesDir)
}

View File

@@ -21,25 +21,77 @@ package com.kunzisoft.keepass.utils
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.text.format.Formatter
import androidx.documentfile.provider.DocumentFile
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import java.io.Serializable
import java.text.DateFormat
import java.util.*
class FileDatabaseInfo : FileInfo { class FileDatabaseInfo : Serializable {
constructor(context: Context, fileUri: Uri): super(context, fileUri) private var context: Context
private var documentFile: DocumentFile? = null
var fileUri: Uri?
private set
constructor(context: Context, filePath: String): super(context, filePath) constructor(context: Context, fileUri: Uri) {
this.context = context
this.fileUri = fileUri
init()
}
constructor(context: Context, filePath: String) {
this.context = context
this.fileUri = UriUtil.parse(filePath)
init()
}
fun init() {
documentFile = UriUtil.getFileData(context, fileUri)
}
var exists: Boolean = false
get() {
return documentFile?.exists() ?: field
}
private set
var canRead: Boolean = false
get() {
return documentFile?.canRead() ?: field
}
private set
var canWrite: Boolean = false
get() {
return documentFile?.canWrite() ?: field
}
private set
fun getModificationString(): String? {
return documentFile?.lastModified()?.let {
DateFormat.getDateTimeInstance()
.format(Date(it))
}
}
fun getSizeString(): String? {
return documentFile?.let {
Formatter.formatFileSize(context, it.length())
}
}
fun retrieveDatabaseAlias(alias: String): String { fun retrieveDatabaseAlias(alias: String): String {
return when { return when {
alias.isNotEmpty() -> alias alias.isNotEmpty() -> alias
PreferencesUtil.isFullFilePathEnable(context) -> filePath ?: "" PreferencesUtil.isFullFilePathEnable(context) -> fileUri?.path ?: ""
else -> fileName ?: "" else -> if (exists) documentFile?.name ?: "" else fileUri?.path ?: ""
} }
} }
fun retrieveDatabaseTitle(titleCallback: (String)->Unit) { fun retrieveDatabaseTitle(titleCallback: (String)->Unit) {
fileUri?.let { fileUri -> fileUri?.let { fileUri ->
FileDatabaseHistoryAction.getInstance(context.applicationContext) FileDatabaseHistoryAction.getInstance(context.applicationContext)
.getFileDatabaseHistory(fileUri) { fileDatabaseHistoryEntity -> .getFileDatabaseHistory(fileUri) { fileDatabaseHistoryEntity ->
@@ -48,5 +100,4 @@ class FileDatabaseInfo : FileInfo {
} }
} }
} }
} }

View File

@@ -1,84 +0,0 @@
/*
* 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.utils
import android.content.Context
import android.net.Uri
import android.text.format.Formatter
import java.io.Serializable
import java.text.DateFormat
import java.util.*
open class FileInfo : Serializable {
var context: Context
var fileUri: Uri?
var filePath: String? = null
var fileName: String? = ""
var lastModification = Date(0L)
var size: Long = 0L
constructor(context: Context, fileUri: Uri) {
this.context = context
this.fileUri = fileUri
init()
}
constructor(context: Context, filePath: String) {
this.context = context
this.fileUri = UriUtil.parse(filePath)
init()
}
fun init() {
this.filePath = fileUri?.path
UriUtil.getFileData(context, fileUri)?.let { file ->
size = file.length()
fileName = file.name
lastModification = Date(file.lastModified())
}
if (fileName == null || fileName!!.isEmpty()) {
fileName = filePath
}
}
fun lastModificationAccessible(): Boolean {
return lastModification.after(Date(0L))
}
fun sizeAccessible(): Boolean {
return size != 0L
}
fun dataAccessible(): Boolean {
return UriUtil.isUriAccessible(context.contentResolver, fileUri)
}
fun getModificationString(): String {
return DateFormat.getDateTimeInstance()
.format(lastModification)
}
fun getSizeString(): String {
return Formatter.formatFileSize(context, size)
}
}

View File

@@ -19,8 +19,7 @@
*/ */
package com.kunzisoft.keepass.utils package com.kunzisoft.keepass.utils
import java.util.ArrayList import java.util.*
import java.util.Locale
object StringUtil { object StringUtil {
@@ -85,5 +84,17 @@ object StringUtil {
return currentText return currentText
} }
}
fun UUID.toKeePassRefString(): String {
val tempString = toString().replace("-", "").toUpperCase(Locale.ENGLISH)
return StringBuffer(reverseString2(tempString.substring(12, 16)))
.append(reverseString2(tempString.substring(8, 12)))
.append(reverseString2(tempString.substring(0, 8)))
.append(reverseString2(tempString.substring(20, 32)))
.append(reverseString2(tempString.substring(16, 20))).toString()
}
private fun reverseString2(string: String): String {
return string.chunked(2).reversed().joinToString("")
} }

View File

@@ -24,7 +24,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
@@ -37,26 +36,6 @@ import java.util.*
object UriUtil { object UriUtil {
fun isUriAccessible(contentResolver: ContentResolver, fileUri: Uri?): Boolean {
if (fileUri == null)
return false
return try {
//https://developer.android.com/reference/android/content/res/AssetFileDescriptor
contentResolver.openInputStream(fileUri)?.close()
true
} catch (e: Exception) {
Log.e(UriUtil.javaClass.name, "Unable to access uri $fileUri : ${e.message}")
false
}
}
fun isUriWritable(contentResolver: ContentResolver, fileUri: Uri?): Boolean {
if (fileUri == null)
return false
// TODO Uri writeable detection
return true
}
fun getFileData(context: Context, fileUri: Uri?): DocumentFile? { fun getFileData(context: Context, fileUri: Uri?): DocumentFile? {
if (fileUri == null) if (fileUri == null)
return null return null

View File

@@ -69,8 +69,8 @@ class AddNodeButtonView @JvmOverloads constructor(context: Context,
} }
private fun inflate(context: Context) { private fun inflate(context: Context) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater.inflate(R.layout.view_button_add_node, this) inflater?.inflate(R.layout.view_button_add_node, this)
addEntryEnable = true addEntryEnable = true
addGroupEnable = true addGroupEnable = true
@@ -132,7 +132,7 @@ class AddNodeButtonView @JvmOverloads constructor(context: Context,
} }
fun showButton() { fun showButton() {
if (addButtonView?.visibility != VISIBLE) if (isEnable && addButtonView?.visibility != VISIBLE)
addButtonView?.show(onAddButtonVisibilityChangedListener) addButtonView?.show(onAddButtonVisibilityChangedListener)
} }

View File

@@ -44,8 +44,8 @@ class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
init { init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater.inflate(R.layout.view_advanced_unlock, this) inflater?.inflate(R.layout.view_advanced_unlock, this)
unlockContainerView = findViewById(R.id.fingerprint_container) unlockContainerView = findViewById(R.id.fingerprint_container)

View File

@@ -31,6 +31,7 @@ import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.adapters.EntryAttachmentsAdapter import com.kunzisoft.keepass.adapters.EntryAttachmentsAdapter
import com.kunzisoft.keepass.adapters.EntryHistoryAdapter import com.kunzisoft.keepass.adapters.EntryHistoryAdapter
@@ -40,8 +41,8 @@ import com.kunzisoft.keepass.database.element.security.ProtectedString
import com.kunzisoft.keepass.model.EntryAttachment import com.kunzisoft.keepass.model.EntryAttachment
import com.kunzisoft.keepass.otp.OtpElement import com.kunzisoft.keepass.otp.OtpElement
import com.kunzisoft.keepass.otp.OtpType import com.kunzisoft.keepass.otp.OtpType
import com.kunzisoft.keepass.utils.toKeePassRefString
import java.util.* import java.util.*
import androidx.recyclerview.widget.SimpleItemAnimator
class EntryContentsView @JvmOverloads constructor(context: Context, class EntryContentsView @JvmOverloads constructor(context: Context,
@@ -91,6 +92,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
private val historyAdapter = EntryHistoryAdapter(context) private val historyAdapter = EntryHistoryAdapter(context)
private val uuidView: TextView private val uuidView: TextView
private val uuidReferenceView: TextView
val isUserNamePresent: Boolean val isUserNamePresent: Boolean
get() = userNameContainerView.visibility == View.VISIBLE get() = userNameContainerView.visibility == View.VISIBLE
@@ -99,8 +101,8 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
get() = passwordContainerView.visibility == View.VISIBLE get() = passwordContainerView.visibility == View.VISIBLE
init { init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater.inflate(R.layout.view_entry_contents, this) inflater?.inflate(R.layout.view_entry_contents, this)
userNameContainerView = findViewById(R.id.entry_user_name_container) userNameContainerView = findViewById(R.id.entry_user_name_container)
userNameView = findViewById(R.id.entry_user_name) userNameView = findViewById(R.id.entry_user_name)
@@ -146,6 +148,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
} }
uuidView = findViewById(R.id.entry_UUID) uuidView = findViewById(R.id.entry_UUID)
uuidReferenceView = findViewById(R.id.entry_UUID_reference)
val attrColorAccent = intArrayOf(R.attr.colorAccent) val attrColorAccent = intArrayOf(R.attr.colorAccent)
val taColorAccent = context.theme.obtainStyledAttributes(attrColorAccent) val taColorAccent = context.theme.obtainStyledAttributes(attrColorAccent)
@@ -346,6 +349,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
fun assignUUID(uuid: UUID) { fun assignUUID(uuid: UUID) {
uuidView.text = uuid.toString() uuidView.text = uuid.toString()
uuidReferenceView.text = uuid.toKeePassRefString()
} }
/* ------------- /* -------------

View File

@@ -43,8 +43,8 @@ open class EntryCustomField @JvmOverloads constructor(context: Context,
init { init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater.inflate(R.layout.item_entry_new_field, this) inflater?.inflate(R.layout.item_entry_new_field, this)
labelView = findViewById(R.id.title) labelView = findViewById(R.id.title)
valueView = findViewById(R.id.value) valueView = findViewById(R.id.value)

View File

@@ -21,21 +21,21 @@ package com.kunzisoft.keepass.view
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import com.google.android.material.textfield.TextInputLayout
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.*
import android.widget.ImageView import com.google.android.material.textfield.TextInputLayout
import android.widget.LinearLayout
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.element.security.ProtectedString import com.kunzisoft.keepass.database.element.security.ProtectedString
import com.kunzisoft.keepass.icons.IconDrawableFactory import com.kunzisoft.keepass.icons.IconDrawableFactory
import com.kunzisoft.keepass.icons.assignDatabaseIcon import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.icons.assignDefaultDatabaseIcon import com.kunzisoft.keepass.icons.assignDefaultDatabaseIcon
import com.kunzisoft.keepass.model.Field import com.kunzisoft.keepass.model.Field
import org.joda.time.Duration
import org.joda.time.Instant
class EntryEditContentsView @JvmOverloads constructor(context: Context, class EntryEditContentsView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
@@ -52,16 +52,26 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
private val entryPasswordLayoutView: TextInputLayout private val entryPasswordLayoutView: TextInputLayout
private val entryPasswordView: EditText private val entryPasswordView: EditText
private val entryConfirmationPasswordView: EditText private val entryConfirmationPasswordView: EditText
val generatePasswordView: View private val entryExpiresCheckBox: CompoundButton
private val entryCommentView: EditText private val entryExpiresTextView: TextView
private val entryNotesView: EditText
private val entryExtraFieldsContainer: ViewGroup private val entryExtraFieldsContainer: ViewGroup
val addNewFieldButton: View
private var iconColor: Int = 0 private var iconColor: Int = 0
private var expiresInstant: DateInstant = DateInstant(Instant.now().plus(Duration.standardDays(30)).toDate())
var onDateClickListener: OnClickListener? = null
set(value) {
field = value
if (entryExpiresCheckBox.isChecked)
entryExpiresTextView.setOnClickListener(value)
else
entryExpiresTextView.setOnClickListener(null)
}
init { init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater.inflate(R.layout.view_entry_edit_contents, this) inflater?.inflate(R.layout.view_entry_edit_contents, this)
entryTitleLayoutView = findViewById(R.id.entry_edit_container_title) entryTitleLayoutView = findViewById(R.id.entry_edit_container_title)
entryTitleView = findViewById(R.id.entry_edit_title) entryTitleView = findViewById(R.id.entry_edit_title)
@@ -71,10 +81,14 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
entryPasswordLayoutView = findViewById(R.id.entry_edit_container_password) entryPasswordLayoutView = findViewById(R.id.entry_edit_container_password)
entryPasswordView = findViewById(R.id.entry_edit_password) entryPasswordView = findViewById(R.id.entry_edit_password)
entryConfirmationPasswordView = findViewById(R.id.entry_edit_confirmation_password) entryConfirmationPasswordView = findViewById(R.id.entry_edit_confirmation_password)
generatePasswordView = findViewById(R.id.entry_edit_generate_button) entryExpiresCheckBox = findViewById(R.id.entry_edit_expires_checkbox)
entryCommentView = findViewById(R.id.entry_edit_notes) entryExpiresTextView = findViewById(R.id.entry_edit_expires_text)
entryNotesView = findViewById(R.id.entry_edit_notes)
entryExtraFieldsContainer = findViewById(R.id.entry_edit_advanced_container) entryExtraFieldsContainer = findViewById(R.id.entry_edit_advanced_container)
addNewFieldButton = findViewById(R.id.entry_edit_add_new_field)
entryExpiresCheckBox.setOnCheckedChangeListener { _, _ ->
assignExpiresDateText()
}
// Retrieve the textColor to tint the icon // Retrieve the textColor to tint the icon
val taIconColor = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor)) val taIconColor = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
@@ -141,32 +155,46 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
} }
} }
fun setOnPasswordGeneratorClickListener(clickListener: () -> Unit) { private fun assignExpiresDateText() {
generatePasswordView.setOnClickListener { clickListener.invoke() } entryExpiresTextView.text = if (entryExpiresCheckBox.isChecked) {
entryExpiresTextView.setOnClickListener(onDateClickListener)
expiresInstant.getDateTimeString(resources)
} else {
entryExpiresTextView.setOnClickListener(null)
resources.getString(R.string.never)
}
if (fontInVisibility)
entryExpiresTextView.applyFontVisibility()
} }
var expires: Boolean
get() {
return entryExpiresCheckBox.isChecked
}
set(value) {
entryExpiresCheckBox.isChecked = value
assignExpiresDateText()
}
var expiresDate: DateInstant
get() {
return expiresInstant
}
set(value) {
expiresInstant = value
assignExpiresDateText()
}
var notes: String var notes: String
get() { get() {
return entryCommentView.text.toString() return entryNotesView.text.toString()
} }
set(value) { set(value) {
entryCommentView.setText(value) entryNotesView.setText(value)
if (fontInVisibility) if (fontInVisibility)
entryCommentView.applyFontVisibility() entryNotesView.applyFontVisibility()
} }
fun allowCustomField(allow: Boolean, action: () -> Unit) {
addNewFieldButton.apply {
if (allow) {
visibility = View.VISIBLE
setOnClickListener { action.invoke() }
} else {
visibility = View.GONE
setOnClickListener(null)
}
}
}
val customFields: MutableList<Field> val customFields: MutableList<Field>
get() { get() {
val customFieldsArray = ArrayList<Field>() val customFieldsArray = ArrayList<Field>()
@@ -228,14 +256,6 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
fun isValid(): Boolean { fun isValid(): Boolean {
var isValid = true var isValid = true
// Require title
if (entryTitleView.text.toString().isEmpty()) {
entryTitleLayoutView.error = context.getString(R.string.error_title_required)
isValid = false
} else {
entryTitleLayoutView.error = null
}
// Validate password // Validate password
if (entryPasswordView.text.toString() != entryConfirmationPasswordView.text.toString()) { if (entryPasswordView.text.toString() != entryConfirmationPasswordView.text.toString()) {
entryPasswordLayoutView.error = context.getString(R.string.error_pass_match) entryPasswordLayoutView.error = context.getString(R.string.error_pass_match)

View File

@@ -54,8 +54,8 @@ class EntryEditCustomField @JvmOverloads constructor(context: Context,
init { init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater.inflate(R.layout.view_entry_new_field, this) inflater?.inflate(R.layout.view_entry_new_field, this)
val deleteView = findViewById<View>(R.id.entry_new_field_delete) val deleteView = findViewById<View>(R.id.entry_new_field_delete)
deleteView.setOnClickListener { deleteViewFromParent() } deleteView.setOnClickListener { deleteViewFromParent() }

View File

@@ -17,6 +17,8 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. * along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
@file:Suppress("DEPRECATION")
package com.kunzisoft.keepass.view package com.kunzisoft.keepass.view
import android.content.Context import android.content.Context

View File

@@ -33,6 +33,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import java.util.*
/** /**
* Replace font by monospace, must be called after seText() * Replace font by monospace, must be called after seText()

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/white"
tools:targetApi="lollipop">
<item>
<shape>
<stroke android:color="?attr/colorAccent" android:width="1dp"/>
<solid android:color="@color/transparent"/>
</shape>
</item>
</ripple>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<stroke android:color="@color/grey" android:width="1dp"/>
<solid android:color="@color/transparent"/>
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M16.5,6v11.5c0,2.21 -1.79,4 -4,4s-4,-1.79 -4,-4V5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5v10.5c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V6H10v9.5c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5V5c0,-2.21 -1.79,-4 -4,-4S7,2.79 7,5v12.5c0,3.04 2.46,5.5 5.5,5.5s5.5,-2.46 5.5,-5.5V6h-1.5z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M11,17c0,0.55 0.45,1 1,1s1,-0.45 1,-1 -0.45,-1 -1,-1 -1,0.45 -1,1zM11,3v4h2L13,5.08c3.39,0.49 6,3.39 6,6.92 0,3.87 -3.13,7 -7,7s-7,-3.13 -7,-7c0,-1.68 0.59,-3.22 1.58,-4.42L12,13l1.41,-1.41 -6.8,-6.8v0.02C4.42,6.45 3,9.05 3,12c0,4.97 4.02,9 9,9 4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9h-1zM18,12c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1 0.45,1 1,1 1,-0.45 1,-1zM6,12c0,0.55 0.45,1 1,1s1,-0.45 1,-1 -0.45,-1 -1,-1 -1,0.45 -1,1z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M9.77344,3.13281 C9.4515,3.1329,9.12601,3.22745,8.83789,3.42188 L1.73828,8.21289
C1.25807,8.53693,1.00007,9.06311,1,9.59961
C0.999958,9.92151,1.09268,10.247,1.28711,10.5352 L6.07813,17.6328
C6.5966,18.4011,7.63207,18.6025,8.40039,18.084 L8.59375,17.9531
C7.93444,17.5713,7.49368,16.9397,7.33398,16.2305
C7.25701,16.1464,7.21481,16.0308,7.23828,15.9102 L7.27148,15.7422
C7.271,15.7299,7.26758,15.7194,7.26758,15.707 L7.09961,15.8184
C6.92859,15.9337,6.69736,15.8897,6.58203,15.7188
C6.46665,15.5479,6.51062,15.3165,6.68164,15.2012 L6.86523,15.0801
L6.65039,15.0371 C6.44804,14.9977,6.31618,14.8059,6.35547,14.6035
C6.39476,14.4011,6.58863,14.2693,6.79102,14.3086 L7.00586,14.3516
L6.88477,14.1699 C6.76939,13.9991,6.81335,13.7677,6.98438,13.6523
C7.1554,13.537,7.38468,13.581,7.5,13.752 L7.62305,13.9316 L7.66406,13.7188
C7.69855,13.5416,7.8519,13.4274,8.02539,13.4258 L11.1816,6.77344
C11.4309,6.24809,11.8397,5.84958,12.3203,5.58984 L11.1602,3.87109
C10.8361,3.3909,10.3119,3.13267,9.77539,3.13281 L9.77344,3.13281 Z
M9.70703,5.15625 C9.90938,5.19561,10.0373,5.39136,9.99805,5.59375
L9.95898,5.80859 L10.1387,5.68555
C10.3097,5.57024,10.5409,5.61618,10.6563,5.78711
C10.7716,5.95797,10.7257,6.18741,10.5547,6.30273 L10.375,6.42578
L10.5879,6.46484 C10.7902,6.5042,10.922,6.70197,10.8828,6.9043
C10.8435,7.1067,10.6496,7.23855,10.4473,7.19922 L10.2344,7.15625
L10.3535,7.33594 C10.4689,7.5068,10.4249,7.73817,10.2539,7.85352
C10.0829,7.9688,9.85163,7.92289,9.73633,7.75195 L9.61523,7.57031
L9.57227,7.78516 C9.53298,7.98758,9.34104,8.11943,9.13867,8.08008
C8.93633,8.04072,8.80451,7.84684,8.84375,7.64453 L8.88477,7.43164
L8.70313,7.55273 C8.53228,7.66806,8.30282,7.62406,8.1875,7.45313
C8.07212,7.28226,8.11609,7.05088,8.28711,6.93555 L8.46875,6.8125
L8.25391,6.76953 C8.05154,6.73017,7.91971,6.53833,7.95898,6.33594
C7.99827,6.13352,8.19412,6.00167,8.39648,6.04102 L8.61133,6.08398
L8.48828,5.90234 C8.3729,5.73148,8.41882,5.50205,8.58984,5.38672
C8.76069,5.27139,8.99014,5.31344,9.10547,5.48438 L9.22656,5.66602
L9.26758,5.45313 C9.30687,5.25073,9.50467,5.11692,9.70703,5.15625 Z
M13.6602,6.24414 C13.0088,6.21529,12.3742,6.57309,12.0762,7.20117
L8.40625,14.9375 C8.00883,15.7749,8.36373,16.7686,9.20117,17.166
L16.9375,20.8379 C17.7749,21.2353,18.7686,20.8804,19.166,20.043 L22.8379,12.3066
C23.2353,11.4693,22.8804,10.4736,22.043,10.0762 L14.3066,6.40625
C14.0973,6.30689,13.8773,6.25374,13.6602,6.24414 Z M4.62109,8.49023
C4.66856,8.4801,4.71886,8.48028,4.76953,8.49023
C4.97188,8.52959,5.10374,8.72142,5.06445,8.92383 L5.02148,9.13867
L5.20313,9.01758 C5.37397,8.90227,5.60343,8.94625,5.71875,9.11719
C5.83413,9.28805,5.78999,9.51944,5.61914,9.63477 L5.43945,9.75586
L5.65039,9.79492 C5.85276,9.83428,5.9865,10.0321,5.94727,10.2344
C5.90798,10.4368,5.71213,10.5686,5.50977,10.5293 L5.29688,10.4883
L5.41797,10.668 C5.53335,10.8388,5.48938,11.0683,5.31836,11.1836
C5.14751,11.2989,4.91806,11.253,4.80273,11.082 L4.67969,10.9023 L4.63672,11.1172
C4.59743,11.3196,4.40355,11.4495,4.20117,11.4102
C3.99883,11.3708,3.867,11.1769,3.90625,10.9746 L3.94922,10.7617 L3.76953,10.8828
C3.59851,10.9981,3.36728,10.9541,3.25195,10.7832
C3.13658,10.6123,3.18054,10.3829,3.35156,10.2676 L3.53516,10.1426
L3.31836,10.1016 C3.11599,10.0622,2.98612,9.86842,3.02539,9.66602
C3.06468,9.46362,3.25857,9.33371,3.46094,9.37305 L3.67578,9.41406
L3.55078,9.23242 C3.4354,9.06156,3.48132,8.83214,3.65234,8.7168
C3.82337,8.60149,4.05462,8.64547,4.16992,8.81641 L4.29102,8.99805
L4.33203,8.7832 C4.36154,8.6314,4.47892,8.52021,4.62109,8.49023 Z
M19.2363,10.7852 C19.3814,10.7935,19.5126,10.8876,19.5645,11.0332
L19.6367,11.2363 L19.7305,11.041
C19.8188,10.8547,20.0403,10.7749,20.2266,10.8633
C20.4128,10.9517,20.4908,11.1712,20.4023,11.3574 L20.3086,11.5586
L20.5156,11.4844 C20.7098,11.4152,20.9211,11.5148,20.9902,11.709
C21.0594,11.9032,20.9597,12.1163,20.7656,12.1855 L20.5586,12.2578
L20.7578,12.3516 C20.944,12.44,21.022,12.6614,20.9336,12.8477
C20.8452,13.0339,20.6238,13.1118,20.4375,13.0234 L20.2402,12.9297
L20.3125,13.1367 C20.3817,13.3309,20.282,13.5421,20.0879,13.6113
C19.8937,13.6805,19.6825,13.5809,19.6133,13.3867 L19.5391,13.1777
L19.4453,13.377 C19.357,13.5632,19.1374,13.6411,18.9512,13.5527 L18.9492,13.5527
C18.763,13.4643,18.6832,13.2429,18.7715,13.0566 L18.8652,12.8613
L18.6621,12.9336 C18.4679,13.0027,18.2547,12.9012,18.1855,12.707
C18.1164,12.5128,18.218,12.3016,18.4121,12.2324 L18.6172,12.1582
L18.4199,12.0664 C18.2337,11.978,18.1557,11.7566,18.2441,11.5703
C18.3325,11.384,18.554,11.3042,18.7402,11.3926 L18.9355,11.4863 L18.8613,11.2832
C18.7922,11.089,18.8938,10.8759,19.0879,10.8066
C19.1364,10.7894,19.188,10.7824,19.2363,10.7852 Z M15.2695,12.1973
C15.4146,12.2056,15.5478,12.2997,15.5996,12.4453 L15.6699,12.6484
L15.7637,12.4531 C15.852,12.2669,16.0735,12.189,16.2598,12.2773
C16.446,12.3657,16.524,12.5872,16.4355,12.7734 L16.3438,12.9707 L16.5488,12.8965
C16.743,12.8273,16.9543,12.9289,17.0234,13.123
C17.0926,13.3172,16.991,13.5304,16.7969,13.5996 L16.5938,13.6699
L16.7891,13.7637 C16.9753,13.8521,17.0552,14.0735,16.9668,14.2598
C16.8784,14.446,16.6569,14.5239,16.4707,14.4355 L16.2734,14.3438
L16.3477,14.5488 C16.4168,14.743,16.3152,14.9542,16.1211,15.0234
C15.9269,15.0926,15.7176,14.993,15.6484,14.7988 L15.5742,14.5918
L15.4785,14.7891 C15.3902,14.9753,15.1687,15.0532,14.9824,14.9648
C14.7962,14.8765,14.7182,14.657,14.8066,14.4707 L14.8984,14.2734
L14.6953,14.3477 C14.5011,14.4168,14.2879,14.3152,14.2188,14.1211
C14.1496,13.9269,14.2493,13.7157,14.4434,13.6465 L14.6504,13.5723
L14.4531,13.4785 C14.2669,13.3901,14.1889,13.1687,14.2773,12.9824
C14.3657,12.7962,14.5872,12.7183,14.7734,12.8066 L14.9688,12.8984
L14.8945,12.6953 C14.8254,12.5011,14.9289,12.288,15.123,12.2188
C15.1716,12.2015,15.2212,12.1945,15.2695,12.1973 Z M11.3008,13.6113
C11.4458,13.6197,11.579,13.7138,11.6309,13.8594 L11.7051,14.0625
L11.7969,13.8672 C11.8852,13.6809,12.1087,13.6011,12.2949,13.6895
C12.4811,13.7778,12.5591,13.9993,12.4707,14.1855 L12.375,14.3848 L12.582,14.3105
C12.7762,14.2414,12.9894,14.341,13.0586,14.5352
C13.1277,14.7294,13.0242,14.9425,12.8301,15.0117 L12.627,15.084 L12.8242,15.1777
C13.0104,15.2661,13.0885,15.4876,13,15.6738
C12.9116,15.8601,12.6902,15.938,12.5039,15.8496 L12.3066,15.7559
L12.3789,15.9629 C12.4481,16.1571,12.3484,16.3683,12.1543,16.4375
C11.9601,16.5067,11.7489,16.4071,11.6797,16.2129 L11.6055,16.0039
L11.5137,16.2031 C11.4253,16.3894,11.2019,16.4693,11.0156,16.3809
L11.0156,16.3789 C10.8294,16.2905,10.7514,16.071,10.8398,15.8848
L10.9336,15.6875 L10.7305,15.7598
C10.5363,15.8289,10.3211,15.7273,10.252,15.5332
C10.1828,15.339,10.2844,15.1278,10.4785,15.0586 L10.6855,14.9863
L10.4863,14.8926 C10.3001,14.8042,10.2221,14.5828,10.3105,14.3965
C10.3989,14.2102,10.6184,14.1304,10.8047,14.2188 L11.0039,14.3125
L10.9297,14.1094 C10.8605,13.9152,10.9622,13.702,11.1563,13.6328
C11.2048,13.6156,11.2524,13.6086,11.3008,13.6113 Z" />
</vector>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<path
android:fillColor="#fffbfb"
android:pathData="M 18 3 L 18 6 L 15 6 L 15 8 L 18 8 L 18 11 L 20 11 L 20 8 L 23 8 L 23 6 L 20 6 L
20 3 L 18 3 z M 4 6 C 2.8920005 6 2.0000002 6.8920005 2 8 L 2 18 C 1.9999998
19.108 2.8920005 20 4 20 L 18 20 C 19.108 20 19.999999 19.108 20 18 L 20 13 L 18
13 L 18 16.533203 C 17.999999 17.345736 17.345736 18 16.533203 18 L 5.4667969 18
C 4.6542635 18 3.9999998 17.345736 4 16.533203 L 4 9.4667969 C 4.0000002
8.6542635 4.6542635 8 5.4667969 8 L 13 8 L 13 6 L 4 6 z M 5 10 L 5 12 L 17 12 L
17 10 L 5 10 z M 5 14 L 5 16 L 17 16 L 17 14 L 5 14 z" />
</group>
</vector>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M9.19922,3.13867 L9.19922,4.73828 L9.19922,6.33984 L10.8008,6.33984
L10.8008,4.79297 C13.6944,5.15457,15.9841,7.44622,16.3457,10.3398
L14.8008,10.3398 L14.8008,11.9395 L16.3438,11.9395
C16.2972,12.3042,16.211,12.6543,16.1074,12.998 L17.7559,12.998
C17.9,12.399,18,11.7819,18,11.1387 C18,6.72041,14.4183,3.13867,10,3.13867
L9.19922,3.13867 Z M4.7207,5.17383 L4.59766,5.25
C4.30768,5.51569,4.03687,5.80202,3.78906,6.10742
C3.74408,6.16236,3.76404,6.13658,3.75391,6.14844
C2.62072,7.56491,2.00133,9.32361,2,11.1387
C2,11.4166,2.02145,11.6889,2.05078,11.959
C2.06909,12.128,2.09815,12.2932,2.12695,12.459
C2.15024,12.5993,2.17255,12.7392,2.20313,12.877
C2.21201,12.9175,2.21732,12.9597,2.22656,13 L2.23633,13
C2.42308,13.7827,2.72966,14.5165,3.12695,15.1914
C3.30082,14.5824,3.66062,14.0532,4.14453,13.666
C4.05066,13.4483,3.95825,13.2294,3.88867,13 L3.89063,13
C3.88529,12.9838,3.88033,12.9674,3.875,12.9512
C3.77847,12.6238,3.7054,12.2864,3.66211,11.9395 L5.19727,11.9395
L5.20703,11.9395 L5.20703,10.3398 L5.19727,10.3398 L3.66406,10.3398
C3.69055,10.1356,3.73432,9.93472,3.7793,9.73438
C3.81343,9.59208,3.85116,9.45203,3.89258,9.3125
C4.09265,8.63652,4.39089,7.99073,4.80859,7.41211 L9.10156,11.7051
C9.41495,12.0185,9.91902,12.0185,10.2324,11.7051
C10.5458,11.3917,10.5458,10.8876,10.2324,10.5742 L5.14258,5.48242
C5.02985,5.36975,4.72451,5.175,4.72266,5.17383 L4.7207,5.17383 Z M6,14
C4.892,14,4,14.892,4,16 L4,19 C4,20.108,4.892,21,6,21 L21,21
C22.108,21,23,20.108,23,19 L23,16 C23,14.892,22.108,14,21,14 L6,14 Z M7.5,15
C7.777,15,8,15.2787,8,15.625 L8,16.293 L8.47266,15.8203
C8.71749,15.5755,9.07172,15.5366,9.26758,15.7324
C9.46352,15.9283,9.42449,16.2825,9.17969,16.5273 L8.70703,17 L9.375,17
C9.72124,17,10,17.223,10,17.5 C10,17.777,9.72124,18,9.375,18 L8.70703,18
L9.17969,18.4727 C9.42449,18.7175,9.46367,19.0717,9.26758,19.2676
C9.07172,19.4634,8.71749,19.4245,8.47266,19.1797 L8,18.707 L8,19.375
C8,19.7212,7.777,20,7.5,20 C7.223,20,7,19.7212,7,19.375 L7,18.707
L6.52734,19.1797 C6.28251,19.4245,5.92828,19.4634,5.73242,19.2676
C5.53649,19.0717,5.57551,18.7175,5.82031,18.4727 L6.29297,18 L5.625,18
C5.27876,18,5,17.777,5,17.5 C5,17.223,5.27876,17,5.625,17 L6.29297,17
L5.82031,16.5273 C5.57551,16.2825,5.53633,15.9283,5.73242,15.7324
C5.92828,15.5366,6.28251,15.5755,6.52734,15.8203 L7,16.293 L7,15.625
C7,15.2787,7.223,15,7.5,15 Z M13.5,15 C13.777,15,14,15.2787,14,15.625 L14,16.293
L14.4727,15.8203 C14.7175,15.5755,15.0717,15.5366,15.2676,15.7324
C15.4635,15.9283,15.4245,16.2825,15.1797,16.5273 L14.707,17 L15.375,17
C15.7212,17,16,17.223,16,17.5 C16,17.777,15.7212,18,15.375,18 L14.707,18
L15.1797,18.4727 C15.4245,18.7175,15.4637,19.0717,15.2676,19.2676
C15.0717,19.4634,14.7175,19.4245,14.4727,19.1797 L14,18.707 L14,19.375
C14,19.7212,13.777,20,13.5,20 C13.223,20,13,19.7212,13,19.375 L13,18.707
L12.5273,19.1797 C12.2825,19.4245,11.9283,19.4634,11.7324,19.2676
C11.5365,19.0717,11.5755,18.7175,11.8203,18.4727 L12.293,18 L11.625,18
C11.2788,18,11,17.777,11,17.5 C11,17.223,11.2788,17,11.625,17 L12.293,17
L11.8203,16.5273 C11.5755,16.2825,11.5363,15.9283,11.7324,15.7324
C11.9283,15.5366,12.2825,15.5755,12.5273,15.8203 L13,16.293 L13,15.625
C13,15.2787,13.223,15,13.5,15 Z M19.5,15 C19.777,15,20,15.2787,20,15.625
L20,16.293 L20.4727,15.8203 C20.7175,15.5755,21.0717,15.5366,21.2676,15.7324
C21.4635,15.9283,21.4245,16.2825,21.1797,16.5273 L20.707,17 L21.375,17
C21.7212,17,22,17.223,22,17.5 C22,17.777,21.7212,18,21.375,18 L20.707,18
L21.1797,18.4727 C21.4245,18.7175,21.4637,19.0717,21.2676,19.2676
C21.0717,19.4634,20.7175,19.4245,20.4727,19.1797 L20,18.707 L20,19.375
C20,19.7212,19.777,20,19.5,20 C19.223,20,19,19.7212,19,19.375 L19,18.707
L18.5273,19.1797 C18.2825,19.4245,17.9283,19.4634,17.7324,19.2676
C17.5365,19.0717,17.5755,18.7175,17.8203,18.4727 L18.293,18 L17.625,18
C17.2788,18,17,17.777,17,17.5 C17,17.223,17.2788,17,17.625,17 L18.293,17
L17.8203,16.5273 C17.5755,16.2825,17.5363,15.9283,17.7324,15.7324
C17.9283,15.5366,18.2825,15.5755,18.5273,15.8203 L19,16.293 L19,15.625
C19,15.2787,19.223,15,19.5,15 Z" />
</vector>

View File

@@ -1,19 +1,27 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp" android:width="24dp"
android:height="24dp"> android:height="24dp"
<group android:viewportWidth="24"
android:translateY="-8"> android:viewportHeight="24">
<group <group>
android:scaleX="1.777778" <path
android:scaleY="1.777778" android:fillColor="#ffffff"
android:translateX="-205.4844" android:pathData="M 12 1 A 11.000003 11.000001 0 0 0 1 12 A 11.000003 11.000001 0 0 0 4 19.529297
android:translateY="-31.99788"> L 4 18 L 4 16.119141 A 9.0000001 9.0000001 0 0 1 3 12 A 9.0000001 9.0000001 0 0
<path 1 4.9746094 6.3886719 L 17.617188 19.03125 A 9.0000001 9.0000001 0 0 1 12 21 A
android:pathData="M125.00684 31.305444l0 -6.644528c0 -0.263013 -0.21159 -0.47461 -0.4746 -0.47461l-6.48633 0c-1.04808 0 -1.89843 0.850344 -1.89843 1.898435l0 6.328127c0 1.048093 0.85035 1.898437 1.89843 1.898437l6.48633 0c0.26301 0 0.4746 -0.2116 0.4746 -0.474611l0 -0.316409c0 -0.148311 -0.0692 -0.282785 -0.176 -0.369792 -0.083 -0.304543 -0.083 -1.172685 0 -1.477229 0.10684 -0.08504 0.176 -0.219501 0.176 -0.36782zm-6.32812 -4.469236c0 -0.06529 0.0534 -0.118652 0.11866 -0.118652l4.19238 0c0.0653 0 0.11866 0.05343 0.11866 0.118652l0 0.39551c0 0.06529 -0.0534 0.118653 -0.11866 0.118653l-4.19238 0c-0.0653 0 -0.11866 -0.05343 -0.11866 -0.118653l0 -0.39551zm0 1.265621c0 -0.06529 0.0534 -0.118653 0.11866 -0.118653l4.19238 0c0.0653 0 0.11866 0.05343 0.11866 0.118653l0 0.395509c0 0.06529 -0.0534 0.118653 -0.11866 0.118653l-4.19238 0c-0.0653 0 -0.11866 -0.05342 -0.11866 -0.118653l0 -0.395509zm5.0111 4.943847l-5.64391 0c-0.35003 0 -0.63282 -0.282781 -0.63282 -0.632808 0 -0.348045 0.28476 -0.632813 0.63282 -0.632813l5.64391 0c-0.0375 0.338162 -0.0375 0.927466 0 1.265621z" 9.0000001 9.0000001 0 0 1 7.9121094 20 L 6 20 L 4.4609375 20 A 11.000003
android:fillColor="#ffffff" /> 11.000001 0 0 0 12 23 A 11.000003 11.000001 0 0 0 23 12 A 11.000003 11.000001 0
</group> 0 0 12 1 z M 12 3 A 9.0000001 9.0000001 0 0 1 21 12 A 9.0000001 9.0000001 0 0 1
19.025391 17.611328 L 6.3828125 4.96875 A 9.0000001 9.0000001 0 0 1 12 3 z M
16.566406 5.0078125 C 16.256202 5.0423192 15.932855 5.1941212 15.669922
5.4570312 L 14.46875 6.6601562 L 17.339844 9.53125 L 18.542969 8.3300781 C
18.895877 7.9770126 19.030492 7.5200648 18.966797 7.1269531 C 18.396436
6.3122027 17.687797 5.6035638 16.873047 5.0332031 C 16.772829 5.0168634
16.672741 4.995984 16.566406 5.0078125 z M 13.449219 7.6777344 L 11.978516
9.1503906 L 14.849609 12.021484 L 16.320312 10.548828 L 13.449219 7.6777344 z M
9.1484375 11.980469 L 5.65625 15.472656 L 5.015625 18.390625 C 4.9299361
18.781059 5.2170219 19.069875 5.6074219 18.984375 L 8.5253906 18.345703 L
12.019531 14.851562 L 9.1484375 11.980469 z" />
</group> </group>
</vector> </vector>

View File

@@ -1,25 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp" android:width="24dp"
android:height="24dp"> android:height="24dp"
<group android:viewportWidth="24"
android:translateY="-8"> android:viewportHeight="24">
<group <group>
android:scaleX="1.777778" <path
android:scaleY="1.777778" android:fillColor="#ffffff"
android:translateX="-205.4844" android:strokeWidth="1.01553178"
android:translateY="-31.99788"> android:pathData="M 16.566406,5.0078125 C 15.782726,5.1133592 15.352352,5.8416456
<group 14.802734,6.3261719 14.631179,6.503043 14.326338,6.6788074 14.664062,6.8554688 L
android:scaleX="0.5625" 17.339844,9.53125 C 17.821017,9.0226367 18.368011,8.5699819 18.791016,8.0117188
android:scaleY="0.5625" 19.125433,7.5187285 19.054409,6.8047721 18.564453,6.4453125 18.109555,6.0127792
android:translateX="115.585" 17.694742,5.5314578 17.210938,5.1328125 17.01828,5.0182169 16.787242,4.9827103
android:translateY="22.49881"> 16.566406,5.0078125 Z M 13.449219,7.6777344 C 10.851548,10.276042
<path 8.2539034,12.874349 5.65625,15.472656 5.4423833,16.493124 5.1885689,17.506656
android:pathData="M4.375 3C2.5117466 3 1 4.5117271 1 6.375l0 11.25C1 19.488276 2.5117466 21 4.375 21l11.53125 0C16.373823 21 16.75 20.623825 16.75 20.15625l0 -0.5625c0 -0.263664 -0.122669 -0.503524 -0.3125 -0.658203 -0.147556 -0.54141 -0.147556 -2.08359 0 -2.625 0.189938 -0.151182 0.3125 -0.390619 0.3125 -0.654297l0 -0.669922 -2.378906 2.378906c-0.0089 0.500068 -0.0036 1.014773 0.03711 1.384766l-1.525391 0 -3.0507808 0.667969C9.333649 19.527124 8.7483479 19.391267 8.3632812 19.005859 8.2870146 18.929486 8.2287106 18.840044 8.171875 18.75L4.375 18.75C3.7527244 18.75 3.25 18.24727 3.25 17.625 3.25 17.006253 3.7562267 16.5 4.375 16.5l3.8027344 0L8.6503906 14.349609 12.125 10.875l-6.4140625 0C5.5948486 10.875 5.5 10.780031 5.5 10.664062l0 -0.7031245C5.5 9.8448664 5.5949375 9.75 5.7109375 9.75l7.4531245 0c0.02365 0 0.03921 0.018137 0.06055 0.025391L16.550781 6.4492188 16.75 6.25l0 -2.40625C16.75 3.3761713 16.373823 3 15.90625 3L4.375 3Zm16.015625 1.5898438c-0.30546 0.033979 -0.623906 0.1844704 -0.882813 0.4433593l-1.183593 1.1835938 2.828125 2.828125 1.183594 -1.1835938c0.517848 -0.5180889 0.601704 -1.2752558 0.1875 -1.6894531L21.195312 4.8457031C20.988219 4.6386018 20.696085 4.5558644 20.390625 4.5898438ZM17.320312 7.21875L9.6464844 14.894531 9.015625 17.767578c-0.08448 0.384462 0.1995577 0.670133 0.5839844 0.585938L12.472656 17.724609 20.148438 10.046875 17.320312 7.21875ZM5.7109375 7.5L13.164062 7.5C13.280151 7.5 13.375 7.594987 13.375 7.7109375l0 0.703125C13.375 8.5301336 13.28008 8.625 13.164062 8.625l-7.4531245 0C5.5948486 8.625 5.5 8.5300127 5.5 8.4140625l0 -0.703125C5.5 7.5948664 5.5949375 7.5 5.7109375 7.5Z" 5,18.53125 c 0.019556,0.598212 0.681759,0.466668 1.0722656,0.351562
android:fillColor="#ffffff" /> 0.8179378,-0.179027 1.6351872,-0.358083 2.453125,-0.537109 2.5983114,-2.598958
</group> 5.1966104,-5.197918 7.7949214,-7.796875 z" />
</group>
</group> </group>
</vector> </vector>

View File

@@ -17,63 +17,100 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> -->
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o"
android:id="@+id/entry_edit_coordinator_layout" android:id="@+id/entry_edit_coordinator_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:importantForAutofill="noExcludeDescendants" app:layout_constraintTop_toBottomOf="@+id/toolbar"
tools:targetApi="o" > app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" > android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<include <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" android:id="@+id/toolbar_layout"
layout="@layout/toolbar_default" android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"/> android:layout_height="match_parent"
app:titleEnabled="false"
app:toolbarId="@+id/toolbar"
app:layout_scrollFlags="enterAlways|enterAlwaysCollapsed|scroll|exitUntilCollapsed|snap">
<ScrollView <FrameLayout
android:id="@+id/entry_edit_scroll" android:layout_width="wrap_content"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="0dp" android:layout_marginTop="?attr/actionBarSize">
app:layout_constraintTop_toBottomOf="@+id/toolbar" <androidx.appcompat.widget.Toolbar
app:layout_constraintStart_toStartOf="parent" android:layout_width="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:fillViewport="true"
android:scrollbars="none">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.kunzisoft.keepass.view.EntryEditContentsView
android:id="@+id/entry_edit_contents"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintWidth_percent="@dimen/content_percent" android:background="?attr/colorPrimaryDark"
app:layout_constraintTop_toTopOf="parent" android:theme="?attr/toolbarAppearance"
app:layout_constraintStart_toStartOf="parent" android:popupTheme="?attr/toolbarPopupAppearance">
app:layout_constraintEnd_toEndOf="parent"/> <androidx.appcompat.widget.ActionMenuView
</androidx.constraintlayout.widget.ConstraintLayout> android:id="@+id/entry_edit_bottom_bar"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"/>
</androidx.appcompat.widget.Toolbar>
<View
android:id="@+id/biometric_delimiter"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/colorAccent"/>
</FrameLayout>
</ScrollView> <androidx.appcompat.widget.Toolbar
</androidx.constraintlayout.widget.ConstraintLayout> android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="?attr/toolbarAppearance"
android:popupTheme="?attr/toolbarPopupAppearance"
app:layout_collapseMode="pin"
tools:targetApi="lollipop" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/entry_edit_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="insideOverlay"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.kunzisoft.keepass.view.EntryEditContentsView
android:id="@+id/entry_edit_contents"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="@dimen/content_percent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/entry_edit_save" android:id="@+id/entry_edit_validate"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" app:layout_anchorGravity="bottom|end"
android:src="@drawable/ic_save_white_24dp" app:layout_anchor="@+id/entry_edit_scroll"
android:contentDescription="@string/content_description_entry_save" android:src="@drawable/ic_check_white_24dp"
android:layout_margin="16dp" android:contentDescription="@string/validate"
app:useCompatPadding="true" app:useCompatPadding="true"
style="@style/KeepassDXStyle.Fab"/> style="@style/KeepassDXStyle.Fab"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -55,12 +55,18 @@
tools:ignore="TextFields" /> tools:ignore="TextFields" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<Button <androidx.appcompat.widget.AppCompatButton
android:id="@+id/generate_password_button" android:id="@+id/generate_password_button"
android:layout_margin="@dimen/button_margin" android:layout_margin="@dimen/button_margin"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="48dp" android:minHeight="48dp"
android:drawableEnd="@drawable/ic_generate_password_white_24dp"
android:drawableRight="@drawable/ic_generate_password_white_24dp"
android:paddingLeft="24dp"
android:paddingStart="24dp"
android:paddingRight="24dp"
android:paddingEnd="24dp"
android:text="@string/generate_password" /> android:text="@string/generate_password" />
</LinearLayout> </LinearLayout>

View File

@@ -27,7 +27,12 @@
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"> android:layout_marginTop="@dimen/default_margin"
android:layout_marginBottom="@dimen/default_margin"
android:layout_marginStart="@dimen/card_view_margin"
android:layout_marginEnd="@dimen/card_view_margin"
android:layout_marginLeft="@dimen/card_view_margin"
android:layout_marginRight="@dimen/card_view_margin">
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -182,10 +187,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/card_view_margin"
android:layout_marginEnd="@dimen/default_margin" android:layout_marginEnd="@dimen/card_view_margin"
android:layout_marginLeft="@dimen/default_margin" android:layout_marginLeft="@dimen/card_view_margin"
android:layout_marginRight="@dimen/default_margin" android:layout_marginRight="@dimen/card_view_margin"
android:layout_marginBottom="@dimen/default_margin"> android:layout_marginBottom="@dimen/default_margin">
<LinearLayout <LinearLayout
android:id="@+id/extra_strings" android:id="@+id/extra_strings"
@@ -200,10 +205,10 @@
android:id="@+id/entry_attachments_container" android:id="@+id/entry_attachments_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/card_view_margin"
android:layout_marginEnd="@dimen/default_margin" android:layout_marginEnd="@dimen/card_view_margin"
android:layout_marginLeft="@dimen/default_margin" android:layout_marginLeft="@dimen/card_view_margin"
android:layout_marginRight="@dimen/default_margin" android:layout_marginRight="@dimen/card_view_margin"
android:layout_marginBottom="@dimen/default_margin"> android:layout_marginBottom="@dimen/default_margin">
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -230,11 +235,11 @@
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/card_view_margin"
android:layout_marginEnd="@dimen/default_margin" android:layout_marginEnd="@dimen/card_view_margin"
android:layout_marginBottom="@dimen/default_margin" android:layout_marginLeft="@dimen/card_view_margin"
android:layout_marginLeft="@dimen/default_margin" android:layout_marginRight="@dimen/card_view_margin"
android:layout_marginRight="@dimen/default_margin"> android:layout_marginBottom="@dimen/default_margin">
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -313,10 +318,10 @@
android:id="@+id/entry_history_container" android:id="@+id/entry_history_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/card_view_margin"
android:layout_marginEnd="@dimen/default_margin" android:layout_marginEnd="@dimen/card_view_margin"
android:layout_marginLeft="@dimen/default_margin" android:layout_marginLeft="@dimen/card_view_margin"
android:layout_marginRight="@dimen/default_margin" android:layout_marginRight="@dimen/card_view_margin"
android:layout_marginBottom="@dimen/default_margin"> android:layout_marginBottom="@dimen/default_margin">
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -401,10 +406,10 @@
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/card_view_margin"
android:layout_marginEnd="@dimen/default_margin" android:layout_marginEnd="@dimen/card_view_margin"
android:layout_marginLeft="@dimen/default_margin" android:layout_marginLeft="@dimen/card_view_margin"
android:layout_marginRight="@dimen/default_margin" android:layout_marginRight="@dimen/card_view_margin"
android:layout_marginBottom="@dimen/default_margin"> android:layout_marginBottom="@dimen/default_margin">
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -421,15 +426,24 @@
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle" /> style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle" />
<HorizontalScrollView <HorizontalScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/entry_UUID" android:id="@+id/entry_UUID"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textIsSelectable="true" android:textIsSelectable="true"
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle" />
</HorizontalScrollView>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/entry_UUID_reference"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
style="@style/KeepassDXStyle.TextAppearance.TextEntryItem" /> style="@style/KeepassDXStyle.TextAppearance.TextEntryItem" />
</HorizontalScrollView> </HorizontalScrollView>
</LinearLayout> </LinearLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

View File

@@ -25,168 +25,195 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <androidx.cardview.widget.CardView
android:padding="@dimen/default_margin" android:id="@+id/entry_edit_container"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:layout_marginBottom="@dimen/default_margin"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<LinearLayout
<androidx.appcompat.widget.AppCompatImageButton android:orientation="vertical"
android:id="@+id/entry_edit_icon_button" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="4dp" android:layout_margin="@dimen/default_margin">
android:src="@drawable/ic_blank_32dp"
android:contentDescription="@string/content_description_entry_icon"
android:layout_gravity="center"/>
<!-- Title -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_edit_container_title"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_title"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Username -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_user_name"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Password -->
<RelativeLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_edit_container_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@+id/entry_edit_generate_button"
android:layout_toStartOf="@+id/entry_edit_generate_button">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_password"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Confirm Password -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_edit_container_confirmation_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:passwordToggleEnabled="true"
android:contentDescription="@string/content_description_repeat_toggle_password_visibility"
android:layout_toLeftOf="@+id/entry_edit_generate_button"
android:layout_toStartOf="@+id/entry_edit_generate_button"
android:layout_below="@+id/entry_edit_container_password">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_confirmation_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_confpassword"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/entry_edit_generate_button" android:id="@+id/entry_edit_icon_button"
android:layout_width="48dp" android:layout_width="wrap_content"
android:layout_height="48dp"
android:padding="12dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:src="@drawable/ic_key_white_24dp"
android:contentDescription="@string/content_description_password_generator"
android:tint="?attr/colorAccent"/>
</RelativeLayout>
<!-- URL -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_url"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:inputType="textUri" android:layout_margin="4dp"
android:importantForAccessibility="no" android:src="@drawable/ic_blank_32dp"
android:importantForAutofill="no" android:contentDescription="@string/content_description_entry_icon"
android:maxLines="1" android:layout_gravity="center"/>
android:hint="@string/entry_url"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Comment --> <!-- Title -->
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:id="@+id/entry_edit_container_title"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_notes"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:gravity="start"
android:maxLines="20"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:inputType="textMultiLine"
android:hint="@string/entry_notes"/>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_advanced_container" android:id="@+id/entry_edit_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:inputType="text"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_title"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Username -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_user_name"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Password -->
<androidx.constraintlayout.widget.ConstraintLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_edit_container_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_password"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Confirm Password -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_edit_container_confirmation_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/entry_edit_container_password"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:passwordToggleEnabled="true"
android:contentDescription="@string/content_description_repeat_toggle_password_visibility">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_confirmation_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_confpassword"/>
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- URL -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:maxLines="1"
android:hint="@string/entry_url"/>
</com.google.android.material.textfield.TextInputLayout>
<!-- Expires -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/entry_edit_expires_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="@string/entry_expires"
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/entry_edit_expires_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginEnd="6dp"
app:layout_constraintTop_toBottomOf="@+id/entry_edit_expires_label"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
style="@style/KeepassDXStyle.TextAppearance.Large"
tools:text="2020-03-04 05:00"/>
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/entry_edit_expires_presets"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/entry_edit_expires_label"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/entry_edit_expires_text"
app:layout_constraintEnd_toStartOf="@+id/entry_edit_expires_checkbox"/>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/entry_edit_expires_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/entry_edit_expires_label"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Notes -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/entry_edit_notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:maxLines="20"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:inputType="textMultiLine"
android:hint="@string/entry_notes"/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout> </LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.AppCompatImageButton <LinearLayout
android:id="@+id/entry_edit_add_new_field" android:id="@+id/entry_edit_advanced_container"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/ic_add_white_24dp" android:orientation="vertical"
android:contentDescription="@string/content_description_add_field" android:paddingTop="@dimen/default_margin"
android:tint="?attr/colorAccent" android:paddingBottom="@dimen/default_margin"
android:scaleType="centerCrop"/> app:layout_constraintTop_toBottomOf="@+id/entry_edit_container">
</LinearLayout> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -17,76 +17,87 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> -->
<RelativeLayout
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginBottom="@dimen/default_margin" android:layout_marginBottom="@dimen/default_margin"
android:importantForAutofill="noExcludeDescendants" android:layout_marginStart="0dp"
android:background="@drawable/background_stroke_element" android:layout_marginEnd="0dp"
tools:targetApi="o"> android:layout_marginLeft="0dp"
android:layout_marginRight="0dp">
<com.google.android.material.textfield.TextInputLayout <RelativeLayout
android:id="@+id/title_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="12dp" android:importantForAutofill="noExcludeDescendants"
android:paddingLeft="12dp" tools:targetApi="o">
android:paddingStart="12dp"
android:paddingRight="12dp"
android:paddingEnd="12dp">
<EditText <com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_new_field_label" android:id="@+id/title_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/field_name" android:paddingTop="12dp"
android:importantForAccessibility="no" android:paddingLeft="@dimen/default_margin"
android:importantForAutofill="no" android:paddingStart="@dimen/default_margin"
android:inputType="text" android:paddingRight="@dimen/default_margin"
android:maxLines="1" /> android:paddingEnd="@dimen/default_margin">
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatImageView <EditText
android:id="@+id/entry_new_field_delete" android:id="@+id/entry_new_field_label"
android:layout_width="48dp" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="wrap_content"
android:padding="12dp" android:hint="@string/field_name"
android:layout_alignParentEnd="true" android:importantForAccessibility="no"
android:layout_alignParentRight="true" android:importantForAutofill="no"
android:src="@drawable/ic_close_white_24dp" android:inputType="text"
android:contentDescription="@string/content_description_remove_field" android:maxLines="1" />
android:tint="?attr/colorAccent" /> </com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.SwitchCompat <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/protection" android:id="@+id/entry_new_field_delete"
style="@style/KeepassDXStyle.TextAppearance.Default" android:layout_width="48dp"
android:layout_width="wrap_content" android:layout_height="48dp"
android:layout_height="wrap_content" android:padding="12dp"
android:minHeight="48dp" android:layout_alignParentEnd="true"
android:layout_below="@+id/value_container" android:layout_alignParentRight="true"
android:layout_centerHorizontal="true" android:src="@drawable/ic_close_white_24dp"
android:text="@string/protection" /> android:contentDescription="@string/content_description_remove_field"
android:tint="?attr/colorAccent" />
<com.google.android.material.textfield.TextInputLayout <androidx.appcompat.widget.SwitchCompat
android:id="@+id/value_container" android:id="@+id/protection"
android:layout_width="match_parent" style="@style/KeepassDXStyle.TextAppearance.Default"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:paddingLeft="12dp" android:layout_height="wrap_content"
android:paddingStart="12dp" android:minHeight="48dp"
android:paddingRight="12dp" android:layout_below="@+id/value_container"
android:paddingEnd="12dp" android:layout_centerHorizontal="true"
android:layout_below="@+id/title_container"> android:text="@string/protection" />
<EditText <com.google.android.material.textfield.TextInputLayout
android:id="@+id/entry_new_field_value" android:id="@+id/value_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:inputType="textMultiLine" android:paddingLeft="@dimen/default_margin"
android:importantForAccessibility="no" android:paddingStart="@dimen/default_margin"
android:importantForAutofill="no" android:paddingRight="@dimen/default_margin"
android:hint="@string/field_value" /> android:paddingEnd="@dimen/default_margin"
</com.google.android.material.textfield.TextInputLayout> android:layout_below="@+id/title_container">
</RelativeLayout> <EditText
android:id="@+id/entry_new_field_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:hint="@string/field_value" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>

View File

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

View File

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

View File

@@ -50,7 +50,6 @@
<string name="error_invalid_path">تأكد أن المسار صحيح.</string> <string name="error_invalid_path">تأكد أن المسار صحيح.</string>
<string name="error_no_name">ادخل اسمًا.</string> <string name="error_no_name">ادخل اسمًا.</string>
<string name="error_pass_match">كلمتا السر غير متطابقتين.</string> <string name="error_pass_match">كلمتا السر غير متطابقتين.</string>
<string name="error_title_required">اكتب عنوانًا.</string>
<string name="field_name">اسم الحقل</string> <string name="field_name">اسم الحقل</string>
<string name="field_value">قيمة الحقل</string> <string name="field_value">قيمة الحقل</string>
<string name="generate_password">توليد كلمة سر</string> <string name="generate_password">توليد كلمة سر</string>
@@ -260,7 +259,7 @@
<string name="content_description_add_entry">إضافة إدخال</string> <string name="content_description_add_entry">إضافة إدخال</string>
<string name="content_description_add_group">إضافة مجموعة</string> <string name="content_description_add_group">إضافة مجموعة</string>
<string name="content_description_file_information">معلومات الملف</string> <string name="content_description_file_information">معلومات الملف</string>
<string name="content_description_password_generator">مولد كلمة السر</string> <string name="entry_password_generator">مولد كلمة السر</string>
<string name="content_description_background">الخلفية</string> <string name="content_description_background">الخلفية</string>
<string name="rounds">دورات التحويل</string> <string name="rounds">دورات التحويل</string>
<string name="rounds_explanation">توفر الدورات الاضافية ضد هجوم توليد التركيبات ،لكنها تبطئ التحميل والحفظ.</string> <string name="rounds_explanation">توفر الدورات الاضافية ضد هجوم توليد التركيبات ،لكنها تبطئ التحميل والحفظ.</string>
@@ -272,9 +271,8 @@
<string name="content_description_node_children">العقد الفرعية</string> <string name="content_description_node_children">العقد الفرعية</string>
<string name="content_description_add_node">أضف عقدة</string> <string name="content_description_add_node">أضف عقدة</string>
<string name="content_description_entry_icon">ايقونة المدخل</string> <string name="content_description_entry_icon">ايقونة المدخل</string>
<string name="content_description_entry_save">حفظ المدخل</string>
<string name="content_description_password_length">طول كلمة السر</string> <string name="content_description_password_length">طول كلمة السر</string>
<string name="content_description_add_field">أضف حقل</string> <string name="entry_add_field">أضف حقل</string>
<string name="content_description_remove_field">أزل حقل</string> <string name="content_description_remove_field">أزل حقل</string>
<string name="error_move_entry_here">لا يمكنك نقل مدخل هنا.</string> <string name="error_move_entry_here">لا يمكنك نقل مدخل هنا.</string>
<string name="error_copy_entry_here">لا يمكنك نسخ مدخل هنا.</string> <string name="error_copy_entry_here">لا يمكنك نسخ مدخل هنا.</string>

View File

@@ -69,7 +69,6 @@
<string name="error_pass_gen_type">Has de seleccionar almenys un tipus de generador de contrasenyes</string> <string name="error_pass_gen_type">Has de seleccionar almenys un tipus de generador de contrasenyes</string>
<string name="error_pass_match">Les contrasenyes no coincideixen.</string> <string name="error_pass_match">Les contrasenyes no coincideixen.</string>
<string name="error_rounds_too_large">Massa passades. Establint a 2147483648.</string> <string name="error_rounds_too_large">Massa passades. Establint a 2147483648.</string>
<string name="error_title_required">És necessari un títol.</string>
<string name="error_wrong_length">Insereix un enter positiu al camp longitud</string> <string name="error_wrong_length">Insereix un enter positiu al camp longitud</string>
<string name="file_browser">Explorador d\'arxius</string> <string name="file_browser">Explorador d\'arxius</string>
<string name="generate_password">Generar contrasenya</string> <string name="generate_password">Generar contrasenya</string>

View File

@@ -71,7 +71,6 @@
<string name="error_pass_match">Zadání hesla se neshodují.</string> <string name="error_pass_match">Zadání hesla se neshodují.</string>
<string name="error_rounds_too_large">Příliš vysoký „Počet průchodů“. Nastavuji na 2147483648.</string> <string name="error_rounds_too_large">Příliš vysoký „Počet průchodů“. Nastavuji na 2147483648.</string>
<string name="error_string_key">Je třeba, aby každý řetězec měl název kolonky.</string> <string name="error_string_key">Je třeba, aby každý řetězec měl název kolonky.</string>
<string name="error_title_required">Přidejte název.</string>
<string name="error_wrong_length">Do nastavení „Délka“ zadejte celé kladné číslo.</string> <string name="error_wrong_length">Do nastavení „Délka“ zadejte celé kladné číslo.</string>
<string name="field_name">Název pole</string> <string name="field_name">Název pole</string>
<string name="field_value">Hodnota pole</string> <string name="field_value">Hodnota pole</string>
@@ -284,7 +283,7 @@
<string name="education_generate_password_title">Vytvořte k záznamu silné heslo.</string> <string name="education_generate_password_title">Vytvořte k záznamu silné heslo.</string>
<string name="education_generate_password_summary">Vygenerujte silné heslo pro svou položku, definujte je podle kritérií formuláře, a nezapomeňte na bezpečné heslo.</string> <string name="education_generate_password_summary">Vygenerujte silné heslo pro svou položku, definujte je podle kritérií formuláře, a nezapomeňte na bezpečné heslo.</string>
<string name="education_entry_new_field_title">Přidat vlastní kolonky</string> <string name="education_entry_new_field_title">Přidat vlastní kolonky</string>
<string name="education_entry_new_field_summary">Chcete-li zaregistrovat základní kolonku, která není ve výchozím stavu k dispozici, jednoduše vyplňte novou kolonku. Novou kolonku můžete také nastavit jako chráněnou.</string> <string name="education_entry_new_field_summary">Registrovat další kolonku, zadat hodnotu a volitelně ji ochránit.</string>
<string name="education_unlock_title">Odemknout databázi</string> <string name="education_unlock_title">Odemknout databázi</string>
<string name="education_read_only_title">Ochraňte svou databázi před zápisem</string> <string name="education_read_only_title">Ochraňte svou databázi před zápisem</string>
<string name="education_read_only_summary">Změnit režim otevírání pro dané sezení. <string name="education_read_only_summary">Změnit režim otevírání pro dané sezení.
@@ -302,7 +301,7 @@
<string name="education_sort_summary">Vyberte řazení položek a skupin.</string> <string name="education_sort_summary">Vyberte řazení položek a skupin.</string>
<string name="education_donation_title">Zapojit se</string> <string name="education_donation_title">Zapojit se</string>
<string name="education_donation_summary">Zapojte se a pomozte zvýšit stabilitu, bezpečnost a přidávání dalších funkcí.</string> <string name="education_donation_summary">Zapojte se a pomozte zvýšit stabilitu, bezpečnost a přidávání dalších funkcí.</string>
<string name="html_text_ad_free">Na rozdíl od mnoha aplikací pro správu hesel, tato je &lt;strong&gt;bez reklam&lt;/strong&gt;, je &lt;strong&gt;svobodným softwarem&lt;/strong&gt; a &lt;strong&gt; pod copyleft licencí&lt;/strong&gt;. &lt;strong&gt;Nesbírá žádné osobní údaje&lt;/strong&gt; v jakékoli formě, bez ohledu na to, jakou verzi používáte.</string> <string name="html_text_ad_free">Na rozdíl od mnoha aplikací pro správu hesel, tato je &lt;strong&gt;bez reklam&lt;/strong&gt;", je "&lt;strong&gt;svobodný software pod copyleft licencí&lt;/strong&gt; a nesbírá žádné osobní údaje na svých serverech bez ohledu na to, jakou verzi používáte.</string>
<string name="html_text_buy_pro">Zakoupením varianty „pro“ získáte přístup k tomuto &lt;strong&gt;vizuálnímu stylu&lt;/strong&gt; a hlavně pomůžete &lt;strong&gt;uskutečnění komunitních projektů.&lt;/strong&gt;</string> <string name="html_text_buy_pro">Zakoupením varianty „pro“ získáte přístup k tomuto &lt;strong&gt;vizuálnímu stylu&lt;/strong&gt; a hlavně pomůžete &lt;strong&gt;uskutečnění komunitních projektů.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Tento &lt;strong&gt;vizuální styl&lt;/strong&gt; je k dispozici díky vaší štědrosti.</string> <string name="html_text_feature_generosity">Tento &lt;strong&gt;vizuální styl&lt;/strong&gt; je k dispozici díky vaší štědrosti.</string>
<string name="html_text_donation">Pro zajištění svobody nás všech a pokračování aktivity, počítáme s vaším &lt;strong&gt;přispěním.&lt;/strong&gt;</string> <string name="html_text_donation">Pro zajištění svobody nás všech a pokračování aktivity, počítáme s vaším &lt;strong&gt;přispěním.&lt;/strong&gt;</string>
@@ -362,10 +361,9 @@
<string name="content_description_keyfile_checkbox">Checkbox souboru s klíčem</string> <string name="content_description_keyfile_checkbox">Checkbox souboru s klíčem</string>
<string name="content_description_repeat_toggle_password_visibility">Přepni ukázání hesla</string> <string name="content_description_repeat_toggle_password_visibility">Přepni ukázání hesla</string>
<string name="content_description_entry_icon">Ikona záznamu</string> <string name="content_description_entry_icon">Ikona záznamu</string>
<string name="content_description_entry_save">Uložit záznam</string> <string name="entry_password_generator">Generátor hesel</string>
<string name="content_description_password_generator">Generátor hesel</string>
<string name="content_description_password_length">Délka hesla</string> <string name="content_description_password_length">Délka hesla</string>
<string name="content_description_add_field">Přidej pole</string> <string name="entry_add_field">Přidej pole</string>
<string name="content_description_remove_field">Odebrat pole</string> <string name="content_description_remove_field">Odebrat pole</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Sem záznam přesunout nelze.</string> <string name="error_move_entry_here">Sem záznam přesunout nelze.</string>
@@ -412,8 +410,6 @@
<string name="contains_duplicate_uuid_procedure">Prověřením toho dialogu opraví KeePassDX chybu (založením nového UUID pro duplikáty) a bude pokračovat.</string> <string name="contains_duplicate_uuid_procedure">Prověřením toho dialogu opraví KeePassDX chybu (založením nového UUID pro duplikáty) a bude pokračovat.</string>
<string name="database_opened">Databáze otevřena</string> <string name="database_opened">Databáze otevřena</string>
<string name="clipboard_explanation_summary">Kopírujte pole záznamů pomocí schránky Vašeho zařízení</string> <string name="clipboard_explanation_summary">Kopírujte pole záznamů pomocí schránky Vašeho zařízení</string>
<string name="persistent_notification_title">Trvalé oznámení</string>
<string name="persistent_notification_summary">Přidat oznámení, když je databáze otevřena</string>
<string name="advanced_unlock_explanation_summary">K snadnějšímu otevření databáze použijte pokročilé odemknutí</string> <string name="advanced_unlock_explanation_summary">K snadnějšímu otevření databáze použijte pokročilé odemknutí</string>
<string name="database_data_compression_title">Komprese dat</string> <string name="database_data_compression_title">Komprese dat</string>
<string name="database_data_compression_summary">Komprese dat snižuje velikost databáze.</string> <string name="database_data_compression_summary">Komprese dat snižuje velikost databáze.</string>
@@ -450,9 +446,26 @@
<string name="keyboard_auto_go_action_summary">Automatická akce klíče Jít po stisknutí klíče Pole</string> <string name="keyboard_auto_go_action_summary">Automatická akce klíče Jít po stisknutí klíče Pole</string>
<string name="download_attachment">Stáhnout %1$s</string> <string name="download_attachment">Stáhnout %1$s</string>
<string name="download_initialization">Zahajuji…</string> <string name="download_initialization">Zahajuji…</string>
<string name="download_progression">Probíhá: %1$d&#37;</string> <string name="download_progression">Probíhá: %1$d%</string>
<string name="download_finalization">Dokončuji…</string> <string name="download_finalization">Dokončuji…</string>
<string name="download_complete">Ukončeno! Klepnout pro otevření souboru.</string> <string name="download_complete">Ukončeno! Klepnout pro otevření souboru.</string>
<string name="hide_expired_entries_title">Skrýt propadlé záznamy</string> <string name="hide_expired_entries_title">Skrýt propadlé záznamy</string>
<string name="hide_expired_entries_summary">Propadlé záznamy budou skryty</string> <string name="hide_expired_entries_summary">Propadlé záznamy budou skryty</string>
<string name="contact">Kontakt</string>
<string name="contribution">Příspěvky</string>
<string name="feedback">Feedback</string>
<string name="auto_focus_search_title">Snadné hledání</string>
<string name="auto_focus_search_summary">Při otevření databáze žádat hledání</string>
<string name="remember_database_locations_title">Uložit umístění databází</string>
<string name="remember_database_locations_summary">Pamatovat si umístění databází</string>
<string name="remember_keyfile_locations_title">Uložit umístění souborů s klíči</string>
<string name="remember_keyfile_locations_summary">Pamatovat si umístění souborů s klíči</string>
<string name="show_recent_files_title">Ukázat nedávné soubory</string>
<string name="show_recent_files_summary">Ukázat umístění nedávných databází</string>
<string name="hide_broken_locations_title">Skrýt špatné odkazy na databáze</string>
<string name="hide_broken_locations_summary">Skrýt špatné odkazy v seznamu nedávných databází</string>
<string name="warning_database_read_only">Udělit právo zápisu pro uložení změn v databázi</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft je &lt;strong&gt;otevřený software&lt;/strong&gt; a &lt;strong&gt;bey reklam&lt;/strong&gt;.
\nJe poskytován jak je, pod licencí &lt;strong&gt;GPLv3&lt;/strong&gt;, bez jakékoli záruky.</string>
<string name="html_about_contribution">Abychom si &lt;strong&gt;udrželi svoji svobodu&lt;/strong&gt;, &lt;strong&gt;opravili chyby&lt;/strong&gt;,&lt;strong&gt;doplnili funkce&lt;/strong&gt; a &lt;strong&gt;byli vždy aktivní&lt;/strong&gt;, počítáme s Vaším &lt;strong&gt;přispěním&lt;/strong&gt;.</string>
</resources> </resources>

View File

@@ -70,7 +70,6 @@
<string name="error_pass_match">Adgangskoderne er ikke ens.</string> <string name="error_pass_match">Adgangskoderne er ikke ens.</string>
<string name="error_rounds_too_large">\"Transformation Runder\" er for stor. Sættes til 2147483648.</string> <string name="error_rounds_too_large">\"Transformation Runder\" er for stor. Sættes til 2147483648.</string>
<string name="error_string_key">Hver streng skal have et feltnavn.</string> <string name="error_string_key">Hver streng skal have et feltnavn.</string>
<string name="error_title_required">Tilføj en titel.</string>
<string name="error_wrong_length">Angiv et positivt heltal i feltet \"Længde\".</string> <string name="error_wrong_length">Angiv et positivt heltal i feltet \"Længde\".</string>
<string name="field_name">Feltnavn</string> <string name="field_name">Feltnavn</string>
<string name="field_value">Feltværdi</string> <string name="field_value">Feltværdi</string>
@@ -283,7 +282,7 @@
<string name="education_generate_password_title">Opret en stærk adgangskode til posten.</string> <string name="education_generate_password_title">Opret en stærk adgangskode til posten.</string>
<string name="education_generate_password_summary">Generer en stærk kodeord til at forbinde elementet, definer det i henhold til kriteriet for formularen og glem ikke et sikkert kodeord.</string> <string name="education_generate_password_summary">Generer en stærk kodeord til at forbinde elementet, definer det i henhold til kriteriet for formularen og glem ikke et sikkert kodeord.</string>
<string name="education_entry_new_field_title">Tilføj brugerdefinerede felter</string> <string name="education_entry_new_field_title">Tilføj brugerdefinerede felter</string>
<string name="education_entry_new_field_summary">Registrer et grundlæggende felt, der ikke er oprettet, ved at udfylde et ny, som også kan beskyttes.</string> <string name="education_entry_new_field_summary">Registrer et ekstra felt, tilføj en værdi og beskyt det eventuelt.</string>
<string name="education_unlock_title">Lås databasen op</string> <string name="education_unlock_title">Lås databasen op</string>
<string name="education_read_only_title">Skrivebeskyt databasen</string> <string name="education_read_only_title">Skrivebeskyt databasen</string>
<string name="education_read_only_summary">Skift åbningstilstanden for sessionen. <string name="education_read_only_summary">Skift åbningstilstanden for sessionen.
@@ -300,9 +299,9 @@
<string name="education_sort_summary">Vælg hvordan poster og grupper er sorteret.</string> <string name="education_sort_summary">Vælg hvordan poster og grupper er sorteret.</string>
<string name="education_donation_title">Deltag</string> <string name="education_donation_title">Deltag</string>
<string name="education_donation_summary">Bidrag til at øge stabiliteten, sikkerheden og med at tilføje flere funktioner.</string> <string name="education_donation_summary">Bidrag til at øge stabiliteten, sikkerheden og med at tilføje flere funktioner.</string>
<string name="html_text_ad_free">I modsætning til andre programmer til adgangskodeadministration er denne &lt;strong&gt; annoncefri &lt;/strong&gt;, &lt;strong&gt; copyleft fri software&lt;/strong&gt;, og indsamler ikke personlige data, uanset hvilken version der bruges.</string> <string name="html_text_ad_free">I modsætning til andre programmer til adgangskodeadministration er denne &lt;strong&gt;annoncefri&lt;/strong&gt;, &lt;strong&gt;copyleft fri software&lt;/strong&gt;, og indsamler ikke personlige data, uanset hvilken version der bruges.</string>
<string name="html_text_buy_pro">Ved at købe pro-versionen, er der adgang til &lt;strong&gt;visuel funktionen&lt;/strong&gt;, og det vil især hjælpe &lt;strong&gt;gennemførelsen af lokale projekter.&lt;/strong&gt;</string> <string name="html_text_buy_pro">Ved at købe pro-versionen, er der adgang til &lt;strong&gt;visuel stil&lt;/strong&gt;, og det vil især hjælpe &lt;strong&gt;gennemførelsen af lokale projekter.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Denne &lt;strong&gt;visuelle funktion&lt;/strong&gt; er tilgængelige takket være bidrag.</string> <string name="html_text_feature_generosity">Denne &lt;strong&gt;visuelle stil&lt;/strong&gt; er tilgængelige takket være bidrag.</string>
<string name="html_text_donation">For at bevare uafhængighed og altid at være aktiv, regner vi med &lt;strong&gt;bidrag.&lt;/strong&gt;</string> <string name="html_text_donation">For at bevare uafhængighed og altid at være aktiv, regner vi med &lt;strong&gt;bidrag.&lt;/strong&gt;</string>
<string name="html_text_dev_feature">Funktionen er &lt;strong&gt;under udvikling&lt;/strong&gt;, og det kræver &lt;strong&gt;bidrag&lt;/strong&gt;, for snart at være tilgængelig.</string> <string name="html_text_dev_feature">Funktionen er &lt;strong&gt;under udvikling&lt;/strong&gt;, og det kræver &lt;strong&gt;bidrag&lt;/strong&gt;, for snart at være tilgængelig.</string>
<string name="html_text_dev_feature_buy_pro">Ved at købe &lt;strong&gt;pro&lt;/strong&gt; versionen,</string> <string name="html_text_dev_feature_buy_pro">Ved at købe &lt;strong&gt;pro&lt;/strong&gt; versionen,</string>
@@ -361,10 +360,9 @@
<string name="content_description_keyfile_checkbox">Afkrydsningsfelt for nøglefil</string> <string name="content_description_keyfile_checkbox">Afkrydsningsfelt for nøglefil</string>
<string name="content_description_repeat_toggle_password_visibility">Gentag for at skifte synlighed for adgangskode</string> <string name="content_description_repeat_toggle_password_visibility">Gentag for at skifte synlighed for adgangskode</string>
<string name="content_description_entry_icon">Indtastningsikon</string> <string name="content_description_entry_icon">Indtastningsikon</string>
<string name="content_description_entry_save">Gem indtastning</string> <string name="entry_password_generator">Adgangskodegenerator</string>
<string name="content_description_password_generator">Adgangskodegenerator</string>
<string name="content_description_password_length">Længde på adgangskode</string> <string name="content_description_password_length">Længde på adgangskode</string>
<string name="content_description_add_field">Tilføj felt</string> <string name="entry_add_field">Tilføj felt</string>
<string name="content_description_remove_field">Fjern felt</string> <string name="content_description_remove_field">Fjern felt</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="list_groups_show_number_entries_title">Vis antal poster</string> <string name="list_groups_show_number_entries_title">Vis antal poster</string>
@@ -411,8 +409,6 @@
<string name="contains_duplicate_uuid_procedure">Ved at godkende dialogboksen, vil KeePassDX løse problemet (ved at generere nye UUID\'er for dubletter) og fortsætte.</string> <string name="contains_duplicate_uuid_procedure">Ved at godkende dialogboksen, vil KeePassDX løse problemet (ved at generere nye UUID\'er for dubletter) og fortsætte.</string>
<string name="database_opened">Database åbnet</string> <string name="database_opened">Database åbnet</string>
<string name="clipboard_explanation_summary">Kopier indtastningsfelter ved hjælp af enhedens udklipsholder</string> <string name="clipboard_explanation_summary">Kopier indtastningsfelter ved hjælp af enhedens udklipsholder</string>
<string name="persistent_notification_title">Vedvarende meddelelse</string>
<string name="persistent_notification_summary">Tilføj en meddelelse, når databasen er åben</string>
<string name="advanced_unlock_explanation_summary">Brug avanceret oplåsning for at gøre det lettere at åbne en database</string> <string name="advanced_unlock_explanation_summary">Brug avanceret oplåsning for at gøre det lettere at åbne en database</string>
<string name="database_data_compression_title">Datakomprimering</string> <string name="database_data_compression_title">Datakomprimering</string>
<string name="database_data_compression_summary">Datakomprimering reducerer databasens størrelse.</string> <string name="database_data_compression_summary">Datakomprimering reducerer databasens størrelse.</string>
@@ -449,9 +445,26 @@
<string name="keyboard_auto_go_action_summary">Handling af Gå-tasten udføres automatisk, efter der er trykket på en Felt nøgle</string> <string name="keyboard_auto_go_action_summary">Handling af Gå-tasten udføres automatisk, efter der er trykket på en Felt nøgle</string>
<string name="download_attachment">Hent %1$s</string> <string name="download_attachment">Hent %1$s</string>
<string name="download_initialization">Initialiserer…</string> <string name="download_initialization">Initialiserer…</string>
<string name="download_progression">I gang: %1$d&#37;</string> <string name="download_progression">I gang: %1$d%</string>
<string name="download_finalization">Færdiggørelse…</string> <string name="download_finalization">Færdiggørelse…</string>
<string name="download_complete">Komplet! Tryk for at åbne filen.</string> <string name="download_complete">Komplet! Tryk for at åbne filen.</string>
<string name="hide_expired_entries_title">Skjul udløbne poster</string> <string name="hide_expired_entries_title">Skjul udløbne poster</string>
<string name="hide_expired_entries_summary">Udløbne poster vil blive skjult</string> <string name="hide_expired_entries_summary">Udløbne poster vil blive skjult</string>
<string name="contact">Kontakt</string>
<string name="contribution">Bidrag</string>
<string name="feedback">Tilbagemelding</string>
<string name="html_about_licence">KeePassDX ©%1$d Kunzisoft er &lt;strong&gt;open source&lt;/strong&gt; og &lt;strong&gt;uden reklamer&lt;/strong&gt;.
\nDet leveres som det er under &lt;strong&gt;GPLv3&lt;/strong&gt; licens uden nogen garanti.</string>
<string name="html_about_contribution">For at &lt;strong&gt;holde vores frihed&lt;/strong&gt;, &lt;strong&gt;rette fejl&lt;/strong&gt;, &lt;strong&gt;tilføje funktioner&lt;/strong&gt; og &lt;strong&gt;at være altid aktiv&lt;/strong&gt;, regner vi med &lt;strong&gt;bidrag&lt;/strong&gt;.</string>
<string name="auto_focus_search_title">Hurtig søgning</string>
<string name="auto_focus_search_summary">Anmod om en søgning når en database åbnes</string>
<string name="remember_database_locations_title">Gem placering af databaser</string>
<string name="remember_database_locations_summary">Husk placeringen af databaser</string>
<string name="remember_keyfile_locations_title">Gem placering af nøglefiler</string>
<string name="remember_keyfile_locations_summary">Husker placeringen af databasernøglefiler</string>
<string name="show_recent_files_title">Vis seneste filer</string>
<string name="show_recent_files_summary">Vis placeringer af de seneste databaser</string>
<string name="hide_broken_locations_title">Skjule brudte databaselinks</string>
<string name="hide_broken_locations_summary">Skjul brudte links på listen over seneste databaser</string>
<string name="warning_database_read_only">Giv fil skriveadgang for at gemme databasændringer</string>
</resources> </resources>

View File

@@ -75,7 +75,6 @@
<string name="error_pass_match">Die Passwörter stimmen nicht überein.</string> <string name="error_pass_match">Die Passwörter stimmen nicht überein.</string>
<string name="error_rounds_too_large">„Transformationsrunden“ zu hoch. Wird auf 2147483648 eingestellt.</string> <string name="error_rounds_too_large">„Transformationsrunden“ zu hoch. Wird auf 2147483648 eingestellt.</string>
<string name="error_string_key">Für jede Zeichenfolge ist ein Feldname notwendig.</string> <string name="error_string_key">Für jede Zeichenfolge ist ein Feldname notwendig.</string>
<string name="error_title_required">Titel hinzufügen.</string>
<string name="error_wrong_length">Eine positive ganze Zahl in das Feld „Länge“ eingeben.</string> <string name="error_wrong_length">Eine positive ganze Zahl in das Feld „Länge“ eingeben.</string>
<string name="field_name">Feldname</string> <string name="field_name">Feldname</string>
<string name="field_value">Feldwert</string> <string name="field_value">Feldwert</string>
@@ -270,7 +269,7 @@
<string name="education_generate_password_title">Ein starkes Passwort für den Eintrag erstellen.</string> <string name="education_generate_password_title">Ein starkes Passwort für den Eintrag erstellen.</string>
<string name="education_generate_password_summary">Erzeugung eines starken Passworts, das mit dem Eintrag verknüpft wird, nach Kriterien, die einfach in einem Formular festgelegt werden. Dabei an die Passwortsicherheit denken.</string> <string name="education_generate_password_summary">Erzeugung eines starken Passworts, das mit dem Eintrag verknüpft wird, nach Kriterien, die einfach in einem Formular festgelegt werden. Dabei an die Passwortsicherheit denken.</string>
<string name="education_entry_new_field_title">Benutzerdefinierte Felder hinzufügen</string> <string name="education_entry_new_field_title">Benutzerdefinierte Felder hinzufügen</string>
<string name="education_entry_new_field_summary">Ein wichtiges, nicht mitgeliefertes Feld erfassen, indem ein neues Feld ausgefüllt wird, das sich auch schützen lässt.</string> <string name="education_entry_new_field_summary">Tragen Sie ein zusätzliches Feld ein, fügen Sie einen Wert hinzu und schützen Sie es optional.</string>
<string name="education_unlock_title">Die Datenbank entsperren</string> <string name="education_unlock_title">Die Datenbank entsperren</string>
<string name="education_field_copy_title">Ein Feld kopieren</string> <string name="education_field_copy_title">Ein Feld kopieren</string>
<string name="education_field_copy_summary">Kopierte Felder können an beliebiger Stelle eingefügt werden. <string name="education_field_copy_summary">Kopierte Felder können an beliebiger Stelle eingefügt werden.
@@ -289,10 +288,10 @@
<string name="html_text_dev_feature">Diese Funktion ist &lt;strong&gt;in Entwicklung&lt;/strong&gt; und erfordert &lt;strong&gt;Ihren Beitrag&lt;/strong&gt;, um bald verfügbar zu sein.</string> <string name="html_text_dev_feature">Diese Funktion ist &lt;strong&gt;in Entwicklung&lt;/strong&gt; und erfordert &lt;strong&gt;Ihren Beitrag&lt;/strong&gt;, um bald verfügbar zu sein.</string>
<string name="html_text_dev_feature_buy_pro">Durch den Kauf der &lt;strong&gt;Pro-Version&lt;/strong&gt;,</string> <string name="html_text_dev_feature_buy_pro">Durch den Kauf der &lt;strong&gt;Pro-Version&lt;/strong&gt;,</string>
<string name="html_text_dev_feature_contibute">Durch Ihr &lt;strong&gt;Mitwirken&lt;/strong&gt;,</string> <string name="html_text_dev_feature_contibute">Durch Ihr &lt;strong&gt;Mitwirken&lt;/strong&gt;,</string>
<string name="html_text_dev_feature_encourage">du bestärkst die Entwickler:innen, &lt;strong&gt;neue Funktionen&lt;/strong&gt; einzuführen und gemäß deinen&lt;strong&gt; Anmerkungen &lt;strong&gt;Fehler auszumerzen&lt;/strong&gt;.&lt;strong&gt;neue Funktionen&lt;/strong&gt; einzuführen und gemäß Ihren Anmerkungen &lt;strong&gt;Fehler auszumerzen&lt;/strong&gt;.</string> <string name="html_text_dev_feature_encourage">Sie ermutigen die Entwickler:innen, &lt;strong&gt;neue Funktionen&lt;/strong&gt; einzuführen und gemäß Ihren Anmerkungen &lt;strong&gt;Fehler zu beheben&lt;/strong&gt;.</string>
<string name="html_text_dev_feature_thanks">Vielen Dank für Ihre Unterstützung.</string> <string name="html_text_dev_feature_thanks">Vielen Dank für Ihre Unterstützung.</string>
<string name="html_text_dev_feature_work_hard">Wir bemühen uns, diese Funktion bald zu veröffentlichen.</string> <string name="html_text_dev_feature_work_hard">Wir bemühen uns, diese Funktion bald zu veröffentlichen.</string>
<string name="html_text_dev_feature_upgrade">Vergessen Sie nicht, Ihre App aktuell zu halten indem sie neue Versionen installieren.</string> <string name="html_text_dev_feature_upgrade">Vergessen Sie nicht, Ihre App aktuell zu halten, indem Sie neue Versionen installieren.</string>
<string name="download">Download</string> <string name="download">Download</string>
<string name="contribute">Unterstützen</string> <string name="contribute">Unterstützen</string>
<string name="encryption_chacha20">ChaCha20</string> <string name="encryption_chacha20">ChaCha20</string>
@@ -358,10 +357,9 @@
<string name="content_description_add_group">Gruppe hinzufügen</string> <string name="content_description_add_group">Gruppe hinzufügen</string>
<string name="content_description_file_information">Datei-Informationen</string> <string name="content_description_file_information">Datei-Informationen</string>
<string name="content_description_entry_icon">Symbol für den Eintrag</string> <string name="content_description_entry_icon">Symbol für den Eintrag</string>
<string name="content_description_entry_save">Eintrag speichern</string> <string name="entry_password_generator">Passwort-Generator</string>
<string name="content_description_password_generator">Passwort-Generator</string>
<string name="content_description_password_length">Passwortlänge</string> <string name="content_description_password_length">Passwortlänge</string>
<string name="content_description_add_field">Feld hinzufügen</string> <string name="entry_add_field">Feld hinzufügen</string>
<string name="content_description_remove_field">Feld entfernen</string> <string name="content_description_remove_field">Feld entfernen</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="list_groups_show_number_entries_title">Anzahl der Einträge anzeigen</string> <string name="list_groups_show_number_entries_title">Anzahl der Einträge anzeigen</string>
@@ -415,8 +413,6 @@
<string name="contains_duplicate_uuid_procedure">Durch die Validierung dieses Dialogs wird KeePassDX das Problem (durch Erzeugung neuer UUIDs für Duplikate) beheben und weiter ausgeführt.</string> <string name="contains_duplicate_uuid_procedure">Durch die Validierung dieses Dialogs wird KeePassDX das Problem (durch Erzeugung neuer UUIDs für Duplikate) beheben und weiter ausgeführt.</string>
<string name="database_opened">Datenbank geöffnet</string> <string name="database_opened">Datenbank geöffnet</string>
<string name="clipboard_explanation_summary">Eintragsfelder mithilfe der Zwischenablage des Geräts kopieren</string> <string name="clipboard_explanation_summary">Eintragsfelder mithilfe der Zwischenablage des Geräts kopieren</string>
<string name="persistent_notification_title">Dauerhafte Benachrichtigung</string>
<string name="persistent_notification_summary">Bei geöffneter Datenbank eine Benachrichtigung hinzufügen</string>
<string name="advanced_unlock_explanation_summary">Erweitertes Entsperren verwenden, um eine Datenbank einfacher zu öffnen.</string> <string name="advanced_unlock_explanation_summary">Erweitertes Entsperren verwenden, um eine Datenbank einfacher zu öffnen.</string>
<string name="database_data_compression_title">Datenkompression</string> <string name="database_data_compression_title">Datenkompression</string>
<string name="database_data_compression_summary">Datenkompression reduziert die Datenbankgröße.</string> <string name="database_data_compression_summary">Datenkompression reduziert die Datenbankgröße.</string>
@@ -453,7 +449,7 @@
<string name="keyboard_auto_go_action_summary">Aktion der Go-Taste, die automatisch nach dem Drücken einer Feldtaste ausgeführt wird</string> <string name="keyboard_auto_go_action_summary">Aktion der Go-Taste, die automatisch nach dem Drücken einer Feldtaste ausgeführt wird</string>
<string name="download_attachment">%1$s herunterladen</string> <string name="download_attachment">%1$s herunterladen</string>
<string name="download_initialization">Initialisieren…</string> <string name="download_initialization">Initialisieren…</string>
<string name="download_progression">Fortschritt: %1$d&#37;</string> <string name="download_progression">Fortschritt: %1$d%</string>
<string name="download_finalization">Fertigstellung…</string> <string name="download_finalization">Fertigstellung…</string>
<string name="download_complete">Vollständig! Tippen Sie, um die Datei zu öffnen.</string> <string name="download_complete">Vollständig! Tippen Sie, um die Datei zu öffnen.</string>
<string name="hide_expired_entries_title">Abgelaufene Einträge ausblenden</string> <string name="hide_expired_entries_title">Abgelaufene Einträge ausblenden</string>

View File

@@ -71,7 +71,6 @@
<string name="error_pass_match">Οι κωδικοί δεν ταιριάζουν.</string> <string name="error_pass_match">Οι κωδικοί δεν ταιριάζουν.</string>
<string name="error_rounds_too_large">Οι \"κύκλοι μετασχηματισμού\" είναι πολύ υψηλοί. Ρύθμιση στο 2147483648.</string> <string name="error_rounds_too_large">Οι \"κύκλοι μετασχηματισμού\" είναι πολύ υψηλοί. Ρύθμιση στο 2147483648.</string>
<string name="error_string_key">Κάθε σειρά πρέπει να έχει όνομα πεδίου.</string> <string name="error_string_key">Κάθε σειρά πρέπει να έχει όνομα πεδίου.</string>
<string name="error_title_required">Προσθέστε έναν τίτλο.</string>
<string name="error_wrong_length">Εισάγετε ένα θετικό ακέραιο αριθμό στο πεδίο \"Μήκος\".</string> <string name="error_wrong_length">Εισάγετε ένα θετικό ακέραιο αριθμό στο πεδίο \"Μήκος\".</string>
<string name="field_name">Όνομα πεδίου</string> <string name="field_name">Όνομα πεδίου</string>
<string name="field_value">Τιμή πεδίου</string> <string name="field_value">Τιμή πεδίου</string>
@@ -341,10 +340,9 @@
<string name="content_description_keyfile_checkbox">Πλαίσιο ελέγχου κλειδιού-αρχείου</string> <string name="content_description_keyfile_checkbox">Πλαίσιο ελέγχου κλειδιού-αρχείου</string>
<string name="content_description_repeat_toggle_password_visibility">Επανάληψη της ορατότητας του κωδικού πρόσβασης</string> <string name="content_description_repeat_toggle_password_visibility">Επανάληψη της ορατότητας του κωδικού πρόσβασης</string>
<string name="content_description_entry_icon">Εικονίδιο καταχώρησης</string> <string name="content_description_entry_icon">Εικονίδιο καταχώρησης</string>
<string name="content_description_entry_save">Αποθήκευση καταχώρησης</string> <string name="entry_password_generator">Γεννήτρια κωδικού πρόσβασης</string>
<string name="content_description_password_generator">Γεννήτρια κωδικού πρόσβασης</string>
<string name="content_description_password_length">Μήκος κωδικού πρόσβασης</string> <string name="content_description_password_length">Μήκος κωδικού πρόσβασης</string>
<string name="content_description_add_field">Προσθήκη πεδίου</string> <string name="entry_add_field">Προσθήκη πεδίου</string>
<string name="content_description_remove_field">Αφαίρεση πεδίου</string> <string name="content_description_remove_field">Αφαίρεση πεδίου</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Δεν μπορείτε να μετακινήσετε μια καταχώρηση εδώ.</string> <string name="error_move_entry_here">Δεν μπορείτε να μετακινήσετε μια καταχώρηση εδώ.</string>
@@ -408,8 +406,6 @@
<string name="autofill_explanation_summary">Ενεργοποιήστε την αυτόματη συμπλήρωση για να συμπληρώσετε γρήγορα φόρμες σε άλλες εφαρμογές</string> <string name="autofill_explanation_summary">Ενεργοποιήστε την αυτόματη συμπλήρωση για να συμπληρώσετε γρήγορα φόρμες σε άλλες εφαρμογές</string>
<string name="database_opened">Η Βάση Δεδομένων άνοιξε</string> <string name="database_opened">Η Βάση Δεδομένων άνοιξε</string>
<string name="clipboard_explanation_summary">Αντιγράψτε τα πεδία εισαγωγής χρησιμοποιώντας το πρόχειρο της συσκευής σας</string> <string name="clipboard_explanation_summary">Αντιγράψτε τα πεδία εισαγωγής χρησιμοποιώντας το πρόχειρο της συσκευής σας</string>
<string name="persistent_notification_title">Συνεχής ειδοποίηση</string>
<string name="persistent_notification_summary">Προσθήκη ειδοποίησης όταν η βάση δεδομένων είναι ανοιχτή</string>
<string name="advanced_unlock_explanation_summary">Χρησιμοποιήστε το προηγμένο ξεκλείδωμα για να ανοίξετε μια βάση δεδομένων πιο εύκολα</string> <string name="advanced_unlock_explanation_summary">Χρησιμοποιήστε το προηγμένο ξεκλείδωμα για να ανοίξετε μια βάση δεδομένων πιο εύκολα</string>
<string name="database_data_compression_title">Συμπίεση Δεδομένων</string> <string name="database_data_compression_title">Συμπίεση Δεδομένων</string>
<string name="database_data_compression_summary">Η συμπίεση δεδομένων μειώνει το μέγεθος της βάσης δεδομένων.</string> <string name="database_data_compression_summary">Η συμπίεση δεδομένων μειώνει το μέγεθος της βάσης δεδομένων.</string>

View File

@@ -67,7 +67,6 @@
<string name="error_pass_gen_type">Debe seleccionar al menos un tipo de generación de contraseñas.</string> <string name="error_pass_gen_type">Debe seleccionar al menos un tipo de generación de contraseñas.</string>
<string name="error_pass_match">Las contraseñas no coinciden.</string> <string name="error_pass_match">Las contraseñas no coinciden.</string>
<string name="error_rounds_too_large">Pasadas demasiado grande. Establecido a 2147483648.</string> <string name="error_rounds_too_large">Pasadas demasiado grande. Establecido a 2147483648.</string>
<string name="error_title_required">Añada un título.</string>
<string name="error_wrong_length">Proporcione un número entero positivo en el campo «Longitud».</string> <string name="error_wrong_length">Proporcione un número entero positivo en el campo «Longitud».</string>
<string name="file_browser">Explorador de archivos</string> <string name="file_browser">Explorador de archivos</string>
<string name="generate_password">Generar contraseña</string> <string name="generate_password">Generar contraseña</string>
@@ -355,9 +354,9 @@
<string name="content_description_password_checkbox">Casilla de contraseña</string> <string name="content_description_password_checkbox">Casilla de contraseña</string>
<string name="content_description_keyfile_checkbox">Casilla de archivo de clave</string> <string name="content_description_keyfile_checkbox">Casilla de archivo de clave</string>
<string name="content_description_entry_icon">Icono de entrada</string> <string name="content_description_entry_icon">Icono de entrada</string>
<string name="content_description_password_generator">Generador de contraseñas</string> <string name="entry_password_generator">Generador de contraseñas</string>
<string name="content_description_password_length">Longitud de contraseña</string> <string name="content_description_password_length">Longitud de contraseña</string>
<string name="content_description_add_field">Añadir campo</string> <string name="entry_add_field">Añadir campo</string>
<string name="content_description_remove_field">Quitar campo</string> <string name="content_description_remove_field">Quitar campo</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">No puede desplazar entradas aquí.</string> <string name="error_move_entry_here">No puede desplazar entradas aquí.</string>
@@ -384,7 +383,6 @@
\n\"Modificable\" le permite agregar, eliminar o modificar todos los elementos.</string> \n\"Modificable\" le permite agregar, eliminar o modificar todos los elementos.</string>
<string name="lock_database_back_root_title">Presione hacia atrás en la raíz para bloquear</string> <string name="lock_database_back_root_title">Presione hacia atrás en la raíz para bloquear</string>
<string name="content_description_repeat_toggle_password_visibility">Repetir la visibilidad de la contraseña</string> <string name="content_description_repeat_toggle_password_visibility">Repetir la visibilidad de la contraseña</string>
<string name="content_description_entry_save">Guardar entrada</string>
<string name="master_key">Llave Maestra</string> <string name="master_key">Llave Maestra</string>
<string name="security">Seguridad</string> <string name="security">Seguridad</string>
<string name="entry_history">Historial</string> <string name="entry_history">Historial</string>

View File

@@ -73,7 +73,6 @@
<string name="error_pass_match">Pasahitzak ez datoz bat.</string> <string name="error_pass_match">Pasahitzak ez datoz bat.</string>
<string name="error_rounds_too_large">Rondak handiegiak. 2147483648 balorean jarrita.</string> <string name="error_rounds_too_large">Rondak handiegiak. 2147483648 balorean jarrita.</string>
<string name="error_string_key">Eremu izen bat behar da testu kate bakoitzerako.</string> <string name="error_string_key">Eremu izen bat behar da testu kate bakoitzerako.</string>
<string name="error_title_required">Izenburu bat behar da.</string>
<string name="error_wrong_length">Eremuaren luzeran entero positibo bat sartu</string> <string name="error_wrong_length">Eremuaren luzeran entero positibo bat sartu</string>
<string name="field_name">Eremuaren izena</string> <string name="field_name">Eremuaren izena</string>
<string name="field_value">Eremuaren balorea</string> <string name="field_value">Eremuaren balorea</string>

View File

@@ -1,161 +1,160 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
Copyright 2019 Jeremy Jamet / Kunzisoft. Copyright 2019 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX. This file is part of KeePassDX.
KeePassDX 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
KeePassDX 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 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="feedback">Palaute:</string> <string name="feedback">Palaute:</string>
<string name="homepage">Kotisivu:</string> <string name="homepage">Kotisivu:</string>
<string name="about_description">KeePassDX on KeePass-salasanahallintaohjelman Android-versio</string> <string name="about_description">KeePassDX on KeePass-salasanahallintaohjelman Android-versio</string>
<string name="accept">Hyväksy</string> <string name="accept">Hyväksy</string>
<string name="add_entry">Lisää uusi salasanatietue</string> <string name="add_entry">Lisää uusi salasanatietue</string>
<string name="add_group">Lisää ryhmä</string> <string name="add_group">Lisää ryhmä</string>
<string name="encryption_algorithm">Algoritmi</string> <string name="encryption_algorithm">Algoritmi</string>
<string name="app_timeout">Ohjelman aikakatkaisu</string> <string name="app_timeout">Ohjelman aikakatkaisu</string>
<string name="app_timeout_summary">Aika, jonka jälkeen KeePass lukitaan jos se on ollut toimeton.</string> <string name="app_timeout_summary">Aika, jonka jälkeen KeePass lukitaan jos se on ollut toimeton.</string>
<string name="application">Ohjelma</string> <string name="application">Ohjelma</string>
<string name="menu_app_settings">Ohjelman asetukset</string> <string name="menu_app_settings">Ohjelman asetukset</string>
<string name="beta_dontask">Älä näytä enää uudelleen</string> <string name="beta_dontask">Älä näytä enää uudelleen</string>
<string name="brackets">Hakasulkeet</string> <string name="brackets">Hakasulkeet</string>
<string name="file_manager_install_description">Tiedostojen selaus vaatii Open Intents File Manager -tiedostonhallintaohjelman, klikkaa alla olevaa linkkiä asentaaksesi sen. Joidenkin ominaisuuksien takia se ei ehkä toimi oikein ensimmäisellä käynnistyksellä.</string> <string name="file_manager_install_description">Tiedostojen selaus vaatii Open Intents File Manager -tiedostonhallintaohjelman, klikkaa alla olevaa linkkiä asentaaksesi sen. Joidenkin ominaisuuksien takia se ei ehkä toimi oikein ensimmäisellä käynnistyksellä.</string>
<string name="clipboard_cleared">Leikepöytä tyhjennetty.</string> <string name="clipboard_cleared">Leikepöytä tyhjennetty.</string>
<string name="clipboard_error_title">Leikepöytävirhe</string> <string name="clipboard_error_title">Leikepöytävirhe</string>
<string name="clipboard_error">Joissakin Android-puhelimissa on virhe leikepöydän toteutuksessa, mikä aiheuttaa kopioinnin epäonnistumisen. Lisätietoa:</string> <string name="clipboard_error">Joissakin Android-puhelimissa on virhe leikepöydän toteutuksessa, mikä aiheuttaa kopioinnin epäonnistumisen. Lisätietoa:</string>
<string name="clipboard_error_clear">Leikepöydän tyhjennys epäonnistui</string> <string name="clipboard_error_clear">Leikepöydän tyhjennys epäonnistui</string>
<string name="clipboard_timeout">Leikepöydän aikakatkaisu</string> <string name="clipboard_timeout">Leikepöydän aikakatkaisu</string>
<string name="clipboard_timeout_summary">Aika, jonka jälkeen leikepöytä tyhjennetään käyttäjätunnuksen tai salasanan kopioinnin jälkeen</string> <string name="clipboard_timeout_summary">Aika, jonka jälkeen leikepöytä tyhjennetään käyttäjätunnuksen tai salasanan kopioinnin jälkeen</string>
<string name="select_to_copy">Valitse kopioidaksesi %1$s</string> <string name="select_to_copy">Valitse kopioidaksesi %1$s</string>
<string name="retrieving_db_key">Luodaan tietokanta-avainta&#8230;</string> <string name="retrieving_db_key">Luodaan tietokanta-avainta&#8230;</string>
<string name="database">Tietokanta</string> <string name="database">Tietokanta</string>
<string name="decrypting_db">Puretaan tietokannan salausta&#8230;</string> <string name="decrypting_db">Puretaan tietokannan salausta&#8230;</string>
<string name="default_checkbox">Käytä tätä oletustietokantana</string> <string name="default_checkbox">Käytä tätä oletustietokantana</string>
<string name="digits">Numerot</string> <string name="digits">Numerot</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft comes with absolutely no warranty. This is free software, and you are welcome to redistribute it under the conditions of the GPL version 3 or later.</string> <string name="html_about_licence">KeePassDX © %1$d Kunzisoft comes with absolutely no warranty. This is free software, and you are welcome to redistribute it under the conditions of the GPL version 3 or later.</string>
<string name="select_database_file">Anna tietokannan tiedostonimi</string> <string name="select_database_file">Anna tietokannan tiedostonimi</string>
<string name="entry_accessed">Käytetty</string> <string name="entry_accessed">Käytetty</string>
<string name="entry_cancel">Peruuta</string> <string name="entry_cancel">Peruuta</string>
<string name="entry_notes">Kommentit</string> <string name="entry_notes">Kommentit</string>
<string name="entry_confpassword">Vahvista salasana</string> <string name="entry_confpassword">Vahvista salasana</string>
<string name="entry_created">Luotu</string> <string name="entry_created">Luotu</string>
<string name="entry_expires">Vanhenee</string> <string name="entry_expires">Vanhenee</string>
<string name="entry_keyfile">Avaintiedosto</string> <string name="entry_keyfile">Avaintiedosto</string>
<string name="entry_modified">Muokattu</string> <string name="entry_modified">Muokattu</string>
<string name="entry_not_found">Tietueen tietoja ei löytynyt.</string> <string name="entry_not_found">Tietueen tietoja ei löytynyt.</string>
<string name="entry_password">Salasana</string> <string name="entry_password">Salasana</string>
<string name="entry_save">Tallenna</string> <string name="entry_save">Tallenna</string>
<string name="entry_title">Nimi</string> <string name="entry_title">Nimi</string>
<string name="entry_url">URL-osoite</string> <string name="entry_url">URL-osoite</string>
<string name="entry_user_name">Käyttäjänimi</string> <string name="entry_user_name">Käyttäjänimi</string>
<string name="error_arc4">The Arcfour stream cipher ei ole tuettu.</string> <string name="error_arc4">The Arcfour stream cipher ei ole tuettu.</string>
<string name="error_can_not_handle_uri">KeePassDX ei osaa käsitellä tätä osoitetta.</string> <string name="error_can_not_handle_uri">KeePassDX ei osaa käsitellä tätä osoitetta.</string>
<string name="error_file_not_create">Tiedoston luonti epäonnistui:</string> <string name="error_file_not_create">Tiedoston luonti epäonnistui:</string>
<string name="error_invalid_db">Viallinen salasanatietokanta.</string> <string name="error_invalid_db">Viallinen salasanatietokanta.</string>
<string name="error_invalid_path">Viallinen hakemistopolku.</string> <string name="error_invalid_path">Viallinen hakemistopolku.</string>
<string name="error_no_name">Nimi puuttuu.</string> <string name="error_no_name">Nimi puuttuu.</string>
<string name="error_nokeyfile">Salasana tai avaintiedosto puuttuu.</string> <string name="error_nokeyfile">Salasana tai avaintiedosto puuttuu.</string>
<string name="error_out_of_memory">Puhelimesta loppui muisti salasanatietokantaa avatessa. Tietokanta voi olla liian suuri tälle puhelinmallille.</string> <string name="error_out_of_memory">Puhelimesta loppui muisti salasanatietokantaa avatessa. Tietokanta voi olla liian suuri tälle puhelinmallille.</string>
<string name="error_pass_gen_type">Vähintään yksi salasanagenerointitapa täytyy olla valittuna.</string> <string name="error_pass_gen_type">Vähintään yksi salasanagenerointitapa täytyy olla valittuna.</string>
<string name="error_pass_match">Salasanat eivät täsmää.</string> <string name="error_pass_match">Salasanat eivät täsmää.</string>
<string name="error_rounds_too_large">Kierroksia on liian paljon. Asetetaan se arvoon 2147483648.</string> <string name="error_rounds_too_large">Kierroksia on liian paljon. Asetetaan se arvoon 2147483648.</string>
<string name="error_string_key">Kentän nimi on pakollinen joka tekstille.</string> <string name="error_string_key">Kentän nimi on pakollinen joka tekstille.</string>
<string name="error_title_required">Otsikko on pakollinen.</string> <string name="error_wrong_length">Syötä positiivinen kokonaisluku pituus-kenttään</string>
<string name="error_wrong_length">Syötä positiivinen kokonaisluku pituus-kenttään</string> <string name="field_name">Kentän nimi</string>
<string name="field_name">Kentän nimi</string> <string name="field_value">Kentän arvo</string>
<string name="field_value">Kentän arvo</string> <string name="file_browser">Tiedostoselain</string>
<string name="file_browser">Tiedostoselain</string> <string name="generate_password">Generoi salasana</string>
<string name="generate_password">Generoi salasana</string> <string name="hint_conf_pass">vahvista salasana</string>
<string name="hint_conf_pass">vahvista salasana</string> <string name="hint_generated_password">generoidut salasanat</string>
<string name="hint_generated_password">generoidut salasanat</string> <string name="hint_group_name">Ryhmän nimi</string>
<string name="hint_group_name">Ryhmän nimi</string> <string name="hint_keyfile">avaintiedosto</string>
<string name="hint_keyfile">avaintiedosto</string> <string name="hint_length">pituus</string>
<string name="hint_length">pituus</string> <string name="hint_pass">salasana</string>
<string name="hint_pass">salasana</string> <string name="password">Salasana</string>
<string name="password">Salasana</string> <string name="install_from_play_store">Asenna Play Storesta</string>
<string name="install_from_play_store">Asenna Play Storesta</string> <string name="install_from_f_droid">Asenna F-Droid</string>
<string name="install_from_f_droid">Asenna F-Droid</string> <string name="invalid_credentials">Väärä salasana tai avaintiedosto.</string>
<string name="invalid_credentials">Väärä salasana tai avaintiedosto.</string> <string name="invalid_algorithm">Epäkelpo algoritmi.</string>
<string name="invalid_algorithm">Epäkelpo algoritmi.</string> <string name="invalid_db_sig">Salasanatietokannan tyyppiä ei tunnistettu.</string>
<string name="invalid_db_sig">Salasanatietokannan tyyppiä ei tunnistettu.</string> <string name="keyfile_is_empty">Avaintiedosto on tyhjä.</string>
<string name="keyfile_is_empty">Avaintiedosto on tyhjä.</string> <string name="length">Pituus</string>
<string name="length">Pituus</string> <string name="list_size_title">Ryhmälistan pituus</string>
<string name="list_size_title">Ryhmälistan pituus</string> <string name="list_size_summary">Tekstin koko ryhmälistauksessa</string>
<string name="list_size_summary">Tekstin koko ryhmälistauksessa</string> <string name="loading_database">Ladataan salasanatietokantaa&#8230;</string>
<string name="loading_database">Ladataan salasanatietokantaa&#8230;</string> <string name="lowercase">pienet kirjaimet</string>
<string name="lowercase">pienet kirjaimet</string> <string name="hide_password_title">Piilota salasaan</string>
<string name="hide_password_title">Piilota salasaan</string> <string name="hide_password_summary">Piilota salasanat oletuksena</string>
<string name="hide_password_summary">Piilota salasanat oletuksena</string> <string name="about">Tietoa</string>
<string name="about">Tietoa</string> <string name="menu_change_key_settings">Vaihda pääsalasanaa</string>
<string name="menu_change_key_settings">Vaihda pääsalasanaa</string> <string name="settings">Asetukset</string>
<string name="settings">Asetukset</string> <string name="menu_database_settings">Salasanatietokannan asetukset</string>
<string name="menu_database_settings">Salasanatietokannan asetukset</string> <string name="menu_delete">Poista</string>
<string name="menu_delete">Poista</string> <string name="menu_donate">Lahjoita</string>
<string name="menu_donate">Lahjoita</string> <string name="menu_edit">Muokkaa</string>
<string name="menu_edit">Muokkaa</string> <string name="menu_hide_password">Piilota salasana</string>
<string name="menu_hide_password">Piilota salasana</string> <string name="menu_lock">Lukitse salasanatietokanta</string>
<string name="menu_lock">Lukitse salasanatietokanta</string> <string name="menu_open">Avaa</string>
<string name="menu_open">Avaa</string> <string name="menu_search">Etsi</string>
<string name="menu_search">Etsi</string> <string name="menu_showpass">Näytä salasana</string>
<string name="menu_showpass">Näytä salasana</string> <string name="menu_url">Mene URL-osoitteeseen</string>
<string name="menu_url">Mene URL-osoitteeseen</string> <string name="minus">Miinus</string>
<string name="minus">Miinus</string> <string name="never">Ei koskaan</string>
<string name="never">Ei koskaan</string> <string name="no_results">Ei hakutuloksia</string>
<string name="no_results">Ei hakutuloksia</string> <string name="no_url_handler">Tälle URL:lle ei ole käsittelijää.</string>
<string name="no_url_handler">Tälle URL:lle ei ole käsittelijää.</string> <string name="open_recent">Avaa viimeisin salasanatietokanta :</string>
<string name="open_recent">Avaa viimeisin salasanatietokanta :</string> <string name="omit_backup_search_title">Älä etsi varmuuskopioista eikä roskakorista</string>
<string name="omit_backup_search_title">Älä etsi varmuuskopioista eikä roskakorista</string> <string name="omit_backup_search_summary">Poista \'Varmuuskopiot\' ja roskakori hakutuloksista</string>
<string name="omit_backup_search_summary">Poista \'Varmuuskopiot\' ja roskakori hakutuloksista</string> <string name="progress_create">Luodaan uutta tietokantaa&#8230;</string>
<string name="progress_create">Luodaan uutta tietokantaa&#8230;</string> <string name="progress_title">Työskennellään&#8230;</string>
<string name="progress_title">Työskennellään&#8230;</string> <string name="protection">Suojaus</string>
<string name="protection">Suojaus</string> <string name="content_description_remove_from_list">Poista</string>
<string name="content_description_remove_from_list">Poista</string> <string name="encryption_rijndael">Rijndael (AES)</string>
<string name="encryption_rijndael">Rijndael (AES)</string> <string name="root">Juuri</string>
<string name="root">Juuri</string> <string name="rounds">Salauskierroksia</string>
<string name="rounds">Salauskierroksia</string> <string name="rounds_explanation">Suurempi kierrosten määrä parantaa suojausta raa\'alla voimalla tehdyiltä murtoyrityksiltä, mutta voi todella hidastaa lataamista ja tallentamista.</string>
<string name="rounds_explanation">Suurempi kierrosten määrä parantaa suojausta raa\'alla voimalla tehdyiltä murtoyrityksiltä, mutta voi todella hidastaa lataamista ja tallentamista.</string> <string name="saving_database">Tallennetaan tietokantaa&#8230;</string>
<string name="saving_database">Tallennetaan tietokantaa&#8230;</string> <string name="space">Tila</string>
<string name="space">Tila</string> <string name="search_label">Etsi</string>
<string name="search_label">Etsi</string> <string name="sort_db">Tietokannan lajittelujärjestys</string>
<string name="sort_db">Tietokannan lajittelujärjestys</string> <string name="special">Erityistä</string>
<string name="special">Erityistä</string> <string name="search">Tietueen otsikko/kuvaus</string>
<string name="search">Tietueen otsikko/kuvaus</string> <string name="search_results">Hakutulokset</string>
<string name="search_results">Hakutulokset</string> <string name="encryption_twofish">Twofish</string>
<string name="encryption_twofish">Twofish</string> <string name="underline">Alleviivattu</string>
<string name="underline">Alleviivattu</string> <string name="unsupported_db_version">Ei-tuettu salasanatietokannan versio.</string>
<string name="unsupported_db_version">Ei-tuettu salasanatietokannan versio.</string> <string name="uppercase">Isot kirjaimet</string>
<string name="uppercase">Isot kirjaimet</string> <string name="warning_unmounted">SD-korttia ei löydy. Et voi ladata tai tallentaa salasanatietokantaa.</string>
<string name="warning_unmounted">SD-korttia ei löydy. Et voi ladata tai tallentaa salasanatietokantaa.</string> <string name="version_label">Versio %1$s</string>
<string name="version_label">Versio %1$s</string>
<string name="education_unlock_summary">Syötä salasana ja/tai avaintiedosto avataksesi tietokantasi.</string>
<string name="education_unlock_summary">Syötä salasana ja/tai avaintiedosto avataksesi tietokantasi.</string>
<string-array name="timeout_options">
<string-array name="timeout_options"> <item>5 sekuntia</item>
<item>5 sekuntia</item> <item>10 sekuntia</item>
<item>10 sekuntia</item> <item>20 sekuntia</item>
<item>20 sekuntia</item> <item>30 sekuntia</item>
<item>30 sekuntia</item> <item>1 minuutti</item>
<item>1 minuutti</item> <item>5 minuttia</item>
<item>5 minuttia</item> <item>15 minuttia</item>
<item>15 minuttia</item> <item>30 minuttia</item>
<item>30 minuttia</item> <item>Ei koskaan</item>
<item>Ei koskaan</item> </string-array>
</string-array> <string-array name="list_size_options">
<string-array name="list_size_options"> <item>Pieni</item>
<item>Pieni</item> <item>Keskikokoinen</item>
<item>Keskikokoinen</item> <item>Suuri</item>
<item>Suuri</item> </string-array>
</string-array>
</resources> </resources>

View File

@@ -49,7 +49,7 @@
<string name="decrypting_db">Déchiffrement du contenu de la base de données…</string> <string name="decrypting_db">Déchiffrement du contenu de la base de données…</string>
<string name="default_checkbox">Utiliser comme base de données par défaut</string> <string name="default_checkbox">Utiliser comme base de données par défaut</string>
<string name="digits">Chiffres</string> <string name="digits">Chiffres</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft est &lt;strong&gt;open source&lt;/strong&gt; et &lt;strong&gt;sans publicité&lt;/strong&gt;. Il est fourni tel quel, sous licence &lt;strong&gt;GPLv3&lt;/strong&gt;, sans aucune garantie.</string> <string name="html_about_licence">KeePassDX © %1$d Kunzisoft est &lt;strong&gt;libre&lt;/strong&gt; et &lt;strong&gt;sans publicité&lt;/strong&gt;. \nIl est fourni tel quel, sous la licence &lt;strong&gt;GPLv3&lt;/strong&gt;, sans aucune garantie.</string>
<string name="entry_accessed">Dernier accès</string> <string name="entry_accessed">Dernier accès</string>
<string name="entry_cancel">Annuler</string> <string name="entry_cancel">Annuler</string>
<string name="entry_notes">Notes</string> <string name="entry_notes">Notes</string>
@@ -76,7 +76,6 @@
<string name="error_pass_match">Les mots de passe ne correspondent pas.</string> <string name="error_pass_match">Les mots de passe ne correspondent pas.</string>
<string name="error_rounds_too_large">«Tours de transformation» trop grand. Définition à 2147483648.</string> <string name="error_rounds_too_large">«Tours de transformation» trop grand. Définition à 2147483648.</string>
<string name="error_string_key">Chaque chaîne doit avoir un nom de champ.</string> <string name="error_string_key">Chaque chaîne doit avoir un nom de champ.</string>
<string name="error_title_required">Veuillez ajouter un titre.</string>
<string name="error_wrong_length">Veuillez saisir un entier positif dans le champ «Longueur».</string> <string name="error_wrong_length">Veuillez saisir un entier positif dans le champ «Longueur».</string>
<string name="error_autofill_enable_service">Impossible dactiver le service de remplissage automatique.</string> <string name="error_autofill_enable_service">Impossible dactiver le service de remplissage automatique.</string>
<string name="field_name">Nom du champ</string> <string name="field_name">Nom du champ</string>
@@ -275,7 +274,6 @@
<string name="html_text_dev_feature_upgrade">Noubliez pas de garder votre application à jour en installant les nouvelles versions.</string> <string name="html_text_dev_feature_upgrade">Noubliez pas de garder votre application à jour en installant les nouvelles versions.</string>
<string name="download">Télécharger</string> <string name="download">Télécharger</string>
<string name="contribute">Contribuer</string> <string name="contribute">Contribuer</string>
<!-- Algorithms -->
<string name="encryption_rijndael">Rijndael (AES)</string> <string name="encryption_rijndael">Rijndael (AES)</string>
<string name="encryption_twofish">Twofish</string> <string name="encryption_twofish">Twofish</string>
<string name="encryption_chacha20">ChaCha20</string> <string name="encryption_chacha20">ChaCha20</string>
@@ -367,10 +365,9 @@
<string name="content_description_add_entry">Ajouter une entrée</string> <string name="content_description_add_entry">Ajouter une entrée</string>
<string name="content_description_add_group">Ajouter un groupe</string> <string name="content_description_add_group">Ajouter un groupe</string>
<string name="content_description_entry_icon">Icône de lentrée</string> <string name="content_description_entry_icon">Icône de lentrée</string>
<string name="content_description_entry_save">Enregistrer lentrée</string> <string name="entry_password_generator">Générateur de mots de passe</string>
<string name="content_description_password_generator">Générateur de mots de passe</string>
<string name="content_description_password_length">Longueur de mot de passe</string> <string name="content_description_password_length">Longueur de mot de passe</string>
<string name="content_description_add_field">Ajouter un champ</string> <string name="entry_add_field">Ajouter un champ</string>
<string name="content_description_remove_field">Supprimer un champ</string> <string name="content_description_remove_field">Supprimer un champ</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="list_groups_show_number_entries_title">Afficher le nombre dentrées</string> <string name="list_groups_show_number_entries_title">Afficher le nombre dentrées</string>
@@ -422,8 +419,6 @@
<string name="contains_duplicate_uuid_procedure">En validant cette boîte de dialogue, KeePassDX corrigera le problème (en générant de nouveaux UUID pour les doublons) et continuera.</string> <string name="contains_duplicate_uuid_procedure">En validant cette boîte de dialogue, KeePassDX corrigera le problème (en générant de nouveaux UUID pour les doublons) et continuera.</string>
<string name="database_opened">Base de données ouverte</string> <string name="database_opened">Base de données ouverte</string>
<string name="clipboard_explanation_summary">Copie les champs dune entrée à laide du presse-papier de votre appareil</string> <string name="clipboard_explanation_summary">Copie les champs dune entrée à laide du presse-papier de votre appareil</string>
<string name="persistent_notification_title">Notification persistante</string>
<string name="persistent_notification_summary">Ajoute une notification lorsque la base de données est ouverte</string>
<string name="advanced_unlock_explanation_summary">Utilise le déverrouillage avancé pour ouvrir plus facilement une base de données</string> <string name="advanced_unlock_explanation_summary">Utilise le déverrouillage avancé pour ouvrir plus facilement une base de données</string>
<string name="database_data_compression_title">Compression de données</string> <string name="database_data_compression_title">Compression de données</string>
<string name="database_data_compression_summary">La compression des données réduit la taille de la base de données.</string> <string name="database_data_compression_summary">La compression des données réduit la taille de la base de données.</string>
@@ -460,7 +455,7 @@
<string name="keyboard_auto_go_action_summary">Action de la touche Go effectuée automatiquement après avoir appuyé sur une touche de champ</string> <string name="keyboard_auto_go_action_summary">Action de la touche Go effectuée automatiquement après avoir appuyé sur une touche de champ</string>
<string name="download_attachment">Téléchargement %1$s</string> <string name="download_attachment">Téléchargement %1$s</string>
<string name="download_initialization">Initialisation…</string> <string name="download_initialization">Initialisation…</string>
<string name="download_progression">En cours : %1$d&#37;</string> <string name="download_progression">En cours : %1$d%</string>
<string name="download_finalization">Finalisation…</string> <string name="download_finalization">Finalisation…</string>
<string name="download_complete">Terminé ! Appuyer pour ouvrir le fichier.</string> <string name="download_complete">Terminé ! Appuyer pour ouvrir le fichier.</string>
<string name="hide_expired_entries_title">Masquer les entrées expirées</string> <string name="hide_expired_entries_title">Masquer les entrées expirées</string>

View File

@@ -58,7 +58,6 @@
<string name="error_pass_match">पासवर्ड मेल नहीं खाते हैं।</string> <string name="error_pass_match">पासवर्ड मेल नहीं खाते हैं।</string>
<string name="error_rounds_too_large">\"परिवर्तन राउंड\" बहुत अधिक है। 2147483648 पर सेट हो रहा है।</string> <string name="error_rounds_too_large">\"परिवर्तन राउंड\" बहुत अधिक है। 2147483648 पर सेट हो रहा है।</string>
<string name="error_string_key">प्रत्येक स्ट्रिंग में फ़ील्ड नाम होना चाहिए।</string> <string name="error_string_key">प्रत्येक स्ट्रिंग में फ़ील्ड नाम होना चाहिए।</string>
<string name="error_title_required">एक शीर्षक जोड़ें।</string>
<string name="content_description_open_file">फ़ाइल खोलें</string> <string name="content_description_open_file">फ़ाइल खोलें</string>
<string name="content_description_node_children">नोड के बच्चे</string> <string name="content_description_node_children">नोड के बच्चे</string>
<string name="content_description_add_node">नोड जोड़ें</string> <string name="content_description_add_node">नोड जोड़ें</string>
@@ -69,10 +68,9 @@
<string name="content_description_keyfile_checkbox">कीफाइल चेकबॉक्स</string> <string name="content_description_keyfile_checkbox">कीफाइल चेकबॉक्स</string>
<string name="content_description_repeat_toggle_password_visibility">पासवर्ड दृश्यता टॉगल दोहराएं</string> <string name="content_description_repeat_toggle_password_visibility">पासवर्ड दृश्यता टॉगल दोहराएं</string>
<string name="content_description_entry_icon">प्रवेश आइकन</string> <string name="content_description_entry_icon">प्रवेश आइकन</string>
<string name="content_description_entry_save">प्रविष्टि सहेजें</string> <string name="entry_password_generator">पासवर्ड जनरेटर</string>
<string name="content_description_password_generator">पासवर्ड जनरेटर</string>
<string name="content_description_password_length">पासवर्ड की लंबाई</string> <string name="content_description_password_length">पासवर्ड की लंबाई</string>
<string name="content_description_add_field">फ़ील्ड जोड़ें</string> <string name="entry_add_field">फ़ील्ड जोड़ें</string>
<string name="content_description_remove_field">फ़ील्ड निकालें</string> <string name="content_description_remove_field">फ़ील्ड निकालें</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="file_manager_install_description">"डेटाबेस फाइल को बनाने खोलने और सेव करने के लिए आपके फोन में फाइल मैनेजर ऐप होना चाहिए जोकि दिए गए एक्शन को सपोर्ट कर सके ACTION_CREATE_DOCUMENT और ACTION_OPEN_DOCUMENT"</string> <string name="file_manager_install_description">"डेटाबेस फाइल को बनाने खोलने और सेव करने के लिए आपके फोन में फाइल मैनेजर ऐप होना चाहिए जोकि दिए गए एक्शन को सपोर्ट कर सके ACTION_CREATE_DOCUMENT और ACTION_OPEN_DOCUMENT"</string>

View File

@@ -30,10 +30,9 @@
<string name="content_description_add_group">Dodaj grupu</string> <string name="content_description_add_group">Dodaj grupu</string>
<string name="content_description_file_information">Informacije o datoteci</string> <string name="content_description_file_information">Informacije o datoteci</string>
<string name="content_description_entry_icon">Ikona unosa</string> <string name="content_description_entry_icon">Ikona unosa</string>
<string name="content_description_entry_save">Spremi unos</string> <string name="entry_password_generator">Generator lozinke</string>
<string name="content_description_password_generator">Generator lozinke</string>
<string name="content_description_password_length">Duljina lozinke</string> <string name="content_description_password_length">Duljina lozinke</string>
<string name="content_description_add_field">Dodaj polje</string> <string name="entry_add_field">Dodaj polje</string>
<string name="content_description_remove_field">Ukloni polje</string> <string name="content_description_remove_field">Ukloni polje</string>
<string name="content_description_update_from_list">Ažuriraj</string> <string name="content_description_update_from_list">Ažuriraj</string>
<string name="content_description_remove_from_list">Ukloni</string> <string name="content_description_remove_from_list">Ukloni</string>
@@ -73,7 +72,6 @@
<string name="error_nokeyfile">Odaberi datoteku ključa.</string> <string name="error_nokeyfile">Odaberi datoteku ključa.</string>
<string name="error_pass_gen_type">Bar jedan tip generiranja lozinke mora biti odabran.</string> <string name="error_pass_gen_type">Bar jedan tip generiranja lozinke mora biti odabran.</string>
<string name="error_pass_match">Lozinke se ne podudaraju.</string> <string name="error_pass_match">Lozinke se ne podudaraju.</string>
<string name="error_title_required">Dodaj naslov.</string>
<string name="error_wrong_length">Unesi pozitivan cijeli broj u polje \"Duljina\".</string> <string name="error_wrong_length">Unesi pozitivan cijeli broj u polje \"Duljina\".</string>
<string name="error_otp_secret_key">Tajni ključ mora biti u Base32 formatu.</string> <string name="error_otp_secret_key">Tajni ključ mora biti u Base32 formatu.</string>
<string name="error_otp_counter">Brojač mora biti između %1$d i %2$d.</string> <string name="error_otp_counter">Brojač mora biti između %1$d i %2$d.</string>
@@ -184,8 +182,6 @@
<string name="clipboard_warning">Ako automatsko brisanje međuspremnika ne uspije, izbrišite njegovu povijest ručno.</string> <string name="clipboard_warning">Ako automatsko brisanje međuspremnika ne uspije, izbrišite njegovu povijest ručno.</string>
<string name="lock_database_screen_off_summary">Zaključaj bazu podataka kada je ekran ugašen</string> <string name="lock_database_screen_off_summary">Zaključaj bazu podataka kada je ekran ugašen</string>
<string name="lock_database_back_root_title">Pritisni \'Natrag\' za zaključavanje</string> <string name="lock_database_back_root_title">Pritisni \'Natrag\' za zaključavanje</string>
<string name="persistent_notification_title">Trajna obavijest</string>
<string name="persistent_notification_summary">Dodaj obavijest kada je baza podataka otvorena</string>
<string name="advanced_unlock">Napredno otključavanje</string> <string name="advanced_unlock">Napredno otključavanje</string>
<string name="advanced_unlock_explanation_summary">Koristite napredno otključavanje za jednostavnije otvaranje baze podataka</string> <string name="advanced_unlock_explanation_summary">Koristite napredno otključavanje za jednostavnije otvaranje baze podataka</string>
<string name="biometric_unlock_enable_title">Biometričko otključavanje</string> <string name="biometric_unlock_enable_title">Biometričko otključavanje</string>

View File

@@ -71,7 +71,6 @@
<string name="error_pass_match">A jelszavak nem egyeznek meg.</string> <string name="error_pass_match">A jelszavak nem egyeznek meg.</string>
<string name="error_rounds_too_large">A „Transzformációs körök” száma túl nagy. Beállítás 2147483648-ra.</string> <string name="error_rounds_too_large">A „Transzformációs körök” száma túl nagy. Beállítás 2147483648-ra.</string>
<string name="error_string_key">Minden karakterlánchoz szükséges egy mezőnév.</string> <string name="error_string_key">Minden karakterlánchoz szükséges egy mezőnév.</string>
<string name="error_title_required">Adjon hozzá egy címet.</string>
<string name="error_wrong_length">Írjon be egy pozitív egész számot a „Hossz” mezőbe.</string> <string name="error_wrong_length">Írjon be egy pozitív egész számot a „Hossz” mezőbe.</string>
<string name="field_name">Mezőnév</string> <string name="field_name">Mezőnév</string>
<string name="field_value">Mezőérték</string> <string name="field_value">Mezőérték</string>

View File

@@ -27,14 +27,14 @@
<string name="add_group">Aggiungi gruppo</string> <string name="add_group">Aggiungi gruppo</string>
<string name="encryption_algorithm">Algoritmo di cifratura</string> <string name="encryption_algorithm">Algoritmo di cifratura</string>
<string name="app_timeout">Scadenza app</string> <string name="app_timeout">Scadenza app</string>
<string name="app_timeout_summary">Inattività prima del blocco dell\'app</string> <string name="app_timeout_summary">Tempo di inattività prima del blocco dell\'app</string>
<string name="application">App</string> <string name="application">App</string>
<string name="menu_app_settings">Impostazioni app</string> <string name="menu_app_settings">Impostazioni app</string>
<string name="brackets">Parentesi</string> <string name="brackets">Parentesi</string>
<string name="file_manager_install_description">Sfoglia i file installando il Gestore File di OpenIntents</string> <string name="file_manager_install_description">È necessario un file manager che accetti gli Intent ACTION_CREATE_DOCUMENT e ACTION_OPEN_DOCUMENT per creare, aprire e salvare i file di database.</string>
<string name="clipboard_cleared">Appunti eliminati</string> <string name="clipboard_cleared">Appunti eliminati</string>
<string name="clipboard_error_title">Errore negli appunti</string> <string name="clipboard_error_title">Errore negli appunti</string>
<string name="clipboard_error">Alcuni telefoni Android di Samsung non permettono alle app di usare gli appunti.</string> <string name="clipboard_error">Alcuni dispositivi non permettono alle app di usare gli appunti.</string>
<string name="clipboard_error_clear">Eliminazione degli appunti fallita</string> <string name="clipboard_error_clear">Eliminazione degli appunti fallita</string>
<string name="clipboard_timeout">Scadenza appunti</string> <string name="clipboard_timeout">Scadenza appunti</string>
<string name="clipboard_timeout_summary">Tempo prima di eliminare gli appunti</string> <string name="clipboard_timeout_summary">Tempo prima di eliminare gli appunti</string>
@@ -44,7 +44,8 @@
<string name="decrypting_db">Decodifica contenuto database…</string> <string name="decrypting_db">Decodifica contenuto database…</string>
<string name="default_checkbox">Usa come database predefinito</string> <string name="default_checkbox">Usa come database predefinito</string>
<string name="digits">Numeri</string> <string name="digits">Numeri</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft viene distribuito assolutamente con nessuna garanzia. Si tratta di software libero e sei invitato a distribuirlo sotto le condizioni della licenza GPL versione 3 o successiva.</string> <string name="html_about_licence">KeePassDX © %1$d Kunzisoft è un programma &lt;strong&gt;open source&lt;/strong&gt; e &lt;strong&gt;senza pubblicità&lt;/strong&gt;.
\nViene distribuito sotto le condizioni della licenza &lt;strong&gt;GPL versione 3&lt;/strong&gt; o successiva, senza alcuna garanzia.</string>
<string name="entry_notes">Note</string> <string name="entry_notes">Note</string>
<string name="select_database_file">Apri un database esistente</string> <string name="select_database_file">Apri un database esistente</string>
<string name="entry_accessed">Ultimo accesso</string> <string name="entry_accessed">Ultimo accesso</string>
@@ -71,7 +72,6 @@
<string name="error_pass_match">Le password non corrispondono.</string> <string name="error_pass_match">Le password non corrispondono.</string>
<string name="error_rounds_too_large">\"Livello\" troppo alto. Impostato a 2147483648.</string> <string name="error_rounds_too_large">\"Livello\" troppo alto. Impostato a 2147483648.</string>
<string name="error_string_key">Ogni stringa deve avere un nome.</string> <string name="error_string_key">Ogni stringa deve avere un nome.</string>
<string name="error_title_required">Aggiungi un titolo.</string>
<string name="error_wrong_length">Inserisci un numero naturale positivo nel campo \"lunghezza\".</string> <string name="error_wrong_length">Inserisci un numero naturale positivo nel campo \"lunghezza\".</string>
<string name="field_name">Nome campo</string> <string name="field_name">Nome campo</string>
<string name="field_value">Valore campo</string> <string name="field_value">Valore campo</string>
@@ -81,13 +81,13 @@
<string name="hint_conf_pass">conferma password</string> <string name="hint_conf_pass">conferma password</string>
<string name="hint_generated_password">password generata</string> <string name="hint_generated_password">password generata</string>
<string name="hint_group_name">Nome gruppo</string> <string name="hint_group_name">Nome gruppo</string>
<string name="hint_keyfile">file chiave</string> <string name="hint_keyfile">File chiave</string>
<string name="hint_length">lunghezza</string> <string name="hint_length">lunghezza</string>
<string name="password">Password</string> <string name="password">Password</string>
<string name="hint_pass">password</string> <string name="hint_pass">password</string>
<string name="install_from_play_store">Installa dal Play Store</string> <string name="install_from_play_store">Installa dal Play Store</string>
<string name="install_from_f_droid">Installa dal F-Droid</string> <string name="install_from_f_droid">Installa dal F-Droid</string>
<string name="invalid_credentials">Password o file chiave non validi.</string> <string name="invalid_credentials">Non è possibile leggere le credenziali. Se questo dovesse riaccadere, il file del databese potrebbe essere corrotto.</string>
<string name="invalid_algorithm">Algoritmo errato.</string> <string name="invalid_algorithm">Algoritmo errato.</string>
<string name="invalid_db_sig">Formato database non riconosciuto.</string> <string name="invalid_db_sig">Formato database non riconosciuto.</string>
<string name="keyfile_is_empty">Il file chiave è vuoto.</string> <string name="keyfile_is_empty">Il file chiave è vuoto.</string>
@@ -139,7 +139,7 @@
<string name="uppercase">Maiuscole</string> <string name="uppercase">Maiuscole</string>
<string name="warning">Attenzione</string> <string name="warning">Attenzione</string>
<string name="warning_password_encoding">Evita password con caratteri al di fuori del formato di codifica del testo nel file di database (i caratteri non riconosciuti vengono convertiti nella stessa lettera).</string> <string name="warning_password_encoding">Evita password con caratteri al di fuori del formato di codifica del testo nel file di database (i caratteri non riconosciuti vengono convertiti nella stessa lettera).</string>
<string name="warning_unmounted">Monta la scheda SD per creare o caricare un database.</string> <string name="warning_unmounted">Monta la scheda di memoria per poter creare o caricare un database.</string>
<string name="version_label">Versione %1$s</string> <string name="version_label">Versione %1$s</string>
<string name="configure_biometric">La scansione di impronte è supportata ma non impostata.</string> <string name="configure_biometric">La scansione di impronte è supportata ma non impostata.</string>
<string name="open_biometric_prompt_unlock_database">Scansione impronte</string> <string name="open_biometric_prompt_unlock_database">Scansione impronte</string>
@@ -237,7 +237,7 @@
<string name="full_file_path_enable_title">Percorso file</string> <string name="full_file_path_enable_title">Percorso file</string>
<string name="full_file_path_enable_summary">Visualizza il percorso file completo</string> <string name="full_file_path_enable_summary">Visualizza il percorso file completo</string>
<string name="recycle_bin_title">Usa il cestino</string> <string name="recycle_bin_title">Usa il cestino</string>
<string name="recycle_bin_summary">Sposta gruppi ed elementi nel cestino prima di eliminare</string> <string name="recycle_bin_summary">Sposta i gruppi e le voci nel gruppo \"Cestino\" prima di eliminarlo</string>
<string name="monospace_font_fields_enable_title">Carattere campi</string> <string name="monospace_font_fields_enable_title">Carattere campi</string>
<string name="monospace_font_fields_enable_summary">Cambia il carattere usato nei campi per una migliore visibilità</string> <string name="monospace_font_fields_enable_summary">Cambia il carattere usato nei campi per una migliore visibilità</string>
<string name="allow_copy_password_title">Fiducia appunti</string> <string name="allow_copy_password_title">Fiducia appunti</string>
@@ -347,7 +347,7 @@
<string name="keyboard_key_sound_title">Suono alla pressione</string> <string name="keyboard_key_sound_title">Suono alla pressione</string>
<string name="selection_mode">Modalità selezione</string> <string name="selection_mode">Modalità selezione</string>
<string name="do_not_kill_app">Non terminare l\'app…</string> <string name="do_not_kill_app">Non terminare l\'app…</string>
<string name="lock_database_back_root_title">Premere Indietro sulla schermata principale per bloccare</string> <string name="lock_database_back_root_title">Premere \'\'Indietro\'\' per bloccare</string>
<string name="lock_database_back_root_summary">Bloccare il database quando l\'utente preme il pulsante Indietro nella schermata principale</string> <string name="lock_database_back_root_summary">Bloccare il database quando l\'utente preme il pulsante Indietro nella schermata principale</string>
<string name="clear_clipboard_notification_title">Pulisci alla chiusura</string> <string name="clear_clipboard_notification_title">Pulisci alla chiusura</string>
<string name="clear_clipboard_notification_summary">Chiudere il database alla chiusura della notifica</string> <string name="clear_clipboard_notification_summary">Chiudere il database alla chiusura della notifica</string>
@@ -364,17 +364,47 @@
<string name="content_description_file_information">Informazioni sul file</string> <string name="content_description_file_information">Informazioni sul file</string>
<string name="content_description_password_checkbox">Casella di controllo della password</string> <string name="content_description_password_checkbox">Casella di controllo della password</string>
<string name="content_description_keyfile_checkbox">Casella di controllo Keyfile</string> <string name="content_description_keyfile_checkbox">Casella di controllo Keyfile</string>
<string name="content_description_repeat_toggle_password_visibility">Ripeti attivare / disattivare la visibilità della password</string> <string name="content_description_repeat_toggle_password_visibility">Ripeti la richiesta di visibilità della password</string>
<string name="content_description_entry_icon">Icona</string> <string name="content_description_entry_icon">Icona</string>
<string name="content_description_password_generator">Generatore di password</string> <string name="entry_password_generator">Generatore di password</string>
<string name="content_description_password_length">Lunghezza della password</string> <string name="content_description_password_length">Lunghezza della password</string>
<string name="content_description_add_field">Aggiungi un campo</string> <string name="entry_add_field">Aggiungi un campo</string>
<string name="content_description_remove_field">Rimuovi un campo</string> <string name="content_description_remove_field">Rimuovi un campo</string>
<string name="error_move_entry_here">Non è possibile spostare una voce qui.</string> <string name="error_move_entry_here">Non è possibile spostare una voce qui.</string>
<string name="error_copy_entry_here">Non è possibile copiare una voce qui.</string> <string name="error_copy_entry_here">Non è possibile copiare una voce qui.</string>
<string name="list_groups_show_number_entries_title">Mostra il numero di voci</string> <string name="list_groups_show_number_entries_title">Mostra il numero di voci</string>
<string name="list_groups_show_number_entries_summary">Mostra il numero di voci in un gruppo</string> <string name="list_groups_show_number_entries_summary">Mostra il numero di voci in un gruppo</string>
<string name="content_description_entry_save">Salva</string>
<string name="content_description_update_from_list">Aggiorna</string> <string name="content_description_update_from_list">Aggiorna</string>
<string name="content_description_keyboard_close_fields">Chiudi campi</string> <string name="content_description_keyboard_close_fields">Chiudi campi</string>
<string name="security">Sicurezza</string>
<string name="content_description_background">Sfondo</string>
<string name="entry_UUID">Identificativo univoco universale</string>
<string name="error_create_database_file">Impossibile creare un database con questa password e file chiave.</string>
<string name="menu_advanced_unlock_settings">Sblocco avanzato</string>
<string name="entry_history">Cronologia</string>
<string name="entry_setup_otp">Imposta password usa e getta</string>
<string name="otp_type">Tipo di password usa e getta</string>
<string name="otp_secret">Segreto</string>
<string name="otp_period">Periodo (secondi)</string>
<string name="otp_counter">Contatore</string>
<string name="otp_digits">Cifre</string>
<string name="otp_algorithm">Algoritmo</string>
<string name="entry_otp">Password usa e getta</string>
<string name="error_invalid_OTP">Segreto per password usa e getta (OTP) non valido.</string>
<string name="error_disallow_no_credentials">Impostare almeno una credenziale.</string>
<string name="error_copy_group_here">Non puoi copiare un gruppo qui.</string>
<string name="error_otp_secret_key">La chiave segreta deve essere nel formato Base32.</string>
<string name="error_otp_counter">Il contatore deve essere tra %1$d e %2$d.</string>
<string name="error_otp_period">Il periodo deve essere tra %1$d e %2$d secondi.</string>
<string name="error_otp_digits">Il token deve contenere tra %1$d e %2$d cifre.</string>
<string name="invalid_db_same_uuid">%1$s con le stesse credenziali univoche %2$s è già esistente.</string>
<string name="creating_database">Sto creando il database…</string>
<string name="menu_security_settings">Impostazioni di sicurezza</string>
<string name="contains_duplicate_uuid">Il databse contiene identificativi univoci univerali duplicati.</string>
<string name="error_save_database">Non è possibile salvare il database.</string>
<string name="menu_save_database">Salva il database</string>
<string name="menu_empty_recycle_bin">Svuota il cestino</string>
<string name="command_execution">Esecuzione del comando…</string>
<string name="warning_permanently_delete_nodes">Sei sicuro di voler eliminare definitivamente i nodi selezionati\?</string>
<string name="entry_attachments">Allegati</string>
</resources> </resources>

View File

@@ -69,7 +69,6 @@
<string name="error_pass_match">הסיסמאות לא תואמות.</string> <string name="error_pass_match">הסיסמאות לא תואמות.</string>
<string name="error_rounds_too_large">מספר סיבובים גדול מדי. מגדיר ל-2147483648.</string> <string name="error_rounds_too_large">מספר סיבובים גדול מדי. מגדיר ל-2147483648.</string>
<string name="error_string_key">שדה שם נדרש לכל מחרוזת.</string> <string name="error_string_key">שדה שם נדרש לכל מחרוזת.</string>
<string name="error_title_required">כותרת נדרשת.</string>
<string name="error_wrong_length">הזן מספר חיובי בשדה האורך</string> <string name="error_wrong_length">הזן מספר חיובי בשדה האורך</string>
<string name="field_name">שם השדה</string> <string name="field_name">שם השדה</string>
<string name="field_value">ערך השדה</string> <string name="field_value">ערך השדה</string>

View File

@@ -65,7 +65,6 @@
<string name="error_pass_gen_type">少なくとも1つ以上のパスワード生成タイプを選択する必要があります。</string> <string name="error_pass_gen_type">少なくとも1つ以上のパスワード生成タイプを選択する必要があります。</string>
<string name="error_pass_match">パスワードが一致しません</string> <string name="error_pass_match">パスワードが一致しません</string>
<string name="error_rounds_too_large">値が大きすぎます。 2147483648にセットしました。</string> <string name="error_rounds_too_large">値が大きすぎます。 2147483648にセットしました。</string>
<string name="error_title_required">タイトルは必須入力です。</string>
<string name="error_wrong_length">\"長さ\"欄には正の整数を入力してください。</string> <string name="error_wrong_length">\"長さ\"欄には正の整数を入力してください。</string>
<string name="file_browser">ファイルブラウザ</string> <string name="file_browser">ファイルブラウザ</string>
<string name="generate_password">パスワードを生成する</string> <string name="generate_password">パスワードを生成する</string>
@@ -194,10 +193,9 @@
<string name="content_description_add_group">グループの追加</string> <string name="content_description_add_group">グループの追加</string>
<string name="content_description_file_information">ファイル情報</string> <string name="content_description_file_information">ファイル情報</string>
<string name="content_description_entry_icon">エントリーのアイコン</string> <string name="content_description_entry_icon">エントリーのアイコン</string>
<string name="content_description_entry_save">エントリーの保存</string> <string name="entry_password_generator">パスワード生成</string>
<string name="content_description_password_generator">パスワード生成</string>
<string name="content_description_password_length">パスワードの長さ</string> <string name="content_description_password_length">パスワードの長さ</string>
<string name="content_description_add_field">フィールドの追加</string> <string name="entry_add_field">フィールドの追加</string>
<string name="content_description_remove_field">フィールドの削除</string> <string name="content_description_remove_field">フィールドの削除</string>
<string name="error_move_entry_here">エントリーを移動できませんでした。</string> <string name="error_move_entry_here">エントリーを移動できませんでした。</string>
<string name="error_copy_entry_here">エントリーをコピーできませんでした。</string> <string name="error_copy_entry_here">エントリーをコピーできませんでした。</string>

View File

@@ -78,7 +78,6 @@
<string name="error_pass_match">비밀번호가 일치하지 않습니다.</string> <string name="error_pass_match">비밀번호가 일치하지 않습니다.</string>
<string name="error_rounds_too_large">\"Transformation rounds\" 가 너무 높습니다. 2147483648로 설정합니다.</string> <string name="error_rounds_too_large">\"Transformation rounds\" 가 너무 높습니다. 2147483648로 설정합니다.</string>
<string name="error_string_key">각 항목은 필드 이름을 가져야 합니다.</string> <string name="error_string_key">각 항목은 필드 이름을 가져야 합니다.</string>
<string name="error_title_required">제목을 입력하십시오.</string>
<string name="error_wrong_length">\"길이\" 필드에는 양수를 입력하십시오.</string> <string name="error_wrong_length">\"길이\" 필드에는 양수를 입력하십시오.</string>
<string name="error_autofill_enable_service">자동 채우기 서비스를 활성화할 수 없습니다.</string> <string name="error_autofill_enable_service">자동 채우기 서비스를 활성화할 수 없습니다.</string>
<string name="error_move_folder_in_itself">그룹을 자신에게 옮길 수 없습니다.</string> <string name="error_move_folder_in_itself">그룹을 자신에게 옮길 수 없습니다.</string>
@@ -164,9 +163,9 @@
<string name="content_description_password_checkbox">비밀번호 체크박스</string> <string name="content_description_password_checkbox">비밀번호 체크박스</string>
<string name="content_description_keyfile_checkbox">내용_설명_키파일_체크박스</string> <string name="content_description_keyfile_checkbox">내용_설명_키파일_체크박스</string>
<string name="content_description_repeat_toggle_password_visibility">토글 비밀번호 가시성 반복</string> <string name="content_description_repeat_toggle_password_visibility">토글 비밀번호 가시성 반복</string>
<string name="content_description_password_generator">비밀번호 생성</string> <string name="entry_password_generator">비밀번호 생성</string>
<string name="content_description_password_length">비밀번호 길이</string> <string name="content_description_password_length">비밀번호 길이</string>
<string name="content_description_add_field">필드 추가</string> <string name="entry_add_field">필드 추가</string>
<string name="content_description_remove_field">필드 제거</string> <string name="content_description_remove_field">필드 제거</string>
<string name="error_move_entry_here">항목을 여기로 옮길 수 없습니다.</string> <string name="error_move_entry_here">항목을 여기로 옮길 수 없습니다.</string>
<string name="error_copy_entry_here">항목을 여기로 복사할 수 없습니다.</string> <string name="error_copy_entry_here">항목을 여기로 복사할 수 없습니다.</string>

View File

@@ -52,7 +52,6 @@
<string name="error_pass_match">Paroles nesakrīt.</string> <string name="error_pass_match">Paroles nesakrīt.</string>
<string name="error_rounds_too_large">Līmenis pārāk liels. Maksimālais 2147483648</string> <string name="error_rounds_too_large">Līmenis pārāk liels. Maksimālais 2147483648</string>
<string name="error_string_key">A field name is required for each string.</string> <string name="error_string_key">A field name is required for each string.</string>
<string name="error_title_required">Nepieciešams nosaukums.</string>
<string name="error_wrong_length">Norādiet garumu lielāku par nulli</string> <string name="error_wrong_length">Norādiet garumu lielāku par nulli</string>
<string name="field_name">Lauka nosaukums</string> <string name="field_name">Lauka nosaukums</string>
<string name="field_value">Lauka vērtība</string> <string name="field_value">Lauka vērtība</string>

View File

@@ -77,7 +77,6 @@
<string name="error_pass_match">Passordene samsvarer ikke.</string> <string name="error_pass_match">Passordene samsvarer ikke.</string>
<string name="error_rounds_too_large">\"Omganger\" er for stort. Setter til 2147483648.</string> <string name="error_rounds_too_large">\"Omganger\" er for stort. Setter til 2147483648.</string>
<string name="error_string_key">Hver streng må ha et feltnavn.</string> <string name="error_string_key">Hver streng må ha et feltnavn.</string>
<string name="error_title_required">En tittel er påkrevd.</string>
<string name="error_wrong_length">Skriv inn et positivt heltall i \"Lengde\"-feltet.</string> <string name="error_wrong_length">Skriv inn et positivt heltall i \"Lengde\"-feltet.</string>
<string name="error_autofill_enable_service">Autofyll-tjenesten kan ikke skrus på.</string> <string name="error_autofill_enable_service">Autofyll-tjenesten kan ikke skrus på.</string>
<string name="error_move_folder_in_itself">Kan ikke flytte gruppe inn i seg selv.</string> <string name="error_move_folder_in_itself">Kan ikke flytte gruppe inn i seg selv.</string>
@@ -342,9 +341,9 @@
<string name="content_description_add_entry">Legg til oppføring</string> <string name="content_description_add_entry">Legg til oppføring</string>
<string name="content_description_add_group">Legg til gruppe</string> <string name="content_description_add_group">Legg til gruppe</string>
<string name="content_description_file_information">Filinfo</string> <string name="content_description_file_information">Filinfo</string>
<string name="content_description_password_generator">Passordgenerator</string> <string name="entry_password_generator">Passordgenerator</string>
<string name="content_description_password_length">Passordslengde</string> <string name="content_description_password_length">Passordslengde</string>
<string name="content_description_add_field">Legg til felt</string> <string name="entry_add_field">Legg til felt</string>
<string name="content_description_remove_field">Fjern felt</string> <string name="content_description_remove_field">Fjern felt</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Du kan ikke flytte en oppføring hit.</string> <string name="error_move_entry_here">Du kan ikke flytte en oppføring hit.</string>
@@ -389,8 +388,6 @@
<string name="menu_security_settings">Sikkerhetsinnstillinger</string> <string name="menu_security_settings">Sikkerhetsinnstillinger</string>
<string name="menu_master_key_settings">Hovednøkkelinnstillinger</string> <string name="menu_master_key_settings">Hovednøkkelinnstillinger</string>
<string name="contains_duplicate_uuid">Databasen inneholder dupliserte UUID-er.</string> <string name="contains_duplicate_uuid">Databasen inneholder dupliserte UUID-er.</string>
<string name="persistent_notification_title">Vedvarende merknad</string>
<string name="persistent_notification_summary">Legg til en merknad når databasen er åpen</string>
<string name="database_data_compression_title">Datakomprimering</string> <string name="database_data_compression_title">Datakomprimering</string>
<string name="database_data_compression_summary">Datakomprimering reduserer databasens størrelse.</string> <string name="database_data_compression_summary">Datakomprimering reduserer databasens størrelse.</string>
<string name="compression">Komprimering</string> <string name="compression">Komprimering</string>
@@ -400,7 +397,6 @@
<string name="menu_empty_recycle_bin">Tøm papirkurv</string> <string name="menu_empty_recycle_bin">Tøm papirkurv</string>
<string name="command_execution">Kjører kommandoen…</string> <string name="command_execution">Kjører kommandoen…</string>
<string name="content_description_node_children">Undernoder</string> <string name="content_description_node_children">Undernoder</string>
<string name="content_description_entry_save">Lagre oppføring</string>
<string name="database_default_username_title">Forvalgt brukernavn</string> <string name="database_default_username_title">Forvalgt brukernavn</string>
<string name="database_custom_color_title">Tilpasset databasefarge</string> <string name="database_custom_color_title">Tilpasset databasefarge</string>
<string name="recycle_bin_group_title">Papirkurvsgruppe</string> <string name="recycle_bin_group_title">Papirkurvsgruppe</string>

View File

@@ -67,7 +67,6 @@
<string name="error_pass_gen_type">Je moet minimaal één soort wachtwoordgenerering kiezen.</string> <string name="error_pass_gen_type">Je moet minimaal één soort wachtwoordgenerering kiezen.</string>
<string name="error_pass_match">De wachtwoorden komen niet overeen.</string> <string name="error_pass_match">De wachtwoorden komen niet overeen.</string>
<string name="error_rounds_too_large">\"Cycli-waarde\" te groot. Wordt ingesteld op 2147483648.</string> <string name="error_rounds_too_large">\"Cycli-waarde\" te groot. Wordt ingesteld op 2147483648.</string>
<string name="error_title_required">Voeg een titel toe.</string>
<string name="error_wrong_length">Voer een positief geheel getal in in het veld \"Lengte\".</string> <string name="error_wrong_length">Voer een positief geheel getal in in het veld \"Lengte\".</string>
<string name="file_browser">Bestandsverkenner</string> <string name="file_browser">Bestandsverkenner</string>
<string name="generate_password">Wachtwoord genereren</string> <string name="generate_password">Wachtwoord genereren</string>
@@ -368,10 +367,9 @@
<string name="content_description_keyfile_checkbox">Sleutelbestandcheckbox</string> <string name="content_description_keyfile_checkbox">Sleutelbestandcheckbox</string>
<string name="content_description_repeat_toggle_password_visibility">Weergave van het wachtwoord wisselen</string> <string name="content_description_repeat_toggle_password_visibility">Weergave van het wachtwoord wisselen</string>
<string name="content_description_entry_icon">Item-icoon</string> <string name="content_description_entry_icon">Item-icoon</string>
<string name="content_description_entry_save">Item opslaan</string> <string name="entry_password_generator">Wachtwoordgenerator</string>
<string name="content_description_password_generator">Wachtwoordgenerator</string>
<string name="content_description_password_length">Wachtwoordlengte</string> <string name="content_description_password_length">Wachtwoordlengte</string>
<string name="content_description_add_field">Veld toevoegen</string> <string name="entry_add_field">Veld toevoegen</string>
<string name="content_description_remove_field">Veld verwijderen</string> <string name="content_description_remove_field">Veld verwijderen</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Je kan hier geen item plaatsen.</string> <string name="error_move_entry_here">Je kan hier geen item plaatsen.</string>
@@ -418,8 +416,6 @@
<string name="contains_duplicate_uuid_procedure">Door dit dialoogvenster te valideren, zal KeePassDX het probleem oplossen (door nieuwe UUID\'s voor duplicaten te genereren) en doorgaan.</string> <string name="contains_duplicate_uuid_procedure">Door dit dialoogvenster te valideren, zal KeePassDX het probleem oplossen (door nieuwe UUID\'s voor duplicaten te genereren) en doorgaan.</string>
<string name="database_opened">Database geopend</string> <string name="database_opened">Database geopend</string>
<string name="clipboard_explanation_summary">Kopieer invoervelden met behulp van het klembord van uw apparaat</string> <string name="clipboard_explanation_summary">Kopieer invoervelden met behulp van het klembord van uw apparaat</string>
<string name="persistent_notification_title">Aanhoudende melding</string>
<string name="persistent_notification_summary">Voeg een melding toe wanneer de database is geopend</string>
<string name="advanced_unlock_explanation_summary">Geavanceerde ontgrendeling gebruiken om een database gemakkelijker te openen</string> <string name="advanced_unlock_explanation_summary">Geavanceerde ontgrendeling gebruiken om een database gemakkelijker te openen</string>
<string name="database_data_compression_title">Gegevenscompressie</string> <string name="database_data_compression_title">Gegevenscompressie</string>
<string name="database_data_compression_summary">Gegevenscompressie verkleint de omvang van de database.</string> <string name="database_data_compression_summary">Gegevenscompressie verkleint de omvang van de database.</string>

View File

@@ -66,7 +66,6 @@
<string name="error_pass_gen_type">Du må velja minst éin passordlagingstype</string> <string name="error_pass_gen_type">Du må velja minst éin passordlagingstype</string>
<string name="error_pass_match">Passorda samsvarer ikkje.</string> <string name="error_pass_match">Passorda samsvarer ikkje.</string>
<string name="error_rounds_too_large">For mange omgangar. Bruker 2147483648.</string> <string name="error_rounds_too_large">For mange omgangar. Bruker 2147483648.</string>
<string name="error_title_required">Treng ein tittel.</string>
<string name="error_wrong_length">Bruk eit positivt heiltal i lengdfeltet</string> <string name="error_wrong_length">Bruk eit positivt heiltal i lengdfeltet</string>
<string name="file_browser">Filbehandlar</string> <string name="file_browser">Filbehandlar</string>
<string name="generate_password">Lag passord</string> <string name="generate_password">Lag passord</string>

View File

@@ -64,7 +64,6 @@
<string name="error_pass_gen_type">Należy wybrać co najmniej jeden rodzaj generowania hasła.</string> <string name="error_pass_gen_type">Należy wybrać co najmniej jeden rodzaj generowania hasła.</string>
<string name="error_pass_match">Hasła nie pasują do siebie.</string> <string name="error_pass_match">Hasła nie pasują do siebie.</string>
<string name="error_rounds_too_large">\"Rundy szyfrowania\" są zbyt wysokie. Ustaw na 2147483648.</string> <string name="error_rounds_too_large">\"Rundy szyfrowania\" są zbyt wysokie. Ustaw na 2147483648.</string>
<string name="error_title_required">Dodaj tytuł.</string>
<string name="error_wrong_length">Wprowadź dodatnią liczbę całkowitą w polu \"Długość\".</string> <string name="error_wrong_length">Wprowadź dodatnią liczbę całkowitą w polu \"Długość\".</string>
<string name="file_browser">Przeglądarka plików</string> <string name="file_browser">Przeglądarka plików</string>
<string name="generate_password">Generuj hasło</string> <string name="generate_password">Generuj hasło</string>
@@ -153,7 +152,8 @@
<string name="clipboard_error">Niektóre urządzenia nie pozwalają aplikacjom korzystać ze schowka.</string> <string name="clipboard_error">Niektóre urządzenia nie pozwalają aplikacjom korzystać ze schowka.</string>
<string name="clipboard_error_clear">Nie można wyczyścić schowka</string> <string name="clipboard_error_clear">Nie można wyczyścić schowka</string>
<string name="clipboard_swipe_clean">Przesuń, by wyczyścić schowek</string> <string name="clipboard_swipe_clean">Przesuń, by wyczyścić schowek</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft korzystasz absolutnie bez gwarancji. To jest bezpłatne oprogramowanie i możesz go redystrybuować na warunkach GPL w wersji 3 lub późniejszej.</string> <string name="html_about_licence">KeePassDX © %1 $d Kunzisoft jest &lt;strong&gt;open source&lt;/strong&gt; i &lt;strong&gt;bez reklam&lt;/strong&gt;.
\nJest on dostarczany w stanie, zgodnie z licencją &lt;strong&gt;GPLv3&lt;/strong&gt; bez żadnych gwarancji.</string>
<string name="entry_not_found">Nie znaleziono danych wejściowych.</string> <string name="entry_not_found">Nie znaleziono danych wejściowych.</string>
<string name="error_load_database">Nie można załadować bazy danych.</string> <string name="error_load_database">Nie można załadować bazy danych.</string>
<string name="error_load_database_KDF_memory">Nie można załadować klucza. Spróbuj zmniejszyć użycie pamięć KDF.</string> <string name="error_load_database_KDF_memory">Nie można załadować klucza. Spróbuj zmniejszyć użycie pamięć KDF.</string>
@@ -284,7 +284,7 @@
<string name="education_generate_password_title">Utwórz silne hasło do swojego wpisu.</string> <string name="education_generate_password_title">Utwórz silne hasło do swojego wpisu.</string>
<string name="education_generate_password_summary">Wygeneruj silne hasło, które będzie kojarzyć się z Twoim wpisem, łatwo zdefiniuj je zgodnie z kryteriami formularza i nie zapomnij o bezpiecznym haśle.</string> <string name="education_generate_password_summary">Wygeneruj silne hasło, które będzie kojarzyć się z Twoim wpisem, łatwo zdefiniuj je zgodnie z kryteriami formularza i nie zapomnij o bezpiecznym haśle.</string>
<string name="education_entry_new_field_title">Dodaj niestandardowe pola</string> <string name="education_entry_new_field_title">Dodaj niestandardowe pola</string>
<string name="education_entry_new_field_summary">Zarejestruj podstawowe pole niedostarczone, wypełniając nowe pole, które możesz również chronić.</string> <string name="education_entry_new_field_summary">Zarejestruj dodatkowe pole, dodaj wartość i opcjonalnie chroń je.</string>
<string name="education_unlock_title">Odblokuj swoją bazę danych</string> <string name="education_unlock_title">Odblokuj swoją bazę danych</string>
<string name="education_read_only_title">Zapisz ochronę swojej bazy danych</string> <string name="education_read_only_title">Zapisz ochronę swojej bazy danych</string>
<string name="education_read_only_summary">Zmień tryb otwierania sesji. <string name="education_read_only_summary">Zmień tryb otwierania sesji.
@@ -301,7 +301,7 @@
<string name="education_sort_summary">Wybierz sposób sortowania wpisów i grup.</string> <string name="education_sort_summary">Wybierz sposób sortowania wpisów i grup.</string>
<string name="education_donation_title">Weź udział</string> <string name="education_donation_title">Weź udział</string>
<string name="education_donation_summary">Pomóż zwiększyć stabilność, bezpieczeństwo i dodawanie kolejnych funkcji.</string> <string name="education_donation_summary">Pomóż zwiększyć stabilność, bezpieczeństwo i dodawanie kolejnych funkcji.</string>
<string name="html_text_ad_free">W przeciwieństwie do wielu aplikacji do zarządzania hasłami, ta jest &lt;strong&gt;wolna od reklam&lt;/strong&gt;, &lt;strong&gt;open source&lt;/strong&gt; i na licencji &lt;strong&gt;licencjonowanie copyleftted&lt;/strong&gt;. &lt;strong&gt;Żadne dane osobowe nie są gromadzone&lt;/strong&gt;, w jakiejkolwiek formie, bez względu na to, z której wersji (bezpłatnej lub pro) korzystasz.</string> <string name="html_text_ad_free">W przeciwieństwie do wielu aplikacji do zarządzania hasłami, ta jest wolna od &lt;strong&gt;reklam&lt;/strong&gt;, &lt;strong&gt;jest wolnym oprogramowaniem copyleftted&lt;/strong&gt; i nie zbiera danych osobowych na swoich serwerach, bez względu na to, jakiej wersji używasz.</string>
<string name="html_text_buy_pro">Kupując wersję pro, będziesz mieć dostęp do &lt;strong&gt;stylu wizualnego&lt;/strong&gt; a szczególnie pomożesz &lt;strong&gt; zrealizować projekty społecznościowe.&lt;/strong&gt;</string> <string name="html_text_buy_pro">Kupując wersję pro, będziesz mieć dostęp do &lt;strong&gt;stylu wizualnego&lt;/strong&gt; a szczególnie pomożesz &lt;strong&gt; zrealizować projekty społecznościowe.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Ten &lt;strong&gt;styl wizualny&lt;/strong&gt; jest dostępny dzięki Twojej hojności.</string> <string name="html_text_feature_generosity">Ten &lt;strong&gt;styl wizualny&lt;/strong&gt; jest dostępny dzięki Twojej hojności.</string>
<string name="html_text_donation">Aby zachować naszą wolność i być zawsze aktywnym, liczymy na Twój &lt;strong&gt;wkład.&lt;/strong&gt;</string> <string name="html_text_donation">Aby zachować naszą wolność i być zawsze aktywnym, liczymy na Twój &lt;strong&gt;wkład.&lt;/strong&gt;</string>
@@ -355,10 +355,9 @@
<string name="content_description_add_group">Dodaj grupę</string> <string name="content_description_add_group">Dodaj grupę</string>
<string name="content_description_file_information">Informacje o pliku</string> <string name="content_description_file_information">Informacje o pliku</string>
<string name="content_description_entry_icon">Ikona wpisu</string> <string name="content_description_entry_icon">Ikona wpisu</string>
<string name="content_description_entry_save">Zapisz wpis</string> <string name="entry_password_generator">Generator haseł</string>
<string name="content_description_password_generator">Generator haseł</string>
<string name="content_description_password_length">Długość hasła</string> <string name="content_description_password_length">Długość hasła</string>
<string name="content_description_add_field">Dodaj pole</string> <string name="entry_add_field">Dodaj pole</string>
<string name="content_description_remove_field">Usuń pole</string> <string name="content_description_remove_field">Usuń pole</string>
<string name="error_copy_entry_here">Nie możesz tutaj skopiować wpisu.</string> <string name="error_copy_entry_here">Nie możesz tutaj skopiować wpisu.</string>
<string name="list_groups_show_number_entries_title">Pokaż liczbę wpisów</string> <string name="list_groups_show_number_entries_title">Pokaż liczbę wpisów</string>
@@ -402,8 +401,6 @@
<string name="menu_master_key_settings">Ustawienia klucza głównego</string> <string name="menu_master_key_settings">Ustawienia klucza głównego</string>
<string name="contains_duplicate_uuid">Baza danych zawiera zduplikowane identyfikatory UUID.</string> <string name="contains_duplicate_uuid">Baza danych zawiera zduplikowane identyfikatory UUID.</string>
<string name="database_opened">Baza danych otwarta</string> <string name="database_opened">Baza danych otwarta</string>
<string name="persistent_notification_title">Stałe powiadamianie</string>
<string name="persistent_notification_summary">Dodaj powiadomienie, gdy baza danych jest otwarta</string>
<string name="database_data_compression_title">Kompresja danych</string> <string name="database_data_compression_title">Kompresja danych</string>
<string name="max_history_items_summary">Ogranicz liczbę elementów historii na wpis</string> <string name="max_history_items_summary">Ogranicz liczbę elementów historii na wpis</string>
<string name="max_history_size_title">Maksymalny rozmiar</string> <string name="max_history_size_title">Maksymalny rozmiar</string>
@@ -449,9 +446,23 @@
<string name="keyboard_auto_go_action_summary">Działanie klawisza Go wykonywane jest automatycznie po naciśnięciu klawisza Field</string> <string name="keyboard_auto_go_action_summary">Działanie klawisza Go wykonywane jest automatycznie po naciśnięciu klawisza Field</string>
<string name="download_attachment">Pobierz %1$s</string> <string name="download_attachment">Pobierz %1$s</string>
<string name="download_initialization">Inicjowanie…</string> <string name="download_initialization">Inicjowanie…</string>
<string name="download_progression">W trakcie realizacji: %1$d&#37;</string> <string name="download_progression">W trakcie realizacji: %1$d%</string>
<string name="download_finalization">Kończę…</string> <string name="download_finalization">Kończę…</string>
<string name="download_complete">Kompletny! Stuknij, aby otworzyć plik.</string> <string name="download_complete">Kompletny! Stuknij, aby otworzyć plik.</string>
<string name="hide_expired_entries_title">Ukryj wygasłe wpisy</string> <string name="hide_expired_entries_title">Ukryj wygasłe wpisy</string>
<string name="hide_expired_entries_summary">Wygasłe wpisy zostaną ukryte</string> <string name="hide_expired_entries_summary">Wygasłe wpisy zostaną ukryte</string>
<string name="contact">Kontakt</string>
<string name="html_about_contribution">Aby &lt;strong&gt;zachować naszą wolność&lt;/strong&gt;, &lt;strong&gt;sprawdzać błędy&lt;/strong&gt;, &lt;strong&gt;dodać funkcje&lt;/strong&gt; i &lt;strong&gt;by być zawsze aktywnym&lt;/strong&gt;, liczymy na twój &lt;strong&gt;wkład&lt;/strong&gt;.</string>
<string name="auto_focus_search_title">Szybkie wyszukiwanie</string>
<string name="auto_focus_search_summary">Wyszukiwanie po otwarciu bazy danych</string>
<string name="remember_database_locations_title">Zapisz lokalizację baz danych</string>
<string name="remember_database_locations_summary">Zapamiętaj lokalizację baz danych</string>
<string name="remember_keyfile_locations_title">Zapisz lokalizację plików kluczy</string>
<string name="remember_keyfile_locations_summary">Zapamiętaj lokalizację plików kluczy baz danych</string>
<string name="show_recent_files_title">Pokaż najnowsze pliki</string>
<string name="show_recent_files_summary">Pokaż lokalizacje najnowszych baz danych</string>
<string name="hide_broken_locations_title">Ukryj uszkodzone łącza do bazy danych</string>
<string name="hide_broken_locations_summary">Ukryj uszkodzone łącza na liście najnowszych baz danych</string>
<string name="warning_database_read_only">Przyznaj dostęp do zapisu pliku, aby zapisać zmiany w bazie danych</string>
<string name="contribution">Wkład</string>
</resources> </resources>

View File

@@ -65,7 +65,6 @@
<string name="error_pass_gen_type">Pelo menos um tipo de geração de senhas deve ser selecionado.</string> <string name="error_pass_gen_type">Pelo menos um tipo de geração de senhas deve ser selecionado.</string>
<string name="error_pass_match">As senhas não combinam.</string> <string name="error_pass_match">As senhas não combinam.</string>
<string name="error_rounds_too_large">\"Número de rodadas\" é muito grande. Modificado para 2147483648.</string> <string name="error_rounds_too_large">\"Número de rodadas\" é muito grande. Modificado para 2147483648.</string>
<string name="error_title_required">Insira um título.</string>
<string name="error_wrong_length">Digite um número inteiro positivo no campo \"Tamanho\".</string> <string name="error_wrong_length">Digite um número inteiro positivo no campo \"Tamanho\".</string>
<string name="file_browser">Localizador de arquivos</string> <string name="file_browser">Localizador de arquivos</string>
<string name="generate_password">Gerar senha</string> <string name="generate_password">Gerar senha</string>
@@ -360,16 +359,15 @@
<string name="content_description_add_group">Adicionar grupo</string> <string name="content_description_add_group">Adicionar grupo</string>
<string name="content_description_file_information">Informações do arquivo</string> <string name="content_description_file_information">Informações do arquivo</string>
<string name="content_description_entry_icon">Ícone da entrada</string> <string name="content_description_entry_icon">Ícone da entrada</string>
<string name="content_description_password_generator">Gerador de senhas</string> <string name="entry_password_generator">Gerador de senhas</string>
<string name="content_description_password_length">Comprimento da senha</string> <string name="content_description_password_length">Comprimento da senha</string>
<string name="content_description_add_field">Adicionar campo</string> <string name="entry_add_field">Adicionar campo</string>
<string name="content_description_remove_field">Remover campo</string> <string name="content_description_remove_field">Remover campo</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Você não pode mover uma entrada para cá.</string> <string name="error_move_entry_here">Você não pode mover uma entrada para cá.</string>
<string name="error_copy_entry_here">Você não pode copiar uma entrada aqui.</string> <string name="error_copy_entry_here">Você não pode copiar uma entrada aqui.</string>
<string name="list_groups_show_number_entries_title">Mostrar número de entradas</string> <string name="list_groups_show_number_entries_title">Mostrar número de entradas</string>
<string name="list_groups_show_number_entries_summary">Mostrar o número de entradas dentro de um grupo</string> <string name="list_groups_show_number_entries_summary">Mostrar o número de entradas dentro de um grupo</string>
<string name="content_description_entry_save">Salvar entrada</string>
<string name="content_description_node_children">Nó filho</string> <string name="content_description_node_children">Nó filho</string>
<string name="content_description_password_checkbox">Caixa de seleção de senha</string> <string name="content_description_password_checkbox">Caixa de seleção de senha</string>
<string name="content_description_keyfile_checkbox">Caixa de seleção do arquivo-chave</string> <string name="content_description_keyfile_checkbox">Caixa de seleção do arquivo-chave</string>
@@ -414,8 +412,6 @@
<string name="contains_duplicate_uuid_procedure">Ao validar este diálogo, o KeePassDX irá consertar o problema (gerando um novo UUID para os duplicados) e continuar.</string> <string name="contains_duplicate_uuid_procedure">Ao validar este diálogo, o KeePassDX irá consertar o problema (gerando um novo UUID para os duplicados) e continuar.</string>
<string name="database_opened">Banco de dados aberto</string> <string name="database_opened">Banco de dados aberto</string>
<string name="clipboard_explanation_summary">Copiar campos de entrada usando a área de transferência do seu aparelho</string> <string name="clipboard_explanation_summary">Copiar campos de entrada usando a área de transferência do seu aparelho</string>
<string name="persistent_notification_title">Notificação persistente</string>
<string name="persistent_notification_summary">Adicionar uma notificação quando o banco de dados for aberto</string>
<string name="advanced_unlock_explanation_summary">Usar destravamento avançado para abrir o banco de dados mais facilmente</string> <string name="advanced_unlock_explanation_summary">Usar destravamento avançado para abrir o banco de dados mais facilmente</string>
<string name="database_data_compression_title">Compressão dos dados</string> <string name="database_data_compression_title">Compressão dos dados</string>
<string name="database_data_compression_summary">Compressão dos dados reduz o tamanho do banco de dados.</string> <string name="database_data_compression_summary">Compressão dos dados reduz o tamanho do banco de dados.</string>

View File

@@ -72,7 +72,6 @@
<string name="error_pass_match">As palavras-passe não coincidem.</string> <string name="error_pass_match">As palavras-passe não coincidem.</string>
<string name="error_rounds_too_large">\"Número de rodadas\" é muito grande. Modificado para 2147483648.</string> <string name="error_rounds_too_large">\"Número de rodadas\" é muito grande. Modificado para 2147483648.</string>
<string name="error_string_key">Um nome do campo é necessário para cada string.</string> <string name="error_string_key">Um nome do campo é necessário para cada string.</string>
<string name="error_title_required">Adicione um título.</string>
<string name="error_wrong_length">Digite um número inteiro positivo no campo \"Tamanho\".</string> <string name="error_wrong_length">Digite um número inteiro positivo no campo \"Tamanho\".</string>
<string name="field_name">Nome do campo</string> <string name="field_name">Nome do campo</string>
<string name="field_value">Valor do campo</string> <string name="field_value">Valor do campo</string>
@@ -358,10 +357,9 @@
<string name="content_description_keyfile_checkbox">Caixa de seleção keyfile</string> <string name="content_description_keyfile_checkbox">Caixa de seleção keyfile</string>
<string name="content_description_repeat_toggle_password_visibility">Repetir alternar a visibilidade da palavra-passe</string> <string name="content_description_repeat_toggle_password_visibility">Repetir alternar a visibilidade da palavra-passe</string>
<string name="content_description_entry_icon">Ícone da entrada</string> <string name="content_description_entry_icon">Ícone da entrada</string>
<string name="content_description_entry_save">Gravação de entrada</string> <string name="entry_password_generator">Gerador de palavras-passe</string>
<string name="content_description_password_generator">Gerador de palavras-passe</string>
<string name="content_description_password_length">Comprimento da palavra-passe</string> <string name="content_description_password_length">Comprimento da palavra-passe</string>
<string name="content_description_add_field">Adicionar campo</string> <string name="entry_add_field">Adicionar campo</string>
<string name="content_description_remove_field">Remover campo</string> <string name="content_description_remove_field">Remover campo</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Você não pode mover uma entrada para cá.</string> <string name="error_move_entry_here">Você não pode mover uma entrada para cá.</string>

View File

@@ -36,10 +36,9 @@
<string name="content_description_keyfile_checkbox">Verifica fisierul cheie</string> <string name="content_description_keyfile_checkbox">Verifica fisierul cheie</string>
<string name="content_description_repeat_toggle_password_visibility">Repetați pentru a comuta vizibilitatea parolei</string> <string name="content_description_repeat_toggle_password_visibility">Repetați pentru a comuta vizibilitatea parolei</string>
<string name="content_description_entry_icon">Pictograma de intrare</string> <string name="content_description_entry_icon">Pictograma de intrare</string>
<string name="content_description_entry_save">Salvați intrarea</string> <string name="entry_password_generator">Generator de parole</string>
<string name="content_description_password_generator">Generator de parole</string>
<string name="content_description_password_length">Lungimea parolei</string> <string name="content_description_password_length">Lungimea parolei</string>
<string name="content_description_add_field">Adăugați câmp</string> <string name="entry_add_field">Adăugați câmp</string>
<string name="content_description_remove_field">Elimina câmp</string> <string name="content_description_remove_field">Elimina câmp</string>
<string name="content_description_update_from_list">Actualizați</string> <string name="content_description_update_from_list">Actualizați</string>
<string name="content_description_remove_from_list">Elimina</string> <string name="content_description_remove_from_list">Elimina</string>
@@ -95,7 +94,6 @@
<string name="error_pass_match">Parolele nu se potrivesc.</string> <string name="error_pass_match">Parolele nu se potrivesc.</string>
<string name="error_rounds_too_large">\"Transformările rotunde\" prea sus. Setarea la 2147483648.</string> <string name="error_rounds_too_large">\"Transformările rotunde\" prea sus. Setarea la 2147483648.</string>
<string name="error_string_key">Fiecare șir trebuie să aibă un nume de câmp.</string> <string name="error_string_key">Fiecare șir trebuie să aibă un nume de câmp.</string>
<string name="error_title_required">Adăugați un titlu.</string>
<string name="error_wrong_length">Introduceți un număr întreg pozitiv în câmpul \"Lungime\".</string> <string name="error_wrong_length">Introduceți un număr întreg pozitiv în câmpul \"Lungime\".</string>
<string name="error_autofill_enable_service">Nu s-a putut activa serviciul de completare automată.</string> <string name="error_autofill_enable_service">Nu s-a putut activa serviciul de completare automată.</string>
<string name="error_move_folder_in_itself">Nu puteți muta un grup în sine.</string> <string name="error_move_folder_in_itself">Nu puteți muta un grup în sine.</string>
@@ -175,4 +173,263 @@
<string name="hide_password_title">Ascundeți parolele</string> <string name="hide_password_title">Ascundeți parolele</string>
<string name="hide_password_summary">Mascați parolele (***) în mod implicit</string> <string name="hide_password_summary">Mascați parolele (***) în mod implicit</string>
<string name="about">Despre</string> <string name="about">Despre</string>
<string name="no_url_handler">Instalați un browser web pentru a deschide această adresă URL.</string>
<string name="select_database_file">Deschide baza de date existentă</string>
<string name="create_keepass_file">Creați o bază de date nouă</string>
<string name="open_recent">Baze de date recente</string>
<string name="progress_create">Crearea noii baze de date …</string>
<string name="progress_title">Lucrând …</string>
<string name="protection">Protecție</string>
<string name="read_only">Protejat la scriere</string>
<string name="read_only_warning">În funcție de managerul de fișiere, este posibil ca KeePassDX să nu poată scrie în stocare.</string>
<string name="contains_duplicate_uuid">Baza de date conține UUID-uri duplicate.</string>
<string name="contains_duplicate_uuid_procedure">Prin validarea acestui dialog, KeePassDX va rezolva problema (prin generarea de noi UUID-uri pentru duplicate) și va continua.</string>
<string name="selection_mode">Mod de selectare</string>
<string name="root">Rădăcină</string>
<string name="encryption_explanation">Algoritmul bazei de date de criptare utilizat pentru toate datele.</string>
<string name="kdf_explanation">Pentru a genera cheia pentru algoritmul de criptare, cheia principală este transformată folosind o funcție de derivare a cheilor sărate aleatoriu.</string>
<string name="rounds">Rundele de transformare</string>
<string name="rounds_explanation">Rundele suplimentare de criptare oferă o protecție mai mare împotriva atacurilor de forță brută, dar pot încetini cu adevărat încărcarea și economisirea.</string>
<string name="memory_usage">Utilizarea memoriei</string>
<string name="memory_usage_explanation">Cantitatea de memorie (în octeți) care trebuie utilizată de funcția de derivare a cheilor.</string>
<string name="parallelism">Paralelism</string>
<string name="parallelism_explanation">Gradul de paralelism (adică numărul de fire) utilizat de funcția de derivare a cheilor.</string>
<string name="saving_database">Salvarea bazei de date …</string>
<string name="command_execution">Executarea comenzii …</string>
<string name="do_not_kill_app">Nu omori aplicația …</string>
<string name="space">Spatiu</string>
<string name="search_label">Cauta</string>
<string name="sort_menu">Sorteaza</string>
<string name="sort_ascending">Prima cea mai mică ↓</string>
<string name="sort_groups_before">Grupuri înainte</string>
<string name="sort_recycle_bin_bottom">Reciclați coșul din partea de jos</string>
<string name="sort_db">Ordine naturală</string>
<string name="sort_title">Titlu</string>
<string name="sort_username">Nume de utilizator</string>
<string name="sort_creation_time">Creare</string>
<string name="sort_last_modify_time">Modificare</string>
<string name="sort_last_access_time">Acces</string>
<string name="special">Special</string>
<string name="search">Căutare</string>
<string name="search_results">Rezultatele căutării</string>
<string name="underline">Subliniere</string>
<string name="unsupported_db_version">Versiunea bazei de date neacceptată.</string>
<string name="uppercase">Cu majuscule</string>
<string name="warning">Avertizare</string>
<string name="warning_password_encoding">Evitați caracterele parole în afara formatului de codare a textului în fișierul bazei de date (caracterele nerecunoscute sunt convertite în aceeași literă).</string>
<string name="warning_unmounted">Montați cardul de memorie pentru a crea sau încărca o bază de date.</string>
<string name="warning_empty_password">Chiar nu doriți nicio protecție de deblocare a parolei\?</string>
<string name="warning_no_encryption_key">Ești sigur că nu vrei să folosești nicio cheie de criptare\?</string>
<string name="warning_permanently_delete_nodes">Sigur doriți să ștergeți definitiv nodurile selectate\?</string>
<string name="version_label">Versiunea %1$s</string>
<string name="build_label">Construiți %1$s</string>
<string name="configure_biometric">Indicatorul biometric este acceptat, dar nu este configurat.</string>
<string name="keystore_not_accessible">Magazinul de chei nu este inițializat corect.</string>
<string name="open_biometric_prompt_unlock_database">Deschideți promptul biometric pentru deblocarea bazei de date</string>
<string name="open_biometric_prompt_store_credential">Deschideți promptul biometric pentru a stoca datele de acreditare</string>
<string name="biometric_prompt_store_credential_title">Salvați recunoașterea biometrică</string>
<string name="biometric_prompt_store_credential_message">Avertisment: trebuie să vă amintiți parola de master dacă utilizați recunoașterea biometrică.</string>
<string name="biometric_prompt_extract_credential_title">Baza de date deschisă cu recunoaștere biometrică</string>
<string name="biometric_prompt_extract_credential_message">Extrageți datele de bază cu date biometrice</string>
<string name="encrypted_value_stored">Parola criptată stocată</string>
<string name="biometric_invalid_key">Nu pot citi cheia biometrică. Vă rugăm să îl ștergeți și să repetați procedura de recunoaștere biometrică.</string>
<string name="biometric_not_recognized">Nu a putut recunoaște biometric</string>
<string name="biometric_scanning_error">Eroare biometrică: %1$s</string>
<string name="no_credentials_stored">Această bază de date nu are încă credențiale stocate.</string>
<string name="credential_before_click_biometric_button">De acum nu există date creditate stocate.</string>
<string name="database_history">Istoric</string>
<string name="menu_appearance_settings">Aparenta</string>
<string name="biometric">Biometric</string>
<string name="general">General</string>
<string name="autofill">Autocompletare</string>
<string name="autofill_service_name">Completarea automată a formularului KeePassDX</string>
<string name="autofill_sign_in_prompt">Conectați-vă cu KeePassDX</string>
<string name="autofill_explanation_summary">Permiteți completarea automată pentru a completa rapid formularele din alte aplicații</string>
<string name="set_autofill_service_title">Setați serviciul automat de completare automată</string>
<string name="password_size_title">Mărimea generată a parolei</string>
<string name="password_size_summary">Setează dimensiunea implicită a parolelor generate</string>
<string name="list_password_generator_options_title">Caractere parolă</string>
<string name="list_password_generator_options_summary">Setați caractere permise generator de parole</string>
<string name="database_opened">Baza de date a fost deschisă</string>
<string name="clipboard">Clipboard</string>
<string name="clipboard_explanation_summary">Copiați câmpurile de intrare cu ajutorul clipboard-ului dispozitivului</string>
<string name="clipboard_notifications_title">Clipboard notificări</string>
<string name="clipboard_notifications_summary">Activați notificările pentru clipboard pentru a copia câmpurile când vizionați o intrare</string>
<string name="clipboard_warning">Dacă ștergerea automată a clipboard-ului nu reușește, ștergeți manual istoricul acestuia.</string>
<string name="lock">Blocheaza</string>
<string name="lock_database_screen_off_title">Blocare ecran</string>
<string name="lock_database_screen_off_summary">Încărcați baza de date când ecranul este deconectat</string>
<string name="lock_database_back_root_title">Apăsați „Înapoi” pentru a bloca ecranul</string>
<string name="lock_database_back_root_summary">Blocați baza de date atunci când utilizatorul face clic pe butonul înapoi de pe ecranul rădăcină</string>
<string name="advanced_unlock">Deblocare avansată</string>
<string name="advanced_unlock_explanation_summary">Utilizați deblocarea avansată pentru a deschide o bază de date mai ușor</string>
<string name="biometric_unlock_enable_title">Deblocare biometrică</string>
<string name="biometric_unlock_enable_summary">Vă permite să scanați biometric pentru a deschide baza de date</string>
<string name="biometric_auto_open_prompt_title">Indicator biometric deschis automat</string>
<string name="biometric_auto_open_prompt_summary">Deschideți automat biometric prompt atunci când o cheie biometrică este definită pentru o bază de date</string>
<string name="biometric_delete_all_key_title">Ștergeți cheile de criptare</string>
<string name="biometric_delete_all_key_summary">Ștergeți toate cheile de criptare legate de recunoașterea biometrică</string>
<string name="biometric_delete_all_key_warning">Sigur doriți să ștergeți toate cheile legate de recunoașterea biometrică\?</string>
<string name="unavailable_feature_text">Nu s-a putut porni această caracteristică.</string>
<string name="unavailable_feature_version">Versiunea dvs. de Android %1$s nu corespunde versiunii minime %2$s necesare.</string>
<string name="unavailable_feature_hardware">Nu s-a putut găsi hardware-ul corespunzător.</string>
<string name="file_name">Nume fișier</string>
<string name="path">Cale</string>
<string name="assign_master_key">Atribuie o cheie master</string>
<string name="full_file_path_enable_title">Calea fișierului</string>
<string name="full_file_path_enable_summary">Vizualizați calea completă a fișierului</string>
<string name="database_data_compression_title">Compresia datelor</string>
<string name="database_data_compression_summary">Compresia datelor reduce dimensiunea bazei de date.</string>
<string name="recycle_bin_title">Utilizarea cosului de gunoi</string>
<string name="recycle_bin_summary">Mută grupuri și intrări în grupul „Coș de reciclare” înainte de ștergere</string>
<string name="recycle_bin_group_title">Grupul cosului de reciclare</string>
<string name="max_history_items_title">Număr maxim</string>
<string name="max_history_items_summary">Limitați numărul de articole istorice pe intrare</string>
<string name="max_history_size_title">Dimensiune maximă</string>
<string name="max_history_size_summary">Limitați dimensiunea istoricului (în octeți) pe intrare</string>
<string name="settings_database_recommend_changing_master_key_title">Recomandă reînnoirea</string>
<string name="settings_database_recommend_changing_master_key_summary">Recomandă schimbarea cheii master (zile)</string>
<string name="settings_database_force_changing_master_key_title">Forteaza reinoirea</string>
<string name="settings_database_force_changing_master_key_summary">Solicitați schimbarea cheii master (zile)</string>
<string name="settings_database_force_changing_master_key_next_time_title">Forteaza reînnoirea data viitoare</string>
<string name="settings_database_force_changing_master_key_next_time_summary">Solicitați schimbarea cheii master data viitoare (o dată)</string>
<string name="monospace_font_fields_enable_title">Font camp</string>
<string name="monospace_font_fields_enable_summary">Schimbați fontul folosit în câmpuri pentru o mai bună vizibilitate a caracterelor</string>
<string name="allow_copy_password_title">Clipboard de incredere</string>
<string name="allow_copy_password_summary">Permiteți copierea parolei de intrare și câmpurile protejate în clipboard</string>
<string name="allow_copy_password_warning">Avertisment: Clipboard-ul este distribuit de toate aplicațiile. Dacă datele sensibile sunt copiate, alt software îl poate recupera.</string>
<string name="enable">Activeaza</string>
<string name="disable">Dezactiveaza</string>
<string name="clear_clipboard_notification_title">Curata la închidere</string>
<string name="clear_clipboard_notification_summary">Blocați baza de date la închiderea notificării</string>
<string name="database_name_title">Numele bazei de date</string>
<string name="database_description_title">Descrierea bazei de date</string>
<string name="database_default_username_title">Nume utilizator implicit</string>
<string name="database_custom_color_title">Culoare personalizată a bazei de date</string>
<string name="database_version_title">Versiunea bazei de date</string>
<string name="text_appearance">Text</string>
<string name="application_appearance">Aplicație</string>
<string name="other">Alta</string>
<string name="compression">Compresie</string>
<string name="compression_none">Nimic</string>
<string name="compression_gzip">gzip</string>
<string name="recycle_bin">Cos de reciclare</string>
<string name="keyboard">Tastatura</string>
<string name="magic_keyboard_title">TastaturaMagica</string>
<string name="magic_keyboard_explanation_summary">Activați o tastatură personalizată care conține parolele și toate câmpurile de identitate</string>
<string name="device_keyboard_setting_title">Setări tastatură dispozitiv</string>
<string name="keyboard_name">TastaturaMagica</string>
<string name="keyboard_label">TastaturaMagica (KeePassDX)</string>
<string name="keyboard_setting_label">Setări TastaturaMagica</string>
<string name="keyboard_entry_category">Intrare</string>
<string name="keyboard_selection_entry_title">Selectia de intrare</string>
<string name="keyboard_selection_entry_summary">Afișați câmpurile de intrare în TastaturaMagica când vizualizați o intrare</string>
<string name="keyboard_notification_entry_title">Informații de notificare</string>
<string name="keyboard_notification_entry_summary">Afișați o notificare atunci când este disponibilă o intrare</string>
<string name="keyboard_notification_entry_clear_close_title">Curata la închidere</string>
<string name="keyboard_notification_entry_clear_close_summary">Închideți baza de date la închiderea notificării</string>
<string name="keyboard_entry_timeout_title">Sesiune expirata</string>
<string name="keyboard_entry_timeout_summary">Sesiune expirata pentru a șterge intrarea tastaturii</string>
<string name="keyboard_notification_entry_content_title_text">Intrare</string>
<string name="keyboard_notification_entry_content_title">%1$s disponibil pe TastaturaMagica</string>
<string name="keyboard_notification_entry_content_text">%1$s</string>
<string name="keyboard_appearance_category">Aparenta</string>
<string name="keyboard_theme_title">Tema tastaturii</string>
<string name="keyboard_keys_category">Chei</string>
<string name="keyboard_auto_go_action_title">Acțiune automată cu cheie</string>
<string name="keyboard_auto_go_action_summary">Acțiunea tastei Go se efectuează automat după apăsarea unei taste Field</string>
<string name="keyboard_key_vibrate_title">Apăsări de taste vibratoare</string>
<string name="keyboard_key_sound_title">Apăsări de taste cheie</string>
<string name="allow_no_password_title">Nu permiteți nicio cheie principală</string>
<string name="allow_no_password_summary">Activați butonul „Deschide” dacă nu sunt selectate acreditările</string>
<string name="delete_entered_password_title">Ștergeți parola</string>
<string name="delete_entered_password_summary">Șterge parola introdusă după o încercare de conectare</string>
<string name="enable_read_only_title">Protejat la scriere</string>
<string name="enable_read_only_summary">Deschideți baza de date numai în citire în mod implicit</string>
<string name="enable_auto_save_database_title">Baza de date Autosave</string>
<string name="enable_auto_save_database_summary">Salvați automat baza de date după o acțiune importantă (numai în modul „Modificabil”)</string>
<string name="enable_education_screens_title">Ecrane educative</string>
<string name="enable_education_screens_summary">Evidențiați elementele pentru a afla cum funcționează aplicația</string>
<string name="reset_education_screens_title">Resetați ecranele educaționale</string>
<string name="reset_education_screens_summary">Afișează din nou toate elementele educaționale</string>
<string name="reset_education_screens_text">Ecranele educaționale sunt resetate</string>
<string name="education_create_database_title">Creați fișierul dvs. de bază de date</string>
<string name="education_create_database_summary">Creați primul dvs. fișier de gestionare a parolelor.</string>
<string name="education_select_database_title">Deschideți o bază de date existentă</string>
<string name="education_select_database_summary">Deschideți fișierul bazei de date anterioare din browserul de fișiere pentru a-l continua.</string>
<string name="education_new_node_title">Adăugați elemente în baza de date</string>
<string name="education_new_node_summary">Înscrierile vă ajută să vă gestionați identitățile digitale.
\n
\nGrupuri (~ foldere) organizează intrări în baza de date.</string>
<string name="education_search_title">Căutați prin intrări</string>
<string name="education_search_summary">Introduceți titlul, numele de utilizator sau conținutul altor câmpuri pentru a prelua parolele.</string>
<string name="education_biometric_title">Deblocarea bazei de date prin biometric</string>
<string name="education_biometric_summary">Conectați parola la biometrica scanată pentru a debloca rapid baza de date.</string>
<string name="education_entry_edit_title">Modificați intrarea</string>
<string name="education_entry_edit_summary">Modificați-vă înregistrarea cu câmpuri personalizate. Datele despre pool pot fi referențiate între diferite câmpuri de intrare.</string>
<string name="education_generate_password_title">Creați o parolă puternică pentru intrarea dvs.</string>
<string name="education_generate_password_summary">Generați o parolă puternică pentru a vă asocia cu intrarea dvs., definiți-o ușor în funcție de criteriile formularului și nu uitați parola securizată.</string>
<string name="education_entry_new_field_title">Adăugați câmpuri personalizate</string>
<string name="education_entry_new_field_summary">Înregistrați un câmp suplimentar, adăugați o valoare și protejați-l opțional.</string>
<string name="education_unlock_title">Deblocați baza de date</string>
<string name="education_unlock_summary">Introduceți parola și / sau fișierul cheie pentru a debloca baza de date.
\n
\nBackup-ul fișierului dvs. de bază de date într-un loc sigur după fiecare modificare.</string>
<string name="education_read_only_title">Protejați-vă baza de date</string>
<string name="education_read_only_summary">Schimbați modul de deschidere pentru sesiune.
\n
\n„Protecție la scriere” previne modificările neintenționate ale bazei de date.
\n„Modificabil” vă permite să adăugați, să ștergeți sau să modificați toate elementele.</string>
<string name="education_field_copy_title">Copiați un câmp</string>
<string name="education_field_copy_summary">Câmpurile copiate pot fi lipite oriunde.
\n
\nFolosiți metoda de completare a formularului pe care o preferați.</string>
<string name="education_lock_title">Blocați baza de date</string>
<string name="education_lock_summary">Blocați rapid baza de date, puteți configura aplicația pentru a o bloca după un timp și când ecranul se va opri.</string>
<string name="education_sort_title">Sortarea articolelor</string>
<string name="education_sort_summary">Alegeți cum sunt sortate intrările și grupurile.</string>
<string name="education_donation_title">Participa</string>
<string name="education_donation_summary">Ajută la creșterea stabilității, securității și la adăugarea mai multor funcții.</string>
<string name="html_text_ad_free">Spre deosebire de multe aplicații de gestionare a parolelor, acesta este &lt;strong&gt; gratuit de anunțuri &lt;/strong&gt;, &lt;strong&gt; software liber copilefted &lt;/strong&gt; și nu colectează date personale pe serverele sale, indiferent de versiunea pe care o utilizați.</string>
<string name="html_text_buy_pro">Cumpărând versiunea pro, veți avea acces la acest &lt;strong&gt; stil vizual &lt;/strong&gt; și vă va ajuta în special &lt;strong&gt; implementarea proiectelor comunitare. &lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Acest &lt;strong&gt; stil vizual &lt;/strong&gt; este disponibil datorită generozității tale.</string>
<string name="html_text_donation">Pentru a ne păstra libertatea și pentru a fi mereu activi, ne bazăm pe contribuția dvs. &lt;strong&gt;. &lt;/strong&gt;</string>
<string name="html_text_dev_feature">Această caracteristică este &lt;strong&gt; în curs de dezvoltare &lt;/strong&gt; și necesită ca contribuția dvs &lt;strong&gt; să fie disponibilă în curând.</string>
<string name="html_text_dev_feature_buy_pro">Cumpărând versiunea &lt;strong&gt; pro &lt;/strong&gt;,</string>
<string name="html_text_dev_feature_contibute">Prin &lt;strong&gt; contribuție &lt;/strong&gt;,</string>
<string name="html_text_dev_feature_encourage">încurajezi dezvoltatorii să creeze &lt;strong&gt; funcții noi &lt;/strong&gt; și să &lt;strong&gt; remedieze erori &lt;/strong&gt; în conformitate cu observațiile tale.</string>
<string name="html_text_dev_feature_thanks">Mulțumesc mult pentru contribuție.</string>
<string name="html_text_dev_feature_work_hard">Muncim din greu pentru a lansa rapid această caracteristică.</string>
<string name="html_text_dev_feature_upgrade">Nu uitați să mențineți aplicația la zi instalând noi versiuni.</string>
<string name="download">Descărcați</string>
<string name="contribute">Contribuie</string>
<string name="download_attachment">Descărcați %1$s</string>
<string name="download_initialization">Inițializare …</string>
<string name="download_progression">In progress: %1$d%</string>
<string name="download_finalization">Finalizare …</string>
<string name="download_complete">Complet! Atingeți pentru a deschide fișierul.</string>
<string name="encryption_rijndael">Rijndael (AES)</string>
<string name="encryption_twofish">Twofish</string>
<string name="encryption_chacha20">ChaCha20</string>
<string name="kdf_AES">AES</string>
<string name="kdf_Argon2">Argon2</string>
<string name="style_choose_title">Tema aplicației</string>
<string name="style_choose_summary">Tema folosită în aplicație</string>
<string name="icon_pack_choose_title">Pachet de pictograme</string>
<string name="icon_pack_choose_summary">Pachet de pictograme folosit în aplicație</string>
<string name="hide_expired_entries_title">Ascundeți intrările expirate</string>
<string name="hide_expired_entries_summary">Înscrierile expirate vor fi ascunse</string>
<string name="omit_backup_search_title">Nu căutați prin intrări de rezervă</string>
<string name="omit_backup_search_summary">Omite grupurile „Backup” și „Recycle bin” din rezultatele căutării</string>
<string name="auto_focus_search_title">Căutare rapidă</string>
<string name="auto_focus_search_summary">Solicitați o căutare atunci când deschideți o bază de date</string>
<string name="remember_database_locations_title">Salvați locația bazelor de date</string>
<string name="remember_database_locations_summary">Amintiți-vă locația bazelor de date</string>
<string name="remember_keyfile_locations_title">Salvați locația fișierelor cheie</string>
<string name="remember_keyfile_locations_summary">Amintiți-vă locația bazelor de date cheie de date</string>
<string name="show_recent_files_title">Afișați fișiere recente</string>
<string name="show_recent_files_summary">Afișați locațiile bazelor de date recente</string>
<string name="hide_broken_locations_title">Ascundeți linkurile de bază de date stricate</string>
<string name="hide_broken_locations_summary">Ascundeți legăturile rupte în lista bazelor de date recente</string>
<string name="warning_database_read_only">Acordă acces la scriere fișier pentru a salva modificările bazei de date</string>
</resources> </resources>

View File

@@ -43,8 +43,8 @@
<string name="decrypting_db">Расшифровка базы…</string> <string name="decrypting_db">Расшифровка базы…</string>
<string name="default_checkbox">База по умолчанию</string> <string name="default_checkbox">База по умолчанию</string>
<string name="digits">Цифры</string> <string name="digits">Цифры</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft с &lt;strong&gt;открытым исходным кодом&lt;strong&gt; и &lt;strong&gt;без рекламы&lt;strong&gt;. <string name="html_about_licence">KeePassDX © %1$d Kunzisoft с &lt;strong&gt;открытым исходным кодом&lt;/strong&gt; и &lt;strong&gt;без рекламы&lt;/strong&gt;.
\nРаспространяется под лицензией &lt;strong&gt;GPLv3&lt;strong&gt; без каких-либо гарантий.</string> \nРаспространяется под лицензией &lt;strong&gt;GPLv3&lt;/strong&gt; без каких-либо гарантий.</string>
<string name="select_database_file">Открыть существующую базу</string> <string name="select_database_file">Открыть существующую базу</string>
<string name="entry_accessed">Доступ</string> <string name="entry_accessed">Доступ</string>
<string name="entry_cancel">Отмена</string> <string name="entry_cancel">Отмена</string>
@@ -72,7 +72,6 @@
<string name="error_pass_match">Пароли не совпадают.</string> <string name="error_pass_match">Пароли не совпадают.</string>
<string name="error_rounds_too_large">Предельное значение 2147483648.</string> <string name="error_rounds_too_large">Предельное значение 2147483648.</string>
<string name="error_string_key">Каждое поле должно иметь название.</string> <string name="error_string_key">Каждое поле должно иметь название.</string>
<string name="error_title_required">Введите название.</string>
<string name="error_wrong_length">Поле \"Длина\" должно быть положительным целым числом.</string> <string name="error_wrong_length">Поле \"Длина\" должно быть положительным целым числом.</string>
<string name="field_name">Название поля</string> <string name="field_name">Название поля</string>
<string name="field_value">Значение поля</string> <string name="field_value">Значение поля</string>
@@ -302,7 +301,7 @@
<string name="education_sort_summary">Выберите критерий сортировки записей и групп.</string> <string name="education_sort_summary">Выберите критерий сортировки записей и групп.</string>
<string name="education_donation_title">Участвуйте</string> <string name="education_donation_title">Участвуйте</string>
<string name="education_donation_summary">Примите участие в проекте для повышения стабильности, безопасности и добавления новых возможностей.</string> <string name="education_donation_summary">Примите участие в проекте для повышения стабильности, безопасности и добавления новых возможностей.</string>
<string name="html_text_ad_free">В отличие от многих приложений управления паролями, это &lt;strong&gt;без рекламы&lt;strong&gt; и &lt;strong&gt;свободно от лицензирования&lt;strong&gt;. Оно не собирает ваши личные данные на своих серверах независимо от того, какую версию вы используете.</string> <string name="html_text_ad_free">В отличие от многих приложений управления паролями, это &lt;strong&gt;без рекламы&lt;/strong&gt; и &lt;strong&gt;свободно от лицензирования&lt;/strong&gt;. Оно не собирает ваши личные данные на своих серверах независимо от того, какую версию вы используете.</string>
<string name="html_text_buy_pro">При покупке Pro-версии вы будете иметь доступ к этим &lt;strong&gt;визуальным стилям&lt;/strong&gt; и особенно поможете &lt;strong&gt;реализации общественных проектов&lt;/strong&gt;.</string> <string name="html_text_buy_pro">При покупке Pro-версии вы будете иметь доступ к этим &lt;strong&gt;визуальным стилям&lt;/strong&gt; и особенно поможете &lt;strong&gt;реализации общественных проектов&lt;/strong&gt;.</string>
<string name="html_text_feature_generosity">Эти &lt;strong&gt;визуальные стили&lt;/strong&gt; доступны благодаря вашей щедрости.</string> <string name="html_text_feature_generosity">Эти &lt;strong&gt;визуальные стили&lt;/strong&gt; доступны благодаря вашей щедрости.</string>
<string name="html_text_donation">Для того, чтобы сохранить нашу независимость и быть всегда активными, мы рассчитываем на ваш &lt;strong&gt;вклад&lt;/strong&gt;.</string> <string name="html_text_donation">Для того, чтобы сохранить нашу независимость и быть всегда активными, мы рассчитываем на ваш &lt;strong&gt;вклад&lt;/strong&gt;.</string>
@@ -314,7 +313,7 @@
<string name="html_text_dev_feature_work_hard">Мы прилагаем все усилия, чтобы быстро выпустить эту функцию.</string> <string name="html_text_dev_feature_work_hard">Мы прилагаем все усилия, чтобы быстро выпустить эту функцию.</string>
<string name="html_text_dev_feature_upgrade">Не забывайте обновлять приложение.</string> <string name="html_text_dev_feature_upgrade">Не забывайте обновлять приложение.</string>
<string name="download">Скачать</string> <string name="download">Скачать</string>
<string name="contribute">Помощь проекту</string> <string name="contribute">Вклад</string>
<string name="encryption_chacha20">ChaCha20</string> <string name="encryption_chacha20">ChaCha20</string>
<string name="kdf_AES">AES</string> <string name="kdf_AES">AES</string>
<string name="kdf_Argon2">Argon2</string> <string name="kdf_Argon2">Argon2</string>
@@ -361,10 +360,9 @@
<string name="content_description_keyfile_checkbox">Флажок ключевого файла</string> <string name="content_description_keyfile_checkbox">Флажок ключевого файла</string>
<string name="content_description_repeat_toggle_password_visibility">Повтор переключения видимости пароля</string> <string name="content_description_repeat_toggle_password_visibility">Повтор переключения видимости пароля</string>
<string name="content_description_entry_icon">Значок записи</string> <string name="content_description_entry_icon">Значок записи</string>
<string name="content_description_entry_save">Сохранение записи</string> <string name="entry_password_generator">Генератор паролей</string>
<string name="content_description_password_generator">Генератор паролей</string>
<string name="content_description_password_length">Длина пароля</string> <string name="content_description_password_length">Длина пароля</string>
<string name="content_description_add_field">Добавить поле</string> <string name="entry_add_field">Добавить поле</string>
<string name="content_description_remove_field">Удалить поле</string> <string name="content_description_remove_field">Удалить поле</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Вы не можете переместить запись сюда.</string> <string name="error_move_entry_here">Вы не можете переместить запись сюда.</string>
@@ -412,8 +410,6 @@
<string name="contains_duplicate_uuid_procedure">Если вы разрешите, KeePassDX исправит проблему (путём создания новых UUID для дубликатов) и продолжит работу.</string> <string name="contains_duplicate_uuid_procedure">Если вы разрешите, KeePassDX исправит проблему (путём создания новых UUID для дубликатов) и продолжит работу.</string>
<string name="database_opened">База открыта</string> <string name="database_opened">База открыта</string>
<string name="clipboard_explanation_summary">Копирование полей ввода с помощью буфера обмена устройства</string> <string name="clipboard_explanation_summary">Копирование полей ввода с помощью буфера обмена устройства</string>
<string name="persistent_notification_title">Постоянное уведомление</string>
<string name="persistent_notification_summary">Показывать уведомление, пока открыта база</string>
<string name="advanced_unlock_explanation_summary">Использовать дополнительную разблокировку для более лёгкого открытия базы данных</string> <string name="advanced_unlock_explanation_summary">Использовать дополнительную разблокировку для более лёгкого открытия базы данных</string>
<string name="database_data_compression_title">Сжатие данных</string> <string name="database_data_compression_title">Сжатие данных</string>
<string name="database_data_compression_summary">Сжатие данных уменьшает размер базы.</string> <string name="database_data_compression_summary">Сжатие данных уменьшает размер базы.</string>
@@ -450,14 +446,14 @@
<string name="keyboard_auto_go_action_summary">Выполнять команду \"Ввод\" автоматически после нажатия кнопки заполнения поля</string> <string name="keyboard_auto_go_action_summary">Выполнять команду \"Ввод\" автоматически после нажатия кнопки заполнения поля</string>
<string name="download_attachment">Скачать %1$s</string> <string name="download_attachment">Скачать %1$s</string>
<string name="download_initialization">Инициализация…</string> <string name="download_initialization">Инициализация…</string>
<string name="download_progression">Выполнение: %1$d&#37;</string> <string name="download_progression">Выполнение: %1$d%</string>
<string name="download_finalization">Завершение…</string> <string name="download_finalization">Завершение…</string>
<string name="download_complete">Готово! Нажмите, чтобы открыть файл.</string> <string name="download_complete">Готово! Нажмите, чтобы открыть файл.</string>
<string name="hide_expired_entries_title">Скрывать устаревшие записи</string> <string name="hide_expired_entries_title">Скрывать устаревшие записи</string>
<string name="hide_expired_entries_summary">Записи с истёкшим сроком окончания будут скрыты</string> <string name="hide_expired_entries_summary">Записи с истёкшим сроком окончания будут скрыты</string>
<string name="contact">Контактная информация</string> <string name="contact">Контактная информация</string>
<string name="contribution">Вклад</string> <string name="contribution">Помощь проекту</string>
<string name="html_about_contribution">Для &lt;strong&gt;сохранения нашей независимости&lt;strong&gt;, &lt;strong&gt;исправления ошибок&lt;strong&gt;, &lt;strong&gt;добавления новых функций&lt;strong&gt; и &lt;strong&gt;поддержания разработки в активном состоянии&lt;strong&gt;, мы рассчитываем на ваш &lt;strong&gt;вклад&lt;strong&gt;.</string> <string name="html_about_contribution">Для &lt;strong&gt;сохранения нашей независимости&lt;/strong&gt;, &lt;strong&gt;исправления ошибок&lt;/strong&gt;, &lt;strong&gt;добавления новых функций&lt;/strong&gt; и &lt;strong&gt;поддержания разработки в активном состоянии&lt;/strong&gt;, мы рассчитываем на ваш &lt;strong&gt;вклад&lt;/strong&gt;.</string>
<string name="auto_focus_search_title">Быстрый поиск</string> <string name="auto_focus_search_title">Быстрый поиск</string>
<string name="auto_focus_search_summary">Открывать поисковый запрос при открытии базы</string> <string name="auto_focus_search_summary">Открывать поисковый запрос при открытии базы</string>
<string name="remember_database_locations_title">Хранить расположение баз</string> <string name="remember_database_locations_title">Хранить расположение баз</string>

View File

@@ -65,7 +65,6 @@
<string name="error_pass_gen_type">Musí byť vybraý najmenej jeden typ generovania hesla</string> <string name="error_pass_gen_type">Musí byť vybraý najmenej jeden typ generovania hesla</string>
<string name="error_pass_match">Heslá sa nezhodujú.</string> <string name="error_pass_match">Heslá sa nezhodujú.</string>
<string name="error_rounds_too_large">Príliš veľa opakovaní. Nastavujem na 2147483648.</string> <string name="error_rounds_too_large">Príliš veľa opakovaní. Nastavujem na 2147483648.</string>
<string name="error_title_required">Vyžaduje sa názov.</string>
<string name="error_wrong_length">Zadajte celé kladné číslo na dĺžku poľa</string> <string name="error_wrong_length">Zadajte celé kladné číslo na dĺžku poľa</string>
<string name="file_browser">Správca Súborov</string> <string name="file_browser">Správca Súborov</string>
<string name="generate_password">Generovať Heslo</string> <string name="generate_password">Generovať Heslo</string>
@@ -157,8 +156,7 @@
<string name="contact">Kontakt</string> <string name="contact">Kontakt</string>
<string name="content_description_open_file">Otvoriť súbor</string> <string name="content_description_open_file">Otvoriť súbor</string>
<string name="content_description_file_information">Informácie o súbore</string> <string name="content_description_file_information">Informácie o súbore</string>
<string name="content_description_entry_save">Uložiť záznam</string> <string name="entry_password_generator">Generátor hesla</string>
<string name="content_description_password_generator">Generátor hesla</string>
<string name="content_description_password_length">Dĺžka hesla</string> <string name="content_description_password_length">Dĺžka hesla</string>
<string name="content_description_background">Pozadie</string> <string name="content_description_background">Pozadie</string>
<string name="security">Bezpečnosť</string> <string name="security">Bezpečnosť</string>

View File

@@ -72,7 +72,6 @@
<string name="error_pass_match">Lösenorden matchar inte.</string> <string name="error_pass_match">Lösenorden matchar inte.</string>
<string name="error_rounds_too_large">\"Transformationsrundor\" är för stort. Sätter värdet till 2147483648.</string> <string name="error_rounds_too_large">\"Transformationsrundor\" är för stort. Sätter värdet till 2147483648.</string>
<string name="error_string_key">Varje sträng måste ha ett fältnamn.</string> <string name="error_string_key">Varje sträng måste ha ett fältnamn.</string>
<string name="error_title_required">Lägg till en titel.</string>
<string name="error_wrong_length">Ange ett positivt heltal i fältet för längd.</string> <string name="error_wrong_length">Ange ett positivt heltal i fältet för längd.</string>
<string name="field_name">Fältnamn</string> <string name="field_name">Fältnamn</string>
<string name="field_value">Fältvärde</string> <string name="field_value">Fältvärde</string>
@@ -173,10 +172,9 @@
<string name="content_description_keyfile_checkbox">Nyckelfilskryssruta</string> <string name="content_description_keyfile_checkbox">Nyckelfilskryssruta</string>
<string name="content_description_repeat_toggle_password_visibility">Repetera växla lösenordssynlighet</string> <string name="content_description_repeat_toggle_password_visibility">Repetera växla lösenordssynlighet</string>
<string name="content_description_entry_icon">Post-ikon</string> <string name="content_description_entry_icon">Post-ikon</string>
<string name="content_description_entry_save">Spara post</string> <string name="entry_password_generator">Lösenordsgenerator</string>
<string name="content_description_password_generator">Lösenordsgenerator</string>
<string name="content_description_password_length">Lösenords längd</string> <string name="content_description_password_length">Lösenords längd</string>
<string name="content_description_add_field">Lägg till fält</string> <string name="entry_add_field">Lägg till fält</string>
<string name="content_description_remove_field">Ta bort fält</string> <string name="content_description_remove_field">Ta bort fält</string>
<string name="content_description_background">Bakgrund</string> <string name="content_description_background">Bakgrund</string>
<string name="content_description_update_from_list">Uppdatera</string> <string name="content_description_update_from_list">Uppdatera</string>
@@ -410,8 +408,6 @@
<string name="autofill_explanation_summary">Aktivera autofyll för att snabbt kunna fylla i formulär i andra appar</string> <string name="autofill_explanation_summary">Aktivera autofyll för att snabbt kunna fylla i formulär i andra appar</string>
<string name="database_opened">Databas öppnad</string> <string name="database_opened">Databas öppnad</string>
<string name="clipboard_explanation_summary">Kopiera post-fält med hjälp av enhetens urklipp</string> <string name="clipboard_explanation_summary">Kopiera post-fält med hjälp av enhetens urklipp</string>
<string name="persistent_notification_title">Beständig avisering</string>
<string name="persistent_notification_summary">Lägg till en avisering när databasen är öppen</string>
<string name="advanced_unlock_explanation_summary">Använd avancerad upplåsning för att öppna en databas enklare</string> <string name="advanced_unlock_explanation_summary">Använd avancerad upplåsning för att öppna en databas enklare</string>
<string name="database_data_compression_title">Datakomprimering</string> <string name="database_data_compression_title">Datakomprimering</string>
<string name="database_data_compression_summary">Datakomprimering reducerar databasens storlek.</string> <string name="database_data_compression_summary">Datakomprimering reducerar databasens storlek.</string>

View File

@@ -77,7 +77,6 @@
<string name="error_pass_match">Parolalar uyuşmuyor.</string> <string name="error_pass_match">Parolalar uyuşmuyor.</string>
<string name="error_rounds_too_large">\"Dönüşüm turları\" çok yüksek. 2147483648\'e ayarlayın.</string> <string name="error_rounds_too_large">\"Dönüşüm turları\" çok yüksek. 2147483648\'e ayarlayın.</string>
<string name="error_string_key">Her dizenin bir alan adı olmalıdır.</string> <string name="error_string_key">Her dizenin bir alan adı olmalıdır.</string>
<string name="error_title_required">Bir başlık ekle.</string>
<string name="error_wrong_length">\"Uzunluk\" alanına pozitif bir tam sayı girin.</string> <string name="error_wrong_length">\"Uzunluk\" alanına pozitif bir tam sayı girin.</string>
<string name="error_autofill_enable_service">Otomatik doldurma hizmeti etkinleştirilemedi.</string> <string name="error_autofill_enable_service">Otomatik doldurma hizmeti etkinleştirilemedi.</string>
<string name="error_move_folder_in_itself">Bir grubu kendine taşıyamazsın.</string> <string name="error_move_folder_in_itself">Bir grubu kendine taşıyamazsın.</string>
@@ -337,9 +336,9 @@
<string name="content_description_password_checkbox">Parola onay kutusu</string> <string name="content_description_password_checkbox">Parola onay kutusu</string>
<string name="content_description_keyfile_checkbox">Anahtar dosyası onay kutusu</string> <string name="content_description_keyfile_checkbox">Anahtar dosyası onay kutusu</string>
<string name="content_description_entry_icon">Giriş simgesi</string> <string name="content_description_entry_icon">Giriş simgesi</string>
<string name="content_description_password_generator">Parola üreteci</string> <string name="entry_password_generator">Parola üreteci</string>
<string name="content_description_password_length">Parola uzunluğu</string> <string name="content_description_password_length">Parola uzunluğu</string>
<string name="content_description_add_field">Alan ekle</string> <string name="entry_add_field">Alan ekle</string>
<string name="content_description_remove_field">Alanı kaldır</string> <string name="content_description_remove_field">Alanı kaldır</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Buraya bir girişi taşıyamazsınız.</string> <string name="error_move_entry_here">Buraya bir girişi taşıyamazsınız.</string>
@@ -354,7 +353,6 @@
<string name="delete_entered_password_summary">Bir bağlantı denemesinden sonra girilen parolayı siler</string> <string name="delete_entered_password_summary">Bir bağlantı denemesinden sonra girilen parolayı siler</string>
<string name="content_description_node_children">Alt düğüm</string> <string name="content_description_node_children">Alt düğüm</string>
<string name="content_description_repeat_toggle_password_visibility">Geçiş şifresi görünürlüğünü tekrarlayın</string> <string name="content_description_repeat_toggle_password_visibility">Geçiş şifresi görünürlüğünü tekrarlayın</string>
<string name="content_description_entry_save">Girdiyi kaydet</string>
<string name="content_description_background">Arka plan</string> <string name="content_description_background">Arka plan</string>
<string name="content_description_update_from_list">Güncelleme</string> <string name="content_description_update_from_list">Güncelleme</string>
<string name="content_description_keyboard_close_fields">Alanları kapat</string> <string name="content_description_keyboard_close_fields">Alanları kapat</string>
@@ -395,8 +393,6 @@
<string name="contains_duplicate_uuid_procedure">Bu iletişim kutusunu doğrulayarak, KeePassDX sorunu çözecek (tekrarlananlar için yeni UUID\'ler oluşturarak) ve devam edecektir.</string> <string name="contains_duplicate_uuid_procedure">Bu iletişim kutusunu doğrulayarak, KeePassDX sorunu çözecek (tekrarlananlar için yeni UUID\'ler oluşturarak) ve devam edecektir.</string>
<string name="database_opened">Veritabanııldı</string> <string name="database_opened">Veritabanııldı</string>
<string name="clipboard_explanation_summary">Cihazınızın panosunu kullanarak giriş alanlarını kopyala</string> <string name="clipboard_explanation_summary">Cihazınızın panosunu kullanarak giriş alanlarını kopyala</string>
<string name="persistent_notification_title">Kalıcı bildirim</string>
<string name="persistent_notification_summary">Veritabanııkken bir bildirim ekle</string>
<string name="advanced_unlock_explanation_summary">Veritabanını daha kolay açmak için gelişmiş kilit açma özelliğini kullan</string> <string name="advanced_unlock_explanation_summary">Veritabanını daha kolay açmak için gelişmiş kilit açma özelliğini kullan</string>
<string name="database_data_compression_title">Veri sıkıştırma</string> <string name="database_data_compression_title">Veri sıkıştırma</string>
<string name="database_data_compression_summary">Veri sıkıştırma veritabanı boyutunu azaltır.</string> <string name="database_data_compression_summary">Veri sıkıştırma veritabanı boyutunu azaltır.</string>

View File

@@ -66,7 +66,6 @@
<string name="error_pass_gen_type">Принаймні один тип генерації пароля необхідно вибрати.</string> <string name="error_pass_gen_type">Принаймні один тип генерації пароля необхідно вибрати.</string>
<string name="error_pass_match">Паролі не співпадають.</string> <string name="error_pass_match">Паролі не співпадають.</string>
<string name="error_rounds_too_large">Надто багато циклів. Установлено 2147483648.</string> <string name="error_rounds_too_large">Надто багато циклів. Установлено 2147483648.</string>
<string name="error_title_required">Необхідно вказати заголовок.</string>
<string name="error_wrong_length">Введіть ціле число на усю довжину поля</string> <string name="error_wrong_length">Введіть ціле число на усю довжину поля</string>
<string name="file_browser">Перегляд файлів</string> <string name="file_browser">Перегляд файлів</string>
<string name="generate_password">Згенерувати пароль</string> <string name="generate_password">Згенерувати пароль</string>

View File

@@ -22,10 +22,14 @@
<style name="KeepassDXStyle.Light" parent="KeepassDXStyle.Light.v21" > <style name="KeepassDXStyle.Light" parent="KeepassDXStyle.Light.v21" >
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item> <item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="android:timePickerDialogTheme">@style/KeepassDXStyle.Light.DateTime.Dialog</item>
<item name="android:datePickerDialogTheme">@style/KeepassDXStyle.Light.DateTime.Dialog</item>
</style> </style>
<style name="KeepassDXStyle.Night" parent="KeepassDXStyle.Night.v21" > <style name="KeepassDXStyle.Night" parent="KeepassDXStyle.Night.v21" >
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item> <item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="android:timePickerDialogTheme">@style/KeepassDXStyle.Night.DateTime.Dialog</item>
<item name="android:datePickerDialogTheme">@style/KeepassDXStyle.Night.DateTime.Dialog</item>
</style> </style>
<!-- Button Style --> <!-- Button Style -->

View File

@@ -39,8 +39,8 @@
<string name="decrypting_db">正在解密数据库内容…</string> <string name="decrypting_db">正在解密数据库内容…</string>
<string name="default_checkbox">设为默认数据库</string> <string name="default_checkbox">设为默认数据库</string>
<string name="digits">数字</string> <string name="digits">数字</string>
<string name="html_about_licence">KeePassDX © %1$d 是Kunzisoft的一个&lt;strong&gt;开源&lt;strong&gt;&lt;strong&gt;无广告&lt;strong&gt;软件。 <string name="html_about_licence">KeePassDX © %1$d 是Kunzisoft的一个&lt;strong&gt;开源&lt;/strong&gt;&lt;strong&gt;无广告&lt;/strong&gt;软件。
\n它是根据&lt;strong&gt;GPLv3 &lt;strong&gt;许可证分发的您可在遵循GPL 3或者更高版本的协议下重新发布。对软件的质量和性能等问题不提供任何形式的担保。</string> \n它是根据&lt;strong&gt;GPLv3&lt;/strong&gt;许可证分发的您可在遵循GPL 3或者更高版本的协议下重新发布。Kunzisoft对软件的质量和性能等问题不提供任何形式的担保。</string>
<string name="select_database_file">打开已有数据库</string> <string name="select_database_file">打开已有数据库</string>
<string name="entry_accessed">访问时间</string> <string name="entry_accessed">访问时间</string>
<string name="entry_cancel">取消</string> <string name="entry_cancel">取消</string>
@@ -66,7 +66,6 @@
<string name="error_pass_gen_type">必须至少选择一种密码生成类型。</string> <string name="error_pass_gen_type">必须至少选择一种密码生成类型。</string>
<string name="error_pass_match">密码不匹配。</string> <string name="error_pass_match">密码不匹配。</string>
<string name="error_rounds_too_large">“变换次数”过多。已设置为2147483648。</string> <string name="error_rounds_too_large">“变换次数”过多。已设置为2147483648。</string>
<string name="error_title_required">请添加标题。</string>
<string name="error_wrong_length">请在“长度”字段输入正整数。</string> <string name="error_wrong_length">请在“长度”字段输入正整数。</string>
<string name="file_browser">文件浏览器</string> <string name="file_browser">文件浏览器</string>
<string name="generate_password">生成密码</string> <string name="generate_password">生成密码</string>
@@ -332,7 +331,7 @@
<string name="education_sort_summary">选择条目和群组的排序方式。</string> <string name="education_sort_summary">选择条目和群组的排序方式。</string>
<string name="education_donation_title">参与开发</string> <string name="education_donation_title">参与开发</string>
<string name="education_donation_summary">帮助增加稳定性,安全性并添加更多的功能。</string> <string name="education_donation_summary">帮助增加稳定性,安全性并添加更多的功能。</string>
<string name="html_text_ad_free">不同于大多数的密码管理程序无论您是使用免费版本还是付费版本的KeePassDX这都是一款&lt;strong&gt;没有广告&lt;strong&gt;&lt;strong&gt;基于copylefted版权协议的免费软件&lt;strong&gt;,同样的本软件的任何版本也不会收集您的个人信息。</string> <string name="html_text_ad_free">不同于大多数的密码管理程序无论您是使用免费版本还是付费版本的KeePassDX这都是一款&lt;strong&gt;没有广告&lt;/strong&gt;&lt;strong&gt;基于copylefted版权协议的免费软件&lt;/strong&gt;,同样的本软件的任何版本也不会收集您的个人信息。</string>
<string name="html_text_buy_pro">通过购买高级版本,您将解锁全部&lt;strong&gt;主题样式&lt;/strong&gt;,重要的是,您会为&lt;strong&gt;社区项目的进行&lt;/strong&gt;提供的帮助</string> <string name="html_text_buy_pro">通过购买高级版本,您将解锁全部&lt;strong&gt;主题样式&lt;/strong&gt;,重要的是,您会为&lt;strong&gt;社区项目的进行&lt;/strong&gt;提供的帮助</string>
<string name="html_text_feature_generosity">&lt;strong&gt;主题样式&lt;/strong&gt;现在已经可用,感谢慷慨相助。</string> <string name="html_text_feature_generosity">&lt;strong&gt;主题样式&lt;/strong&gt;现在已经可用,感谢慷慨相助。</string>
<string name="html_text_donation">为继续建设此自由项目,我们需要&lt;strong&gt;捐助。&lt;/strong&gt;</string> <string name="html_text_donation">为继续建设此自由项目,我们需要&lt;strong&gt;捐助。&lt;/strong&gt;</string>
@@ -364,10 +363,9 @@
<string name="content_description_keyfile_checkbox">密钥文件选框</string> <string name="content_description_keyfile_checkbox">密钥文件选框</string>
<string name="content_description_repeat_toggle_password_visibility">重复切换密码可见性</string> <string name="content_description_repeat_toggle_password_visibility">重复切换密码可见性</string>
<string name="content_description_entry_icon">条目图标</string> <string name="content_description_entry_icon">条目图标</string>
<string name="content_description_entry_save">保存条目</string> <string name="entry_password_generator">密码生成器</string>
<string name="content_description_password_generator">密码生成器</string>
<string name="content_description_password_length">密码长度</string> <string name="content_description_password_length">密码长度</string>
<string name="content_description_add_field">添加字段</string> <string name="entry_add_field">添加字段</string>
<string name="content_description_remove_field">删除字段</string> <string name="content_description_remove_field">删除字段</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">无法移动条目到此处。</string> <string name="error_move_entry_here">无法移动条目到此处。</string>
@@ -414,8 +412,6 @@
<string name="contains_duplicate_uuid_procedure">通过验证此对话框KeePassDX将解决这个问题通过给重复项生成新的UUID并继续。</string> <string name="contains_duplicate_uuid_procedure">通过验证此对话框KeePassDX将解决这个问题通过给重复项生成新的UUID并继续。</string>
<string name="database_opened">数据库开启</string> <string name="database_opened">数据库开启</string>
<string name="clipboard_explanation_summary">使用设备的剪贴板来复制输入字段</string> <string name="clipboard_explanation_summary">使用设备的剪贴板来复制输入字段</string>
<string name="persistent_notification_title">持久通知</string>
<string name="persistent_notification_summary">当数据库打开时产生一条通知</string>
<string name="advanced_unlock_explanation_summary">使用高级解锁轻松打开数据库</string> <string name="advanced_unlock_explanation_summary">使用高级解锁轻松打开数据库</string>
<string name="database_data_compression_title">数据压缩</string> <string name="database_data_compression_title">数据压缩</string>
<string name="database_data_compression_summary">数据压缩可降低数据库大小。</string> <string name="database_data_compression_summary">数据压缩可降低数据库大小。</string>
@@ -452,14 +448,14 @@
<string name="keyboard_auto_go_action_summary">填入用户名或密码后直接登录</string> <string name="keyboard_auto_go_action_summary">填入用户名或密码后直接登录</string>
<string name="download_attachment">下载%1$s</string> <string name="download_attachment">下载%1$s</string>
<string name="download_initialization">正在初始化…</string> <string name="download_initialization">正在初始化…</string>
<string name="download_progression">进行中:%1$d&#37;</string> <string name="download_progression">进行中:%1$d%</string>
<string name="download_finalization">正在完成…</string> <string name="download_finalization">正在完成…</string>
<string name="download_complete">完成!点击打开文件。</string> <string name="download_complete">完成!点击打开文件。</string>
<string name="hide_expired_entries_title">隐藏过期条目</string> <string name="hide_expired_entries_title">隐藏过期条目</string>
<string name="hide_expired_entries_summary">过期条目将被隐藏</string> <string name="hide_expired_entries_summary">过期条目将被隐藏</string>
<string name="contact">联系我们</string> <string name="contact">联系我们</string>
<string name="contribution">贡献</string> <string name="contribution">贡献</string>
<string name="html_about_contribution">为了&lt;strong&gt;保持我们的自由&lt;strong&gt;&lt;strong&gt;修复错误&lt;strong&gt;&lt;strong&gt;添加功能&lt;strong&gt;&lt;strong&gt;始终保持活跃&lt;strong&gt;,我们期待您的 &lt;strong&gt;贡献&lt;strong&gt;</string> <string name="html_about_contribution">为了&lt;strong&gt;保持我们的自由&lt;/strong&gt;&lt;strong&gt;修复错误&lt;/strong&gt;&lt;strong&gt;添加功能&lt;/strong&gt;&lt;strong&gt;始终保持活跃&lt;/strong&gt;,我们期待您的 &lt;strong&gt;贡献&lt;/strong&gt;</string>
<string name="auto_focus_search_title">快速搜索</string> <string name="auto_focus_search_title">快速搜索</string>
<string name="auto_focus_search_summary">打开数据库时询问是否进行搜索</string> <string name="auto_focus_search_summary">打开数据库时询问是否进行搜索</string>
<string name="remember_database_locations_title">数据库保存的路径</string> <string name="remember_database_locations_title">数据库保存的路径</string>

View File

@@ -65,7 +65,6 @@
<string name="error_pass_gen_type">必須至少選擇一個密碼生成類型。</string> <string name="error_pass_gen_type">必須至少選擇一個密碼生成類型。</string>
<string name="error_pass_match">密碼不正確。</string> <string name="error_pass_match">密碼不正確。</string>
<string name="error_rounds_too_large">次數太多。最大設置到2147483648。</string> <string name="error_rounds_too_large">次數太多。最大設置到2147483648。</string>
<string name="error_title_required">添加標題。</string>
<string name="error_wrong_length">長度欄位輸入一個正整數</string> <string name="error_wrong_length">長度欄位輸入一個正整數</string>
<string name="file_browser">檔案管理器</string> <string name="file_browser">檔案管理器</string>
<string name="generate_password">生成密碼</string> <string name="generate_password">生成密碼</string>
@@ -167,7 +166,7 @@
<string name="key_derivation_function">金鑰推算函數</string> <string name="key_derivation_function">金鑰推算函數</string>
<string name="edit_entry">編輯入口</string> <string name="edit_entry">編輯入口</string>
<string name="content_description_open_file">開啟檔案</string> <string name="content_description_open_file">開啟檔案</string>
<string name="content_description_password_generator">密碼產生器</string> <string name="entry_password_generator">密碼產生器</string>
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="content_description_background">背景</string> <string name="content_description_background">背景</string>
<string name="content_description_update_from_list">更新</string> <string name="content_description_update_from_list">更新</string>
@@ -186,9 +185,8 @@
<string name="content_description_keyfile_checkbox">金鑰檔案核取方塊</string> <string name="content_description_keyfile_checkbox">金鑰檔案核取方塊</string>
<string name="content_description_repeat_toggle_password_visibility">重複切換密碼可見性</string> <string name="content_description_repeat_toggle_password_visibility">重複切換密碼可見性</string>
<string name="content_description_entry_icon">條目圖示</string> <string name="content_description_entry_icon">條目圖示</string>
<string name="content_description_entry_save">條目保存</string>
<string name="content_description_password_length">密碼長度</string> <string name="content_description_password_length">密碼長度</string>
<string name="content_description_add_field">添加欄位</string> <string name="entry_add_field">添加欄位</string>
<string name="content_description_remove_field">刪除欄位</string> <string name="content_description_remove_field">刪除欄位</string>
<string name="master_key">主密鑰</string> <string name="master_key">主密鑰</string>
<string name="menu_master_key_settings">主密鑰設定</string> <string name="menu_master_key_settings">主密鑰設定</string>

View File

@@ -22,6 +22,7 @@
<dimen name="image_button_margin">8dp</dimen> <dimen name="image_button_margin">8dp</dimen>
<dimen name="image_list_margin">12dp</dimen> <dimen name="image_list_margin">12dp</dimen>
<dimen name="button_margin">6dp</dimen> <dimen name="button_margin">6dp</dimen>
<dimen name="card_view_margin">12dp</dimen>
<dimen name="icon_size">32dp</dimen> <dimen name="icon_size">32dp</dimen>

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