mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Compare commits
35 Commits
4.2.0beta0
...
4.1.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b98bd740c | ||
|
|
5adeb5cde0 | ||
|
|
b949d5d861 | ||
|
|
b4264a30a4 | ||
|
|
cf799c0f68 | ||
|
|
97f0ca519b | ||
|
|
cf4047b701 | ||
|
|
40608a3eb5 | ||
|
|
99cb50d031 | ||
|
|
b0d0c35241 | ||
|
|
6044c93a4a | ||
|
|
b544b5d54d | ||
|
|
852378e484 | ||
|
|
711a344860 | ||
|
|
72087c7e5c | ||
|
|
f17d211fbd | ||
|
|
ae903ad236 | ||
|
|
7c3a15ce79 | ||
|
|
2230fe66ab | ||
|
|
84a62a32ff | ||
|
|
da8ef9340c | ||
|
|
af068349e4 | ||
|
|
56cb5953dd | ||
|
|
2fc2a9c7c1 | ||
|
|
69e7cdbc47 | ||
|
|
39d9a74a73 | ||
|
|
b609d4e182 | ||
|
|
7212c73481 | ||
|
|
3ee4caa153 | ||
|
|
28e4d929bb | ||
|
|
e8ecf28f7c | ||
|
|
3d5adbfc01 | ||
|
|
72bfc50703 | ||
|
|
a60e2e780d | ||
|
|
9210851765 |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Bug Report
|
name: Bug report
|
||||||
description: Report a bug.
|
description: Report a bug.
|
||||||
labels: ["bug"]
|
labels: ["bug"]
|
||||||
body:
|
body:
|
||||||
|
|||||||
13
CHANGELOG
13
CHANGELOG
@@ -1,3 +1,16 @@
|
|||||||
|
KeePassDX(4.1.9)
|
||||||
|
* Fix landscape UI #2198 #2200 (@chenxiaolong)
|
||||||
|
* Fix start loop and flash screen #2201
|
||||||
|
* Small fixes
|
||||||
|
|
||||||
|
KeePassDX(4.1.8)
|
||||||
|
* Updated to API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
|
||||||
|
* Remember last read-only state #2099 #2100 (Thx @rmacklin)
|
||||||
|
* Fix merge deletion #1516
|
||||||
|
* Fix space in search #175
|
||||||
|
* Fix deletable recycle bin #2163
|
||||||
|
* Small fixes
|
||||||
|
|
||||||
KeePassDX(4.1.7)
|
KeePassDX(4.1.7)
|
||||||
* Fix CipherDatabase for biometric states #2119
|
* Fix CipherDatabase for biometric states #2119
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId "com.kunzisoft.keepass"
|
applicationId "com.kunzisoft.keepass"
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode = 139
|
versionCode = 143
|
||||||
versionName = "4.1.7"
|
versionName = "4.1.9"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
||||||
testApplicationId = "com.kunzisoft.keepass.tests"
|
testApplicationId = "com.kunzisoft.keepass.tests"
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import android.content.Intent
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@@ -38,13 +37,10 @@ import androidx.activity.result.ActivityResultLauncher
|
|||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.content.res.ResourcesCompat
|
|
||||||
import androidx.core.graphics.BlendModeColorFilterCompat
|
import androidx.core.graphics.BlendModeColorFilterCompat
|
||||||
import androidx.core.graphics.BlendModeCompat
|
import androidx.core.graphics.BlendModeCompat
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
@@ -83,11 +79,13 @@ import com.kunzisoft.keepass.view.hideByFading
|
|||||||
import com.kunzisoft.keepass.view.setTransparentNavigationBar
|
import com.kunzisoft.keepass.view.setTransparentNavigationBar
|
||||||
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
||||||
import com.kunzisoft.keepass.viewmodels.EntryViewModel
|
import com.kunzisoft.keepass.viewmodels.EntryViewModel
|
||||||
|
import java.util.EnumSet
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class EntryActivity : DatabaseLockActivity() {
|
class EntryActivity : DatabaseLockActivity() {
|
||||||
|
|
||||||
private var footer: ViewGroup? = null
|
private var footer: ViewGroup? = null
|
||||||
|
private var container: View? = null
|
||||||
private var coordinatorLayout: CoordinatorLayout? = null
|
private var coordinatorLayout: CoordinatorLayout? = null
|
||||||
private var collapsingToolbarLayout: CollapsingToolbarLayout? = null
|
private var collapsingToolbarLayout: CollapsingToolbarLayout? = null
|
||||||
private var appBarLayout: AppBarLayout? = null
|
private var appBarLayout: AppBarLayout? = null
|
||||||
@@ -139,6 +137,7 @@ class EntryActivity : DatabaseLockActivity() {
|
|||||||
|
|
||||||
// Get views
|
// Get views
|
||||||
footer = findViewById(R.id.activity_entry_footer)
|
footer = findViewById(R.id.activity_entry_footer)
|
||||||
|
container = findViewById(R.id.activity_entry_container)
|
||||||
coordinatorLayout = findViewById(R.id.toolbar_coordinator)
|
coordinatorLayout = findViewById(R.id.toolbar_coordinator)
|
||||||
collapsingToolbarLayout = findViewById(R.id.toolbar_layout)
|
collapsingToolbarLayout = findViewById(R.id.toolbar_layout)
|
||||||
appBarLayout = findViewById(R.id.app_bar)
|
appBarLayout = findViewById(R.id.app_bar)
|
||||||
@@ -154,8 +153,12 @@ class EntryActivity : DatabaseLockActivity() {
|
|||||||
setTransparentNavigationBar {
|
setTransparentNavigationBar {
|
||||||
// To fix margin with API 27
|
// To fix margin with API 27
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout!!, null)
|
ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout!!, null)
|
||||||
coordinatorLayout?.applyWindowInsets(WindowInsetPosition.TOP)
|
container?.applyWindowInsets(EnumSet.of(
|
||||||
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM)
|
WindowInsetPosition.TOP_MARGINS,
|
||||||
|
WindowInsetPosition.BOTTOM_MARGINS,
|
||||||
|
WindowInsetPosition.START_MARGINS,
|
||||||
|
WindowInsetPosition.END_MARGINS,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty title
|
// Empty title
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
|||||||
import com.kunzisoft.keepass.view.updateLockPaddingStart
|
import com.kunzisoft.keepass.view.updateLockPaddingStart
|
||||||
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
|
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
|
||||||
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
|
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
|
||||||
|
import java.util.EnumSet
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class EntryEditActivity : DatabaseLockActivity(),
|
class EntryEditActivity : DatabaseLockActivity(),
|
||||||
@@ -180,8 +181,12 @@ class EntryEditActivity : DatabaseLockActivity(),
|
|||||||
|
|
||||||
// To apply fit window with transparency
|
// To apply fit window with transparency
|
||||||
setTransparentNavigationBar(applyToStatusBar = true) {
|
setTransparentNavigationBar(applyToStatusBar = true) {
|
||||||
container?.applyWindowInsets(WindowInsetPosition.TOP_BOTTOM_IME)
|
container?.applyWindowInsets(EnumSet.of(
|
||||||
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM_IME)
|
WindowInsetPosition.TOP_MARGINS,
|
||||||
|
WindowInsetPosition.BOTTOM_MARGINS,
|
||||||
|
WindowInsetPosition.START_MARGINS,
|
||||||
|
WindowInsetPosition.END_MARGINS,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
stopService(Intent(this, ClipboardEntryNotificationService::class.java))
|
stopService(Intent(this, ClipboardEntryNotificationService::class.java))
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
@@ -117,6 +118,7 @@ import com.kunzisoft.keepass.view.updateLockPaddingStart
|
|||||||
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
|
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
|
||||||
import com.kunzisoft.keepass.viewmodels.GroupViewModel
|
import com.kunzisoft.keepass.viewmodels.GroupViewModel
|
||||||
import org.joda.time.LocalDateTime
|
import org.joda.time.LocalDateTime
|
||||||
|
import java.util.EnumSet
|
||||||
|
|
||||||
|
|
||||||
class GroupActivity : DatabaseLockActivity(),
|
class GroupActivity : DatabaseLockActivity(),
|
||||||
@@ -131,6 +133,7 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
private var header: ViewGroup? = null
|
private var header: ViewGroup? = null
|
||||||
private var footer: ViewGroup? = null
|
private var footer: ViewGroup? = null
|
||||||
private var drawerLayout: DrawerLayout? = null
|
private var drawerLayout: DrawerLayout? = null
|
||||||
|
private var constraintLayout: ConstraintLayout? = null
|
||||||
private var databaseNavView: NavigationDatabaseView? = null
|
private var databaseNavView: NavigationDatabaseView? = null
|
||||||
private var coordinatorLayout: CoordinatorLayout? = null
|
private var coordinatorLayout: CoordinatorLayout? = null
|
||||||
private var coordinatorError: CoordinatorLayout? = null
|
private var coordinatorError: CoordinatorLayout? = null
|
||||||
@@ -279,6 +282,7 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
header = findViewById(R.id.activity_group_header)
|
header = findViewById(R.id.activity_group_header)
|
||||||
footer = findViewById(R.id.activity_group_footer)
|
footer = findViewById(R.id.activity_group_footer)
|
||||||
drawerLayout = findViewById(R.id.drawer_layout)
|
drawerLayout = findViewById(R.id.drawer_layout)
|
||||||
|
constraintLayout = findViewById(R.id.activity_group_container_view)
|
||||||
databaseNavView = findViewById(R.id.database_nav_view)
|
databaseNavView = findViewById(R.id.database_nav_view)
|
||||||
coordinatorLayout = findViewById(R.id.group_coordinator)
|
coordinatorLayout = findViewById(R.id.group_coordinator)
|
||||||
coordinatorError = findViewById(R.id.error_coordinator)
|
coordinatorError = findViewById(R.id.error_coordinator)
|
||||||
@@ -296,8 +300,19 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
|
|
||||||
// To apply fit window with transparency
|
// To apply fit window with transparency
|
||||||
setTransparentNavigationBar(applyToStatusBar = true) {
|
setTransparentNavigationBar(applyToStatusBar = true) {
|
||||||
drawerLayout?.applyWindowInsets(WindowInsetPosition.TOP_BOTTOM_IME)
|
constraintLayout?.applyWindowInsets(EnumSet.of(
|
||||||
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM_IME)
|
WindowInsetPosition.TOP_MARGINS,
|
||||||
|
WindowInsetPosition.BOTTOM_MARGINS,
|
||||||
|
WindowInsetPosition.START_MARGINS,
|
||||||
|
WindowInsetPosition.END_MARGINS,
|
||||||
|
))
|
||||||
|
// The background of the drawer is meant to overlap system bars, so use padding
|
||||||
|
databaseNavView?.applyWindowInsets(EnumSet.of(
|
||||||
|
WindowInsetPosition.TOP_PADDING,
|
||||||
|
WindowInsetPosition.BOTTOM_PADDING,
|
||||||
|
// Only on the start side, since the drawer is anchored to one side of the screen
|
||||||
|
WindowInsetPosition.START_PADDING,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
lockView?.setOnClickListener {
|
lockView?.setOnClickListener {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import androidx.biometric.BiometricManager
|
|||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
@@ -75,8 +76,8 @@ import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.
|
|||||||
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
|
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
|
||||||
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY
|
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY
|
||||||
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY
|
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY
|
||||||
import com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity
|
|
||||||
import com.kunzisoft.keepass.settings.AppearanceSettingsActivity
|
import com.kunzisoft.keepass.settings.AppearanceSettingsActivity
|
||||||
|
import com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
|
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
|
||||||
@@ -107,7 +108,11 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
private var deviceUnlockFragment: DeviceUnlockFragment? = null
|
private var deviceUnlockFragment: DeviceUnlockFragment? = null
|
||||||
|
|
||||||
private val mDatabaseFileViewModel: DatabaseFileViewModel by viewModels()
|
private val mDatabaseFileViewModel: DatabaseFileViewModel by viewModels()
|
||||||
private val mDeviceUnlockViewModel: DeviceUnlockViewModel by viewModels()
|
private val mDeviceUnlockViewModel: DeviceUnlockViewModel? by lazy {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
ViewModelProvider(this)[DeviceUnlockViewModel::class.java]
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
private val mPasswordActivityEducation = PasswordActivityEducation(this)
|
private val mPasswordActivityEducation = PasswordActivityEducation(this)
|
||||||
|
|
||||||
@@ -177,7 +182,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
// Listen password checkbox to init advanced unlock and confirmation button
|
// Listen password checkbox to init advanced unlock and confirmation button
|
||||||
mainCredentialView?.onConditionToStoreCredentialChanged = { _, verified ->
|
mainCredentialView?.onConditionToStoreCredentialChanged = { _, verified ->
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
mDeviceUnlockViewModel.checkConditionToStoreCredential(
|
mDeviceUnlockViewModel?.checkConditionToStoreCredential(
|
||||||
condition = verified
|
condition = verified
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -242,29 +247,31 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
mDeviceUnlockViewModel.uiState.collect { uiState ->
|
mDeviceUnlockViewModel?.let { deviceUnlockViewModel ->
|
||||||
// New value received
|
deviceUnlockViewModel.uiState.collect { uiState ->
|
||||||
uiState.credentialRequiredCipher?.let { cipher ->
|
// New value received
|
||||||
mDeviceUnlockViewModel.encryptCredential(
|
uiState.credentialRequiredCipher?.let { cipher ->
|
||||||
credential = getCredentialForEncryption(),
|
deviceUnlockViewModel.encryptCredential(
|
||||||
cipher = cipher
|
credential = getCredentialForEncryption(),
|
||||||
)
|
cipher = cipher
|
||||||
}
|
)
|
||||||
uiState.cipherEncryptDatabase?.let { cipherEncryptDatabase ->
|
}
|
||||||
onCredentialEncrypted(cipherEncryptDatabase)
|
uiState.cipherEncryptDatabase?.let { cipherEncryptDatabase ->
|
||||||
mDeviceUnlockViewModel.consumeCredentialEncrypted()
|
onCredentialEncrypted(cipherEncryptDatabase)
|
||||||
}
|
deviceUnlockViewModel.consumeCredentialEncrypted()
|
||||||
uiState.cipherDecryptDatabase?.let { cipherDecryptDatabase ->
|
}
|
||||||
onCredentialDecrypted(cipherDecryptDatabase)
|
uiState.cipherDecryptDatabase?.let { cipherDecryptDatabase ->
|
||||||
mDeviceUnlockViewModel.consumeCredentialDecrypted()
|
onCredentialDecrypted(cipherDecryptDatabase)
|
||||||
}
|
deviceUnlockViewModel.consumeCredentialDecrypted()
|
||||||
uiState.exception?.let { error ->
|
}
|
||||||
Snackbar.make(
|
uiState.exception?.let { error ->
|
||||||
coordinatorLayout,
|
Snackbar.make(
|
||||||
deviceUnlockError(error, this@MainCredentialActivity),
|
coordinatorLayout,
|
||||||
Snackbar.LENGTH_LONG
|
deviceUnlockError(error, this@MainCredentialActivity),
|
||||||
).asError().show()
|
Snackbar.LENGTH_LONG
|
||||||
mDeviceUnlockViewModel.exceptionShown()
|
).asError().show()
|
||||||
|
deviceUnlockViewModel.exceptionShown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,10 +311,6 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
mDatabaseFileUri?.let { databaseFileUri ->
|
mDatabaseFileUri?.let { databaseFileUri ->
|
||||||
mDatabaseFileViewModel.loadDatabaseFile(databaseFileUri)
|
mDatabaseFileViewModel.loadDatabaseFile(databaseFileUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
mDatabase?.let { database ->
|
|
||||||
launchGroupActivityIfLoaded(database)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
|
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
|
||||||
@@ -517,7 +520,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
} else {
|
} else {
|
||||||
// Init Biometric elements
|
// Init Biometric elements
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
mDeviceUnlockViewModel.connect(databaseFileUri)
|
mDeviceUnlockViewModel?.connect(databaseFileUri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +664,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
try {
|
try {
|
||||||
menu.findItem(R.id.menu_open_file_read_mode_key)
|
menu.findItem(R.id.menu_open_file_read_mode_key)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Unable to find read mode menu")
|
Log.e(TAG, "Unable to find read mode menu", e)
|
||||||
}
|
}
|
||||||
performedNextEducation(menu)
|
performedNextEducation(menu)
|
||||||
},
|
},
|
||||||
@@ -690,7 +693,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ignored: Exception) {}
|
} catch (_: Exception) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,7 +730,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
mDeviceUnlockViewModel.disconnect()
|
mDeviceUnlockViewModel?.disconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,21 +176,14 @@ class SortDialogFragment : DatabaseDialogFragment() {
|
|||||||
return bundle
|
return bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getInstance(sortNodeEnum: SortNodeEnum,
|
|
||||||
ascending: Boolean,
|
|
||||||
groupsBefore: Boolean): SortDialogFragment {
|
|
||||||
val bundle = buildBundle(sortNodeEnum, ascending, groupsBefore)
|
|
||||||
val fragment = SortDialogFragment()
|
|
||||||
fragment.arguments = bundle
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getInstance(sortNodeEnum: SortNodeEnum,
|
fun getInstance(sortNodeEnum: SortNodeEnum,
|
||||||
ascending: Boolean,
|
ascending: Boolean,
|
||||||
groupsBefore: Boolean,
|
groupsBefore: Boolean,
|
||||||
recycleBinBottom: Boolean): SortDialogFragment {
|
recycleBinBottom: Boolean?): SortDialogFragment {
|
||||||
val bundle = buildBundle(sortNodeEnum, ascending, groupsBefore)
|
val bundle = buildBundle(sortNodeEnum, ascending, groupsBefore)
|
||||||
bundle.putBoolean(SORT_RECYCLE_BIN_BOTTOM_BUNDLE_KEY, recycleBinBottom)
|
recycleBinBottom?.let {
|
||||||
|
bundle.putBoolean(SORT_RECYCLE_BIN_BOTTOM_BUNDLE_KEY, recycleBinBottom)
|
||||||
|
}
|
||||||
val fragment = SortDialogFragment()
|
val fragment = SortDialogFragment()
|
||||||
fragment.arguments = bundle
|
fragment.arguments = bundle
|
||||||
return fragment
|
return fragment
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
|||||||
|
|
||||||
private var specialMode: SpecialMode = SpecialMode.DEFAULT
|
private var specialMode: SpecialMode = SpecialMode.DEFAULT
|
||||||
|
|
||||||
private var mRecycleBinEnable: Boolean = false
|
|
||||||
private var mRecycleBin: Group? = null
|
|
||||||
|
|
||||||
private var mRecycleViewScrollListener = object : RecyclerView.OnScrollListener() {
|
private var mRecycleViewScrollListener = object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
super.onScrollStateChanged(recyclerView, newState)
|
super.onScrollStateChanged(recyclerView, newState)
|
||||||
@@ -102,21 +99,14 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
|||||||
R.id.menu_sort -> {
|
R.id.menu_sort -> {
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
val sortDialogFragment: SortDialogFragment =
|
val sortDialogFragment: SortDialogFragment =
|
||||||
if (mRecycleBinEnable) {
|
SortDialogFragment.getInstance(
|
||||||
SortDialogFragment.getInstance(
|
PreferencesUtil.getListSort(context),
|
||||||
PreferencesUtil.getListSort(context),
|
PreferencesUtil.getAscendingSort(context),
|
||||||
PreferencesUtil.getAscendingSort(context),
|
PreferencesUtil.getGroupsBeforeSort(context),
|
||||||
PreferencesUtil.getGroupsBeforeSort(context),
|
if (mDatabase?.isRecycleBinEnabled == true) {
|
||||||
PreferencesUtil.getRecycleBinBottomSort(context)
|
PreferencesUtil.getRecycleBinBottomSort(context)
|
||||||
)
|
} else null
|
||||||
} else {
|
)
|
||||||
SortDialogFragment.getInstance(
|
|
||||||
PreferencesUtil.getListSort(context),
|
|
||||||
PreferencesUtil.getAscendingSort(context),
|
|
||||||
PreferencesUtil.getGroupsBeforeSort(context)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
sortDialogFragment.show(childFragmentManager, "sortDialog")
|
sortDialogFragment.show(childFragmentManager, "sortDialog")
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@@ -165,9 +155,6 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
|
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
|
||||||
mRecycleBinEnable = database?.isRecycleBinEnabled == true
|
|
||||||
mRecycleBin = database?.recycleBin
|
|
||||||
|
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
database?.let { database ->
|
database?.let { database ->
|
||||||
mAdapter = NodesAdapter(context, database).apply {
|
mAdapter = NodesAdapter(context, database).apply {
|
||||||
@@ -312,6 +299,11 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun containsRecycleBin(nodes: List<Node>): Boolean {
|
||||||
|
return mDatabase?.isRecycleBinEnabled == true
|
||||||
|
&& nodes.any { it == mDatabase?.recycleBin }
|
||||||
|
}
|
||||||
|
|
||||||
fun actionNodesCallback(database: ContextualDatabase,
|
fun actionNodesCallback(database: ContextualDatabase,
|
||||||
nodes: List<Node>,
|
nodes: List<Node>,
|
||||||
menuListener: NodesActionMenuListener?,
|
menuListener: NodesActionMenuListener?,
|
||||||
@@ -336,8 +328,7 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
|||||||
// Open and Edit for a single item
|
// Open and Edit for a single item
|
||||||
if (nodes.size == 1) {
|
if (nodes.size == 1) {
|
||||||
// Edition
|
// Edition
|
||||||
if (database.isReadOnly
|
if (database.isReadOnly || containsRecycleBin(nodes)) {
|
||||||
|| (mRecycleBinEnable && nodes[0] == mRecycleBin)) {
|
|
||||||
menu?.removeItem(R.id.menu_edit)
|
menu?.removeItem(R.id.menu_edit)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -357,8 +348,7 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deletion
|
// Deletion
|
||||||
if (database.isReadOnly
|
if (database.isReadOnly || containsRecycleBin(nodes)) {
|
||||||
|| (mRecycleBinEnable && nodes.any { it == mRecycleBin })) {
|
|
||||||
menu?.removeItem(R.id.menu_delete)
|
menu?.removeItem(R.id.menu_delete)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ class DatabaseTaskProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initServiceConnection() {
|
private fun initServiceConnection() {
|
||||||
|
stopDialog()
|
||||||
if (serviceConnection == null) {
|
if (serviceConnection == null) {
|
||||||
serviceConnection = object : ServiceConnection {
|
serviceConnection = object : ServiceConnection {
|
||||||
override fun onBindingDied(name: ComponentName?) {
|
override fun onBindingDied(name: ComponentName?) {
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ object SearchHelper {
|
|||||||
&& !searchInfo.containsOnlyNullValues()) {
|
&& !searchInfo.containsOnlyNullValues()) {
|
||||||
// If search provide results
|
// If search provide results
|
||||||
database.createVirtualGroupFromSearchInfo(
|
database.createVirtualGroupFromSearchInfo(
|
||||||
searchInfo.toString(),
|
searchInfoString = searchInfo.toString(),
|
||||||
searchInfo.isASearchByDomain(),
|
searchInfoByDomain = searchInfo.isASearchByDomain(),
|
||||||
MAX_SEARCH_ENTRY
|
max = MAX_SEARCH_ENTRY
|
||||||
)?.let { searchGroup ->
|
)?.let { searchGroup ->
|
||||||
if (searchGroup.numberOfChildEntries > 0) {
|
if (searchGroup.numberOfChildEntries > 0) {
|
||||||
searchWithoutUI = true
|
searchWithoutUI = true
|
||||||
|
|||||||
@@ -70,8 +70,12 @@ open class SettingsActivity
|
|||||||
// To apply navigation bar with background color
|
// To apply navigation bar with background color
|
||||||
/* TODO Settings nav bar
|
/* TODO Settings nav bar
|
||||||
setTransparentNavigationBar {
|
setTransparentNavigationBar {
|
||||||
coordinatorLayout?.applyWindowInsets(WindowInsetPosition.TOP)
|
coordinatorLayout?.applyWindowInsets(EnumSet.of(
|
||||||
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM)
|
WindowInsetPosition.TOP_MARGINS,
|
||||||
|
WindowInsetPosition.BOTTOM_MARGINS,
|
||||||
|
WindowInsetPosition.START_MARGINS,
|
||||||
|
WindowInsetPosition.END_MARGINS,
|
||||||
|
))
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
mExternalFileHelper = ExternalFileHelper(this)
|
mExternalFileHelper = ExternalFileHelper(this)
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import android.animation.AnimatorSet
|
|||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
@@ -58,7 +57,6 @@ import androidx.core.view.WindowInsetsCompat
|
|||||||
import androidx.core.view.forEach
|
import androidx.core.view.forEach
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.core.view.updatePadding
|
|
||||||
import androidx.core.view.updatePaddingRelative
|
import androidx.core.view.updatePaddingRelative
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
@@ -66,6 +64,7 @@ import com.kunzisoft.keepass.R
|
|||||||
import com.kunzisoft.keepass.database.helper.getLocalizedMessage
|
import com.kunzisoft.keepass.database.helper.getLocalizedMessage
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
|
import java.util.EnumSet
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -304,10 +303,9 @@ fun CollapsingToolbarLayout.changeTitleColor(color: Int) {
|
|||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, applyWindowInsets: () -> Unit) {
|
fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, applyWindowInsets: () -> Unit) {
|
||||||
// Only in portrait
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1
|
|
||||||
&& resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
window.navigationBarColor = ContextCompat.getColor(this, R.color.surface_selector)
|
window.navigationBarColor = ContextCompat.getColor(this, R.color.surface_selector)
|
||||||
if (applyToStatusBar) {
|
if (applyToStatusBar) {
|
||||||
@@ -323,7 +321,7 @@ fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, appl
|
|||||||
/**
|
/**
|
||||||
* Apply a margin to a view to fix the window inset
|
* Apply a margin to a view to fix the window inset
|
||||||
*/
|
*/
|
||||||
fun View.applyWindowInsets(position: WindowInsetPosition = WindowInsetPosition.BOTTOM) {
|
fun View.applyWindowInsets(positions: EnumSet<WindowInsetPosition>) {
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets ->
|
ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets ->
|
||||||
var consumed = false
|
var consumed = false
|
||||||
|
|
||||||
@@ -339,52 +337,78 @@ fun View.applyWindowInsets(position: WindowInsetPosition = WindowInsetPosition.B
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()
|
||||||
when (position) {
|
or WindowInsetsCompat.Type.displayCutout()
|
||||||
WindowInsetPosition.TOP -> {
|
or WindowInsetsCompat.Type.ime())
|
||||||
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
|
|
||||||
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
val isRtl = layoutDirection == View.LAYOUT_DIRECTION_RTL
|
||||||
topMargin = insets.top
|
|
||||||
|
val wantTopMargins = positions.contains(WindowInsetPosition.TOP_MARGINS)
|
||||||
|
val wantBottomMargins = positions.contains(WindowInsetPosition.BOTTOM_MARGINS)
|
||||||
|
val wantStartMargins = positions.contains(WindowInsetPosition.START_MARGINS)
|
||||||
|
val wantEndMargins = positions.contains(WindowInsetPosition.END_MARGINS)
|
||||||
|
|
||||||
|
if (view.layoutParams is ViewGroup.MarginLayoutParams
|
||||||
|
&& (wantTopMargins || wantBottomMargins || wantStartMargins || wantEndMargins)) {
|
||||||
|
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
if (wantTopMargins) {
|
||||||
|
topMargin = insets.top
|
||||||
|
}
|
||||||
|
if (wantBottomMargins) {
|
||||||
|
bottomMargin = insets.bottom
|
||||||
|
}
|
||||||
|
if (wantStartMargins) {
|
||||||
|
if (isRtl) {
|
||||||
|
rightMargin = insets.right
|
||||||
|
} else {
|
||||||
|
leftMargin = insets.left
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (wantEndMargins) {
|
||||||
WindowInsetPosition.LEGIT_TOP -> {
|
if (isRtl) {
|
||||||
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
|
leftMargin = insets.left
|
||||||
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
} else {
|
||||||
topMargin = 0
|
rightMargin = insets.right
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowInsetPosition.BOTTOM -> {
|
|
||||||
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
|
|
||||||
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
|
||||||
bottomMargin = insets.bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowInsetPosition.BOTTOM_IME -> {
|
|
||||||
val imeHeight = windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom
|
|
||||||
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
|
|
||||||
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
|
||||||
bottomMargin = if (imeHeight > 1) 0 else insets.bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowInsetPosition.TOP_BOTTOM_IME -> {
|
|
||||||
val imeHeight = windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom
|
|
||||||
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
|
|
||||||
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
|
||||||
topMargin = insets.top
|
|
||||||
bottomMargin = if (imeHeight > 1) imeHeight else 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val wantTopPadding = positions.contains(WindowInsetPosition.TOP_PADDING)
|
||||||
|
val wantBottomPadding = positions.contains(WindowInsetPosition.BOTTOM_PADDING)
|
||||||
|
val wantStartPadding = positions.contains(WindowInsetPosition.START_PADDING)
|
||||||
|
val wantEndPadding = positions.contains(WindowInsetPosition.END_PADDING)
|
||||||
|
|
||||||
|
if (wantTopPadding || wantBottomPadding || wantStartPadding || wantEndPadding) {
|
||||||
|
val topPadding = if (wantTopPadding) insets.top else 0
|
||||||
|
val bottomPadding = if (wantBottomPadding) insets.bottom else 0
|
||||||
|
var leftPadding = 0
|
||||||
|
var rightPadding = 0
|
||||||
|
|
||||||
|
if (wantStartPadding) {
|
||||||
|
if (isRtl) {
|
||||||
|
rightPadding = insets.right
|
||||||
|
} else {
|
||||||
|
leftPadding = insets.left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wantEndPadding) {
|
||||||
|
if (isRtl) {
|
||||||
|
leftPadding = insets.left
|
||||||
|
} else {
|
||||||
|
rightPadding = insets.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setPadding(leftPadding, topPadding, rightPadding, bottomPadding)
|
||||||
|
}
|
||||||
|
|
||||||
// If any of the children consumed the insets, return an appropriate value
|
// If any of the children consumed the insets, return an appropriate value
|
||||||
if (consumed) WindowInsetsCompat.CONSUMED else windowInsets
|
if (consumed) WindowInsetsCompat.CONSUMED else windowInsets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class WindowInsetPosition {
|
enum class WindowInsetPosition {
|
||||||
TOP, BOTTOM, LEGIT_TOP, BOTTOM_IME, TOP_BOTTOM_IME
|
TOP_MARGINS, BOTTOM_MARGINS, START_MARGINS, END_MARGINS,
|
||||||
|
TOP_PADDING, BOTTOM_PADDING, START_PADDING, END_PADDING,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/activity_entry_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:filterTouchesWhenObscured="true">
|
android:filterTouchesWhenObscured="true">
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
--><resources>
|
--><resources>
|
||||||
<string name="feedback">Σχόλια</string>
|
<string name="feedback">Σχόλια</string>
|
||||||
<string name="homepage">Αρχική Σελίδα</string>
|
<string name="homepage">Αρχική Σελίδα</string>
|
||||||
<string name="about_description">Το KeePassDX είναι μία εφαρμογή Android του διαχειριστή κωδικών KeePass</string>
|
<string name="about_description">Υλοποίηση του διαχειριστή κωδικών πρόσβασης KeePass για Android.</string>
|
||||||
<string name="accept">Αποδοχή</string>
|
<string name="accept">Αποδοχή</string>
|
||||||
<string name="add_entry">Προσθήκη καταχώρησης</string>
|
<string name="add_entry">Προσθήκη καταχώρησης</string>
|
||||||
<string name="add_group">Προσθήκη ομάδας</string>
|
<string name="add_group">Προσθήκη ομάδας</string>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
--><resources>
|
--><resources>
|
||||||
<string name="feedback">Comentarios</string>
|
<string name="feedback">Comentarios</string>
|
||||||
<string name="homepage">Página de inicio</string>
|
<string name="homepage">Página de inicio</string>
|
||||||
<string name="about_description">Implementación para Android del gestor de contraseñas KeePass</string>
|
<string name="about_description">Implementación para Android del gestor de contraseñas KeePass.</string>
|
||||||
<string name="accept">Aceptar</string>
|
<string name="accept">Aceptar</string>
|
||||||
<string name="add_entry">Añadir apunte</string>
|
<string name="add_entry">Añadir apunte</string>
|
||||||
<string name="add_group">Añadir grupo</string>
|
<string name="add_group">Añadir grupo</string>
|
||||||
@@ -691,4 +691,5 @@
|
|||||||
<string name="generate_keyfile">Generar archivo de claves</string>
|
<string name="generate_keyfile">Generar archivo de claves</string>
|
||||||
<string name="recursive_number_entries_title">Número recursivo de entradas</string>
|
<string name="recursive_number_entries_title">Número recursivo de entradas</string>
|
||||||
<string name="hide_templates_summary">Las plantillas no se muestran</string>
|
<string name="hide_templates_summary">Las plantillas no se muestran</string>
|
||||||
|
<string name="error_otp_secret_length">La clave secreta debe tener al menos %1$d caracteres.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
<string name="content_description_update_from_list">I-update</string>
|
<string name="content_description_update_from_list">I-update</string>
|
||||||
<string name="content_description_keyboard_close_fields">Isara ang mga field</string>
|
<string name="content_description_keyboard_close_fields">Isara ang mga field</string>
|
||||||
<string name="select_to_copy">Piliin para kopyahin ang %1$s sa clipboard</string>
|
<string name="select_to_copy">Piliin para kopyahin ang %1$s sa clipboard</string>
|
||||||
<string name="html_about_licence">KeePassDX © %1$d Ang Kunzisoft ay <strong>open source</strong> at <strong>walang advertising</strong>. \nIbinigay ito nang as is, sa ilalim <strong>GPLv3</strong> na lisensya, nang walang anumang warranty.</string>
|
<string name="html_about_licence">Ang KeePassDX © Kunzisoft ay open source at walang kasamang patalastas.\nIbinibigay ito nang buo sa ilalim ng lisensiyang GPLv3, nang walang anumang garantiya.</string>
|
||||||
<string name="html_about_privacy"><strong>Walang user data ay kinukuha</strong>, ang aplikasyon na ito ay hindi kumokonekta sa anumang server, gumanagana ng lokal at ganap na ginagalang ang pagkapribado ng mga gumagamit.</string>
|
<string name="html_about_privacy"><strong>Walang user data ay kinukuha</strong>, ang aplikasyon na ito ay hindi kumokonekta sa anumang server, gumanagana ng lokal at ganap na ginagalang ang pagkapribado ng mga gumagamit.</string>
|
||||||
<string name="html_about_contribution">Para <strong>panatilihin ang aming kalayaan</strong>, <strong>ayusin ang mga bug</strong>, <strong>magdagdag ng mga feature</strong> at <strong>maging palaging aktibo</strong>, umaasa kami sa iyong <strong>kontribusyon</strong>.</string>
|
<string name="html_about_contribution">Para <strong>panatilihin ang aming kalayaan</strong>, <strong>ayusin ang mga bug</strong>, <strong>magdagdag ng mga feature</strong> at <strong>maging palaging aktibo</strong>, umaasa kami sa iyong <strong>kontribusyon</strong>.</string>
|
||||||
<string name="entry_accessed">Na-access</string>
|
<string name="entry_accessed">Na-access</string>
|
||||||
|
|||||||
@@ -383,7 +383,7 @@
|
|||||||
<string name="education_lock_summary">Zaključaj bazu podataka brzo, aplikaciju možeš postaviti tako da bazu nakon nekog vremena zaključa i kad se ekran isključi.</string>
|
<string name="education_lock_summary">Zaključaj bazu podataka brzo, aplikaciju možeš postaviti tako da bazu nakon nekog vremena zaključa i kad se ekran isključi.</string>
|
||||||
<string name="show_recent_files_summary">Prikaži mjesto nedavnih baza podataka</string>
|
<string name="show_recent_files_summary">Prikaži mjesto nedavnih baza podataka</string>
|
||||||
<string name="education_device_unlock_summary">Za brzo otključavanje baze podataka, poveži lozinku sa skeniranom biometrijom ili podacima za prijavu uređaja.</string>
|
<string name="education_device_unlock_summary">Za brzo otključavanje baze podataka, poveži lozinku sa skeniranom biometrijom ili podacima za prijavu uređaja.</string>
|
||||||
<string name="html_text_donation"><strong>Doprinosom</strong> projektu <i>(novčano, kodom, prijevodom)</i> pomažeš mu da živi i napreduje, a također stječeš pravo na postupak otključavanja <strong>tema</strong>.</strong></string>
|
<string name="html_text_donation"><strong>Doprinosom</strong> projektu <i>(novčano, kodom, prijevodom)</i> pomažeš mu da živi i napreduje, a također stječeš pravo na postupak otključavanja <strong>tema</strong>.</string>
|
||||||
<string name="kdf_explanation">Za stvaranje ključa za algoritam šifriranja, glavni ključ se transformira pomoću funkcije za generiranje ključeva koja sadrži slučajnu komponentu.</string>
|
<string name="kdf_explanation">Za stvaranje ključa za algoritam šifriranja, glavni ključ se transformira pomoću funkcije za generiranje ključeva koja sadrži slučajnu komponentu.</string>
|
||||||
<string name="lock_database_back_root_summary">Zaključaj bazu podataka kad korisnik pritisne gumb za natrag na glavnom ekranu</string>
|
<string name="lock_database_back_root_summary">Zaključaj bazu podataka kad korisnik pritisne gumb za natrag na glavnom ekranu</string>
|
||||||
<string name="hide_broken_locations_title">Sakrij pokvarene poveznice baze podataka</string>
|
<string name="hide_broken_locations_title">Sakrij pokvarene poveznice baze podataka</string>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
--><resources>
|
--><resources>
|
||||||
<string name="feedback">משוב</string>
|
<string name="feedback">משוב</string>
|
||||||
<string name="homepage">דף הבית</string>
|
<string name="homepage">דף הבית</string>
|
||||||
<string name="about_description">מימוש אנדרואיד של מנהל הסיסמאות KeePass</string>
|
<string name="about_description">מימוש אנדרואיד של מנהל הסיסמאות KeePass.</string>
|
||||||
<string name="accept">קבל</string>
|
<string name="accept">קבל</string>
|
||||||
<string name="add_entry">הוסף ערך</string>
|
<string name="add_entry">הוסף ערך</string>
|
||||||
<string name="add_group">הוסף קבוצה</string>
|
<string name="add_group">הוסף קבוצה</string>
|
||||||
|
|||||||
@@ -24,12 +24,12 @@
|
|||||||
<string name="add_entry">Dodaj wpis</string>
|
<string name="add_entry">Dodaj wpis</string>
|
||||||
<string name="add_group">Dodaj grupę</string>
|
<string name="add_group">Dodaj grupę</string>
|
||||||
<string name="encryption_algorithm">Algorytm szyfrowania</string>
|
<string name="encryption_algorithm">Algorytm szyfrowania</string>
|
||||||
<string name="app_timeout">Koniec czasu</string>
|
<string name="app_timeout">Limit czasu</string>
|
||||||
<string name="app_timeout_summary">Czas bezczynności przed zablokowaniem bazy danych</string>
|
<string name="app_timeout_summary">Czas bezczynności przed zablokowaniem bazy danych</string>
|
||||||
<string name="application">Aplikacja</string>
|
<string name="application">Aplikacja</string>
|
||||||
<string name="menu_app_settings">Ustawienia ogólne</string>
|
<string name="menu_app_settings">Ustawienia ogólne</string>
|
||||||
<string name="brackets">Nawiasy</string>
|
<string name="brackets">Nawiasy</string>
|
||||||
<string name="file_manager_install_description">Do tworzenia, otwierania i zapisywania plików bazy danych potrzebny jest menedżer plików, który akceptuje działanie Intent Action ACTION_CREATE_DOCUMENT i ACTION_OPEN_DOCUMENT.</string>
|
<string name="file_manager_install_description">Do tworzenia, otwierania i zapisywania plików bazy danych wymagany jest menedżer plików akceptujący zamierzone działania ACTION_CREATE_DOCUMENT i ACTION_OPEN_DOCUMENT.</string>
|
||||||
<string name="clipboard_cleared">Schowek został wyczyszczony</string>
|
<string name="clipboard_cleared">Schowek został wyczyszczony</string>
|
||||||
<string name="clipboard_timeout">Czas wygaśnięcia schowka</string>
|
<string name="clipboard_timeout">Czas wygaśnięcia schowka</string>
|
||||||
<string name="clipboard_timeout_summary">Czas przechowywania w schowku (jeśli jest obsługiwany przez urządzenie)</string>
|
<string name="clipboard_timeout_summary">Czas przechowywania w schowku (jeśli jest obsługiwany przez urządzenie)</string>
|
||||||
@@ -60,11 +60,11 @@
|
|||||||
<string name="error_invalid_path">Upewnij się, że ścieżka jest prawidłowa.</string>
|
<string name="error_invalid_path">Upewnij się, że ścieżka jest prawidłowa.</string>
|
||||||
<string name="error_no_name">Wpisz nazwę.</string>
|
<string name="error_no_name">Wpisz nazwę.</string>
|
||||||
<string name="error_nokeyfile">Wybierz plik klucza.</string>
|
<string name="error_nokeyfile">Wybierz plik klucza.</string>
|
||||||
<string name="error_out_of_memory">W urządzeniu zabrakło pamięci do załadowania całej bazy danych.</string>
|
<string name="error_out_of_memory">Brak pamięci na załadowanie całej bazy danych.</string>
|
||||||
<string name="error_pass_gen_type">Należy wybrać co najmniej jeden rodzaj generowania hasła.</string>
|
<string name="error_pass_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 transformacji” są zbyt wysokie. Ustaw na 2147483648.</string>
|
||||||
<string name="error_wrong_length">Wprowadź dodatnią liczbę całkowitą w polu \"Długość\".</string>
|
<string name="error_wrong_length">Wprowadź dodatnią liczbę całkowitą w polu „Długość”.</string>
|
||||||
<string name="file_browser">Menedżer plików</string>
|
<string name="file_browser">Menedżer plików</string>
|
||||||
<string name="generate_password">Generuj hasło</string>
|
<string name="generate_password">Generuj hasło</string>
|
||||||
<string name="hint_conf_pass">Potwierdź hasło</string>
|
<string name="hint_conf_pass">Potwierdź hasło</string>
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
<string name="invalid_credentials">Nie można odczytać uwierzytelnień.</string>
|
<string name="invalid_credentials">Nie można odczytać uwierzytelnień.</string>
|
||||||
<string name="invalid_db_sig">Nie można rozpoznać formatu bazy danych.</string>
|
<string name="invalid_db_sig">Nie można rozpoznać formatu bazy danych.</string>
|
||||||
<string name="length">Długość</string>
|
<string name="length">Długość</string>
|
||||||
<string name="list_size_title">Wielkość listy grup</string>
|
<string name="list_size_title">Rozmiar elementów listy</string>
|
||||||
<string name="list_size_summary">Wielkość tekstu w liście grup</string>
|
<string name="list_size_summary">Rozmiar tekstu na liście elementów</string>
|
||||||
<string name="loading_database">Wczytywanie bazy danych…</string>
|
<string name="loading_database">Wczytywanie bazy danych…</string>
|
||||||
<string name="lowercase">Małe litery</string>
|
<string name="lowercase">Małe litery</string>
|
||||||
<string name="hide_password_title">Ukryj hasła</string>
|
<string name="hide_password_title">Ukryj hasła</string>
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
<string name="progress_create">Tworzenie nowej bazy danych…</string>
|
<string name="progress_create">Tworzenie nowej bazy danych…</string>
|
||||||
<string name="progress_title">Pracuję…</string>
|
<string name="progress_title">Pracuję…</string>
|
||||||
<string name="content_description_remove_from_list">Usuń</string>
|
<string name="content_description_remove_from_list">Usuń</string>
|
||||||
<string name="root">Root</string>
|
<string name="root">Główny</string>
|
||||||
<string name="rounds">Rundy szyfrowania</string>
|
<string name="rounds">Rundy szyfrowania</string>
|
||||||
<string name="rounds_explanation">Dodatkowe rundy szyfrowania zapewniają lepszą ochronę przed atakami typu brute force, ale mogą znacznie spowolnić ładowanie i zapisywanie.</string>
|
<string name="rounds_explanation">Dodatkowe rundy szyfrowania zapewniają lepszą ochronę przed atakami typu brute force, ale mogą znacznie spowolnić ładowanie i zapisywanie.</string>
|
||||||
<string name="saving_database">Zapisywanie bazy danych…</string>
|
<string name="saving_database">Zapisywanie bazy danych…</string>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft jest <strong>open source</strong> i <strong>bez reklam</strong>. \nJest on dostarczany w stanie, zgodnie z licencją <strong>GPLv3</strong> bez żadnych gwarancji.</string>
|
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft jest <strong>open source</strong> i <strong>bez reklam</strong>. \nJest on dostarczany w stanie, zgodnie z licencją <strong>GPLv3</strong> 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ęci” KDF.</string>
|
||||||
<string name="error_string_key">Każdy ciąg musi mieć nazwę pola.</string>
|
<string name="error_string_key">Każdy ciąg musi mieć nazwę pola.</string>
|
||||||
<string name="error_autofill_enable_service">Nie można włączyć usługi autouzupełniania.</string>
|
<string name="error_autofill_enable_service">Nie można włączyć usługi autouzupełniania.</string>
|
||||||
<string name="field_name">Nazwa pola</string>
|
<string name="field_name">Nazwa pola</string>
|
||||||
@@ -149,8 +149,8 @@
|
|||||||
<string name="menu_move">Przenieś</string>
|
<string name="menu_move">Przenieś</string>
|
||||||
<string name="menu_paste">Wklej</string>
|
<string name="menu_paste">Wklej</string>
|
||||||
<string name="menu_cancel">Anuluj</string>
|
<string name="menu_cancel">Anuluj</string>
|
||||||
<string name="menu_file_selection_read_only">Chroniony przed zapisem</string>
|
<string name="menu_file_selection_read_only">Ochrona przed zapisem</string>
|
||||||
<string name="menu_open_file_read_and_write">Modyfikowalne</string>
|
<string name="menu_open_file_read_and_write">Modyfikowalny</string>
|
||||||
<string name="protection">Ochrona</string>
|
<string name="protection">Ochrona</string>
|
||||||
<string name="read_only">Ochrona przed zapisem</string>
|
<string name="read_only">Ochrona przed zapisem</string>
|
||||||
<string name="read_only_warning">KeePassDX potrzebuje uprawnień do zapisu, aby mógł modyfikować bazę danych.</string>
|
<string name="read_only_warning">KeePassDX potrzebuje uprawnień do zapisu, aby mógł modyfikować bazę danych.</string>
|
||||||
@@ -208,12 +208,12 @@
|
|||||||
<string name="assign_master_key">Przypisz klucz główny</string>
|
<string name="assign_master_key">Przypisz klucz główny</string>
|
||||||
<string name="create_keepass_file">Utwórz nowy sejf</string>
|
<string name="create_keepass_file">Utwórz nowy sejf</string>
|
||||||
<string name="recycle_bin_title">Wykorzystanie kosza</string>
|
<string name="recycle_bin_title">Wykorzystanie kosza</string>
|
||||||
<string name="recycle_bin_summary">Przenosi grupy i wpisy do grupy \"Kosz\" przed usunięciem</string>
|
<string name="recycle_bin_summary">Przenosi grupy i wpisy do grupy „Kosz” przed usunięciem</string>
|
||||||
<string name="monospace_font_fields_enable_title">Czcionka pola</string>
|
<string name="monospace_font_fields_enable_title">Czcionka pola</string>
|
||||||
<string name="monospace_font_fields_enable_summary">Zmień czcionkę użytą w polach, aby poprawić widoczność znaków</string>
|
<string name="monospace_font_fields_enable_summary">Zmień czcionkę użytą w polach, aby poprawić widoczność znaków</string>
|
||||||
<string name="allow_copy_password_title">Ochrona schowka</string>
|
<string name="allow_copy_password_title">Ochrona schowka</string>
|
||||||
<string name="allow_copy_password_summary">Zezwalanie na kopiowanie hasła wejściowego i chronionych pól do schowka</string>
|
<string name="allow_copy_password_summary">Zezwalanie na kopiowanie hasła wejściowego i chronionych pól do schowka</string>
|
||||||
<string name="allow_copy_password_warning">Ostrzeżenie: Schowek jest współużytkowany przez wszystkie aplikacje. Jeśli poufne dane są kopiowane, inne oprogramowanie może je odzyskać.</string>
|
<string name="allow_copy_password_warning">Ostrzeżenie: schowek jest współużytkowany przez wszystkie aplikacje. Jeśli poufne dane są kopiowane, inne oprogramowanie może je odzyskać.</string>
|
||||||
<string name="database_name_title">Nazwa bazy danych</string>
|
<string name="database_name_title">Nazwa bazy danych</string>
|
||||||
<string name="database_description_title">Opis bazy danych</string>
|
<string name="database_description_title">Opis bazy danych</string>
|
||||||
<string name="database_version_title">Wersja bazy danych</string>
|
<string name="database_version_title">Wersja bazy danych</string>
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
<string name="magic_keyboard_title">Magikeyboard</string>
|
<string name="magic_keyboard_title">Magikeyboard</string>
|
||||||
<string name="magic_keyboard_explanation_summary">Aktywuj niestandardową klawiaturę wypełniającą hasła i wszystkie pola tożsamości</string>
|
<string name="magic_keyboard_explanation_summary">Aktywuj niestandardową klawiaturę wypełniającą hasła i wszystkie pola tożsamości</string>
|
||||||
<string name="allow_no_password_title">Zezwalaj na brak klucza głównego</string>
|
<string name="allow_no_password_title">Zezwalaj na brak klucza głównego</string>
|
||||||
<string name="allow_no_password_summary">Umożliwia naciśnięcie przycisku \"Otwórz\", jeśli nie wybrano żadnych poświadczeń</string>
|
<string name="allow_no_password_summary">Umożliwia naciśnięcie przycisku „Otwórz”, jeśli nie wybrano żadnych poświadczeń</string>
|
||||||
<string name="enable_education_screens_title">Wskazówki edukacyjne</string>
|
<string name="enable_education_screens_title">Wskazówki edukacyjne</string>
|
||||||
<string name="enable_education_screens_summary">Podświetl elementy, aby dowiedzieć się, jak działa aplikacja</string>
|
<string name="enable_education_screens_summary">Podświetl elementy, aby dowiedzieć się, jak działa aplikacja</string>
|
||||||
<string name="reset_education_screens_title">Zresetuj wskazówki edukacyjne</string>
|
<string name="reset_education_screens_title">Zresetuj wskazówki edukacyjne</string>
|
||||||
@@ -248,10 +248,7 @@
|
|||||||
<string name="education_entry_new_field_summary">Zarejestruj dodatkowe pole, dodaj wartość i opcjonalnie chroń je.</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. \n \n„Ochrona przed zapisem” zapobiega niezamierzonym zmianom w bazie danych. \n„Modyfikowalny” pozwala dodawać, usuwać lub modyfikować wszystkie elementy według uznania.</string>
|
||||||
\n
|
|
||||||
\n\"Ochrona przed zapisem\" zapobiega niezamierzonych zmian w bazie danych.
|
|
||||||
\n\"Modyfikowalne\" pozwala dodawać, usuwać lub modyfikować wszystkie elementy, jak chcesz.</string>
|
|
||||||
<string name="education_field_copy_title">Skopiuj pole</string>
|
<string name="education_field_copy_title">Skopiuj pole</string>
|
||||||
<string name="education_field_copy_summary">Skopiowane pola można wkleić w dowolnym miejscu.
|
<string name="education_field_copy_summary">Skopiowane pola można wkleić w dowolnym miejscu.
|
||||||
\n
|
\n
|
||||||
@@ -295,17 +292,17 @@
|
|||||||
<string name="keyboard_notification_entry_clear_close_summary">Zamknij bazę danych podczas zamykania powiadomienia</string>
|
<string name="keyboard_notification_entry_clear_close_summary">Zamknij bazę danych podczas zamykania powiadomienia</string>
|
||||||
<string name="keyboard_appearance_category">Wygląd</string>
|
<string name="keyboard_appearance_category">Wygląd</string>
|
||||||
<string name="keyboard_theme_title">Motyw klawiatury</string>
|
<string name="keyboard_theme_title">Motyw klawiatury</string>
|
||||||
<string name="keyboard_keys_category">Klawiatura</string>
|
<string name="keyboard_keys_category">Klawisze</string>
|
||||||
<string name="keyboard_key_vibrate_title">Wibracja po naciśnięciu klawisza</string>
|
<string name="keyboard_key_vibrate_title">Wibracje przy naciskaniu klawiszy</string>
|
||||||
<string name="keyboard_key_sound_title">Dźwięk przy naciśnięciu</string>
|
<string name="keyboard_key_sound_title">Dźwięk przy naciskaniu klawiszy</string>
|
||||||
<string name="do_not_kill_app">Nie zabijaj aplikacji…</string>
|
<string name="do_not_kill_app">Nie zamykaj aplikacji…</string>
|
||||||
<string name="lock_database_back_root_title">Wciśnij \'Powrót\', aby zablokować</string>
|
<string name="lock_database_back_root_title">Naciśnij „Wstecz”, aby zablokować</string>
|
||||||
<string name="lock_database_back_root_summary">Zablokuj bazę danych, gdy użytkownik kliknie przycisk \"Wstecz\" na ekranie głównym</string>
|
<string name="lock_database_back_root_summary">Zablokuj bazę danych, gdy użytkownik kliknie przycisk „Wstecz” na ekranie głównym</string>
|
||||||
<string name="clear_clipboard_notification_title">Wyczyść po zamknięciu</string>
|
<string name="clear_clipboard_notification_title">Wyczyść po zamknięciu</string>
|
||||||
<string name="clear_clipboard_notification_summary">Blokowanie bazy danych po wygaśnięciu czasu trwania schowka lub zamknięciu powiadomienia po rozpoczęciu korzystania z niej</string>
|
<string name="clear_clipboard_notification_summary">Blokowanie bazy danych po wygaśnięciu czasu trwania schowka lub zamknięciu powiadomienia po rozpoczęciu korzystania z niej</string>
|
||||||
<string name="recycle_bin">Kosz</string>
|
<string name="recycle_bin">Kosz</string>
|
||||||
<string name="keyboard_selection_entry_title">Wybór wpisu</string>
|
<string name="keyboard_selection_entry_title">Wybór wpisu</string>
|
||||||
<string name="keyboard_selection_entry_summary">Podczas przeglądania wpisu w KeePassDX zapełnij Magikeyboard tym wpisem</string>
|
<string name="keyboard_selection_entry_summary">Podczas przeglądania wpisu w KeePassDX zapełnij Magikeyboard tym wpisem</string>
|
||||||
<string name="delete_entered_password_title">Usuń hasło</string>
|
<string name="delete_entered_password_title">Usuń hasło</string>
|
||||||
<string name="delete_entered_password_summary">Usuwa hasło wprowadzone po próbie połączenia z bazą danych</string>
|
<string name="delete_entered_password_summary">Usuwa hasło wprowadzone po próbie połączenia z bazą danych</string>
|
||||||
<string name="content_description_open_file">Otwórz plik</string>
|
<string name="content_description_open_file">Otwórz plik</string>
|
||||||
@@ -367,7 +364,7 @@
|
|||||||
<string name="compression_none">Żadna</string>
|
<string name="compression_none">Żadna</string>
|
||||||
<string name="compression_gzip">Gzip</string>
|
<string name="compression_gzip">Gzip</string>
|
||||||
<string name="device_keyboard_setting_title">Ustawienia klawiatury urządzenia</string>
|
<string name="device_keyboard_setting_title">Ustawienia klawiatury urządzenia</string>
|
||||||
<string name="error_invalid_OTP">Nieprawidłowy klucz OTP.</string>
|
<string name="error_invalid_OTP">Nieprawidłowy klucz tajny OTP.</string>
|
||||||
<string name="error_disallow_no_credentials">Należy ustawić co najmniej jedno poświadczenie.</string>
|
<string name="error_disallow_no_credentials">Należy ustawić co najmniej jedno poświadczenie.</string>
|
||||||
<string name="error_otp_secret_key">Klucz tajny musi być w formacie Base32.</string>
|
<string name="error_otp_secret_key">Klucz tajny musi być w formacie Base32.</string>
|
||||||
<string name="error_otp_counter">Licznik musi być między %1$d a %2$d.</string>
|
<string name="error_otp_counter">Licznik musi być między %1$d a %2$d.</string>
|
||||||
@@ -391,11 +388,11 @@
|
|||||||
<string name="keystore_not_accessible">Magazyn kluczy nie został poprawnie zainicjowany.</string>
|
<string name="keystore_not_accessible">Magazyn kluczy nie został poprawnie zainicjowany.</string>
|
||||||
<string name="recycle_bin_group_title">Kosz grupy</string>
|
<string name="recycle_bin_group_title">Kosz grupy</string>
|
||||||
<string name="enable_auto_save_database_title">Automatycznie zapisuj bazę danych</string>
|
<string name="enable_auto_save_database_title">Automatycznie zapisuj bazę danych</string>
|
||||||
<string name="enable_auto_save_database_summary">Zapisz bazę danych po każdym ważnym działaniu (w trybie „Modyfikowalnym”)</string>
|
<string name="enable_auto_save_database_summary">Zapisz bazę danych po każdym ważnym działaniu (w trybie „Modyfikowalny”)</string>
|
||||||
<string name="entry_attachments">Załączniki</string>
|
<string name="entry_attachments">Załączniki</string>
|
||||||
<string name="menu_restore_entry_history">Przywróć historię</string>
|
<string name="menu_restore_entry_history">Przywróć historię</string>
|
||||||
<string name="menu_delete_entry_history">Usuń historię</string>
|
<string name="menu_delete_entry_history">Usuń historię</string>
|
||||||
<string name="keyboard_auto_go_action_title">Automatyczne działanie klucza</string>
|
<string name="keyboard_auto_go_action_title">Automatyczna akcja klawiszy</string>
|
||||||
<string name="keyboard_auto_go_action_summary">Akcja klawisza „Idź” po naciśnięciu klawisza „Pole”</string>
|
<string name="keyboard_auto_go_action_summary">Akcja klawisza „Idź” po naciśnięciu klawisza „Pole”</string>
|
||||||
<string name="download_attachment">Pobierz %1$s</string>
|
<string name="download_attachment">Pobierz %1$s</string>
|
||||||
<string name="download_initialization">Inicjowanie…</string>
|
<string name="download_initialization">Inicjowanie…</string>
|
||||||
@@ -428,7 +425,7 @@
|
|||||||
<string name="lock_database_show_button_summary">Wyświetla przycisk blokady w interfejsie użytkownika</string>
|
<string name="lock_database_show_button_summary">Wyświetla przycisk blokady w interfejsie użytkownika</string>
|
||||||
<string name="lock_database_show_button_title">Pokaż przycisk blokady</string>
|
<string name="lock_database_show_button_title">Pokaż przycisk blokady</string>
|
||||||
<string name="autofill_preference_title">Ustawienia autouzupełniania</string>
|
<string name="autofill_preference_title">Ustawienia autouzupełniania</string>
|
||||||
<string name="warning_database_link_revoked">Dostęp do pliku anulowany przez menedżera plików</string>
|
<string name="warning_database_link_revoked">Dostęp do pliku anulowany przez menedżer plików</string>
|
||||||
<string name="error_label_exists">Ta etykieta już istnieje.</string>
|
<string name="error_label_exists">Ta etykieta już istnieje.</string>
|
||||||
<string name="autofill_block_restart">Zrestartuj aplikację zawierającą formularz, aby aktywować blokadę.</string>
|
<string name="autofill_block_restart">Zrestartuj aplikację zawierającą formularz, aby aktywować blokadę.</string>
|
||||||
<string name="autofill_block">Blokowanie autouzupełniania</string>
|
<string name="autofill_block">Blokowanie autouzupełniania</string>
|
||||||
@@ -441,9 +438,9 @@
|
|||||||
<string name="autofill_web_domain_blocklist_summary">Lista zablokowanych, która uniemożliwia automatyczne wypełnianie domen internetowych</string>
|
<string name="autofill_web_domain_blocklist_summary">Lista zablokowanych, która uniemożliwia automatyczne wypełnianie domen internetowych</string>
|
||||||
<string name="autofill_web_domain_blocklist_title">Lista zablokowanych domen internetowych</string>
|
<string name="autofill_web_domain_blocklist_title">Lista zablokowanych domen internetowych</string>
|
||||||
<string name="autofill_application_id_blocklist_title">Lista zablokowanych aplikacji</string>
|
<string name="autofill_application_id_blocklist_title">Lista zablokowanych aplikacji</string>
|
||||||
<string name="keyboard_previous_fill_in_summary">Automatycznie przełącz się z powrotem na poprzednią klawiaturę po wykonaniu automatycznej akcji klawiszy</string>
|
<string name="keyboard_previous_fill_in_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury po wykonaniu automatycznej akcji klawiszy</string>
|
||||||
<string name="keyboard_previous_fill_in_title">Przełącz się z powrotem</string>
|
<string name="keyboard_previous_fill_in_title">Przełącz z powrotem</string>
|
||||||
<string name="keyboard_previous_database_credentials_summary">Automatycznie przełącz się z powrotem do poprzedniej klawiatury na ekranie poświadczeń bazy danych</string>
|
<string name="keyboard_previous_database_credentials_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury na ekranie poświadczeń bazy danych</string>
|
||||||
<string name="keyboard_previous_database_credentials_title">Ekran poświadczeń bazy danych</string>
|
<string name="keyboard_previous_database_credentials_title">Ekran poświadczeń bazy danych</string>
|
||||||
<string name="keyboard_change">Przełącz klawiaturę</string>
|
<string name="keyboard_change">Przełącz klawiaturę</string>
|
||||||
<string name="upload_attachment">Prześlij %1$s</string>
|
<string name="upload_attachment">Prześlij %1$s</string>
|
||||||
@@ -451,9 +448,7 @@
|
|||||||
<string name="education_add_attachment_title">Dodaj załącznik</string>
|
<string name="education_add_attachment_title">Dodaj załącznik</string>
|
||||||
<string name="warning_sure_add_file">Czy mimo to dodać plik\?</string>
|
<string name="warning_sure_add_file">Czy mimo to dodać plik\?</string>
|
||||||
<string name="warning_replace_file">Przesłanie tego pliku spowoduje zastąpienie istniejącego.</string>
|
<string name="warning_replace_file">Przesłanie tego pliku spowoduje zastąpienie istniejącego.</string>
|
||||||
<string name="warning_file_too_big">Baza danych KeePass powinna zawierać tylko małe pliki narzędziowe (takie jak pliki kluczy PGP).
|
<string name="warning_file_too_big">Baza danych KeePass powinna zawierać tylko małe pliki narzędziowe (takie jak pliki kluczy PGP). \n \nTwoja baza danych może stać się bardzo duża i obniżyć wydajność w wyniku tego przesyłania.</string>
|
||||||
\n
|
|
||||||
\nTwoja baza danych może stać się bardzo duża i zmniejszyć wydajność dzięki temu wgrywaniu danych.</string>
|
|
||||||
<string name="database_data_remove_unlinked_attachments_summary">Usuwa załączniki znajdujące się w bazie danych, ale niepowiązane z danym wpisem</string>
|
<string name="database_data_remove_unlinked_attachments_summary">Usuwa załączniki znajdujące się w bazie danych, ale niepowiązane z danym wpisem</string>
|
||||||
<string name="database_data_remove_unlinked_attachments_title">Usuń niepołączone dane</string>
|
<string name="database_data_remove_unlinked_attachments_title">Usuń niepołączone dane</string>
|
||||||
<string name="data">Dane</string>
|
<string name="data">Dane</string>
|
||||||
@@ -471,7 +466,7 @@
|
|||||||
<string name="autofill_save_search_info_title">Zapisz informacje wyszukiwania</string>
|
<string name="autofill_save_search_info_title">Zapisz informacje wyszukiwania</string>
|
||||||
<string name="autofill_close_database_summary">Zamknij bazę danych po wybraniu autouzupełniania</string>
|
<string name="autofill_close_database_summary">Zamknij bazę danych po wybraniu autouzupełniania</string>
|
||||||
<string name="autofill_close_database_title">Zamknij bazę danych</string>
|
<string name="autofill_close_database_title">Zamknij bazę danych</string>
|
||||||
<string name="keyboard_previous_lock_summary">Automatycznie przełącz się z powrotem do poprzedniej klawiatury po zablokowaniu bazy danych</string>
|
<string name="keyboard_previous_lock_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury po zablokowaniu bazy danych</string>
|
||||||
<string name="keyboard_previous_lock_title">Zablokuj bazę danych</string>
|
<string name="keyboard_previous_lock_title">Zablokuj bazę danych</string>
|
||||||
<string name="keyboard_save_search_info_summary">Staraj się zapisywać udostępnione informacje podczas dokonywania ręcznego wyboru wpisu, aby ułatwić sobie przyszłe użycie</string>
|
<string name="keyboard_save_search_info_summary">Staraj się zapisywać udostępnione informacje podczas dokonywania ręcznego wyboru wpisu, aby ułatwić sobie przyszłe użycie</string>
|
||||||
<string name="keyboard_save_search_info_title">Zapisz udostępnione informacje</string>
|
<string name="keyboard_save_search_info_title">Zapisz udostępnione informacje</string>
|
||||||
@@ -618,17 +613,13 @@
|
|||||||
<string name="menu_save_copy_to">Zapisz kopię w …</string>
|
<string name="menu_save_copy_to">Zapisz kopię w …</string>
|
||||||
<string name="expired">Wygasłe</string>
|
<string name="expired">Wygasłe</string>
|
||||||
<string name="warning_database_already_opened">Baza danych jest już otwarta, należy ją najpierw zamknąć, aby otworzyć nową</string>
|
<string name="warning_database_already_opened">Baza danych jest już otwarta, należy ją najpierw zamknąć, aby otworzyć nową</string>
|
||||||
<string name="device_unlock_keystore_warning">Ta funkcja umożliwia przechowywanie zaszyfrowanych danych uwierzytelniających w bezpiecznym magazynie kluczy urządzenia.
|
<string name="device_unlock_keystore_warning">Ta funkcja umożliwia przechowywanie zaszyfrowanych danych uwierzytelniających w bezpiecznym magazynie kluczy urządzenia. \n \nMoże nie być w pełni funkcjonalna w zależności od konkretnej implementacji interfejsu API systemu operacyjnego. \n \nSprawdź kompatybilność i bezpieczeństwo magazynu kluczy u producenta urządzenia i twórcy używanego ROM-u.</string>
|
||||||
\n
|
|
||||||
\nW zależności od konkretnej implementacji interfejsu API systemu operacyjnego, może nie być w pełni funkcjonalna.
|
|
||||||
\n
|
|
||||||
\nSprawdź kompatybilność i bezpieczeństwo magazynu kluczy u producenta urządzenia i twórcy używanego ROM-u.</string>
|
|
||||||
<string name="passphrase">Fraza hasła</string>
|
<string name="passphrase">Fraza hasła</string>
|
||||||
<string name="colorize_password_summary">Koloruj znaki hasła według typu</string>
|
<string name="colorize_password_summary">Koloruj znaki hasła według typu</string>
|
||||||
<string name="keyboard_previous_search_title">Ekran wyszukiwania</string>
|
<string name="keyboard_previous_search_title">Ekran wyszukiwania</string>
|
||||||
<string name="entropy">Entropia: %1$s bitowa</string>
|
<string name="entropy">Entropia: %1$s bitowa</string>
|
||||||
<string name="entropy_high">Entropia: Wysoka</string>
|
<string name="entropy_high">Entropia: wysoka</string>
|
||||||
<string name="entropy_calculate">Entropia: Oblicz…</string>
|
<string name="entropy_calculate">Entropia: oblicz…</string>
|
||||||
<string name="at_least_one_char">Co najmniej po jednym znaku z każdego</string>
|
<string name="at_least_one_char">Co najmniej po jednym znaku z każdego</string>
|
||||||
<string name="exclude_ambiguous_chars">Wyklucz niejednoznaczne znaki</string>
|
<string name="exclude_ambiguous_chars">Wyklucz niejednoznaczne znaki</string>
|
||||||
<string name="consider_chars_filter">Rozważ znaki</string>
|
<string name="consider_chars_filter">Rozważ znaki</string>
|
||||||
@@ -640,7 +631,7 @@
|
|||||||
<string name="content_description_passphrase_word_count">Liczba słów frazy hasła</string>
|
<string name="content_description_passphrase_word_count">Liczba słów frazy hasła</string>
|
||||||
<string name="ignore_chars_filter">Ignoruj znaki</string>
|
<string name="ignore_chars_filter">Ignoruj znaki</string>
|
||||||
<string name="colorize_password_title">Koloruj hasła</string>
|
<string name="colorize_password_title">Koloruj hasła</string>
|
||||||
<string name="keyboard_previous_search_summary">Automatycznie przełączaj z powrotem do poprzedniej klawiatury na ekranie wyszukiwania</string>
|
<string name="keyboard_previous_search_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury na ekranie wyszukiwania</string>
|
||||||
<string name="waiting_challenge_request">Oczekiwanie na żądanie wyzwania…</string>
|
<string name="waiting_challenge_request">Oczekiwanie na żądanie wyzwania…</string>
|
||||||
<string name="waiting_challenge_response">Oczekiwanie na odpowiedź na wyzwanie…</string>
|
<string name="waiting_challenge_response">Oczekiwanie na odpowiedź na wyzwanie…</string>
|
||||||
<string name="error_challenge_already_requested">Wyzwanie już zażądane.</string>
|
<string name="error_challenge_already_requested">Wyzwanie już zażądane.</string>
|
||||||
@@ -700,7 +691,7 @@
|
|||||||
<string name="nodes">Węzły</string>
|
<string name="nodes">Węzły</string>
|
||||||
<string name="warning_large_keyfile">Nie zaleca się dodawania dużego pliku klucza, ponieważ może to uniemożliwić otwarcie bazy danych.</string>
|
<string name="warning_large_keyfile">Nie zaleca się dodawania dużego pliku klucza, ponieważ może to uniemożliwić otwarcie bazy danych.</string>
|
||||||
<string name="generate_keyfile">Wygeneruj plik klucza</string>
|
<string name="generate_keyfile">Wygeneruj plik klucza</string>
|
||||||
<string name="recursive_number_entries_summary">Rekurencyjnie oblicza liczbę wpisów w grupie</string>
|
<string name="recursive_number_entries_summary">Rekurencyjnie oblicza liczbę wpisów w grupie</string>
|
||||||
<string name="recursive_number_entries_title">Rekurencyjna liczba wpisów</string>
|
<string name="recursive_number_entries_title">Rekurencyjna liczba wpisów</string>
|
||||||
<string name="hide_templates_title">Ukryj szablony</string>
|
<string name="hide_templates_title">Ukryj szablony</string>
|
||||||
<string name="hide_templates_summary">Szablony nie są wyświetlane</string>
|
<string name="hide_templates_summary">Szablony nie są wyświetlane</string>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
--><resources>
|
--><resources>
|
||||||
<string name="feedback">Geri bildirim</string>
|
<string name="feedback">Geri bildirim</string>
|
||||||
<string name="homepage">Ana Sayfa</string>
|
<string name="homepage">Ana Sayfa</string>
|
||||||
<string name="about_description">KeePass Parola Yöneticisi\'nin Android uygulama uyarlaması</string>
|
<string name="about_description">KeePass Parola Yöneticisi\'nin Android uygulama uyarlaması.</string>
|
||||||
<string name="accept">Kabul et</string>
|
<string name="accept">Kabul et</string>
|
||||||
<string name="add_entry">Girdi ekle</string>
|
<string name="add_entry">Girdi ekle</string>
|
||||||
<string name="edit_entry">Girdi düzenle</string>
|
<string name="edit_entry">Girdi düzenle</string>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||||
--><resources>
|
--><resources>
|
||||||
<string name="about">關於</string>
|
<string name="about">關於</string>
|
||||||
<string name="about_description">兼容KeePass密碼管理軟體的Android程式</string>
|
<string name="about_description">兼容KeePass密碼管理軟體的Android程式。</string>
|
||||||
<string name="accept">接受</string>
|
<string name="accept">接受</string>
|
||||||
<string name="account">帳戶</string>
|
<string name="account">帳戶</string>
|
||||||
<string name="add_entry">新增項目</string>
|
<string name="add_entry">新增項目</string>
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
<string name="encryption_explanation">資料庫所有資料均採用加密演算法</string>
|
<string name="encryption_explanation">資料庫所有資料均採用加密演算法</string>
|
||||||
<string name="enter">輸入</string>
|
<string name="enter">輸入</string>
|
||||||
<string name="entry_UUID">UUID</string>
|
<string name="entry_UUID">UUID</string>
|
||||||
<string name="entry_accessed">存取於</string>
|
<string name="entry_accessed">存取時間</string>
|
||||||
<string name="entry_add_attachment">添加附件</string>
|
<string name="entry_add_attachment">添加附件</string>
|
||||||
<string name="entry_add_field">添加欄位</string>
|
<string name="entry_add_field">添加欄位</string>
|
||||||
<string name="entry_attachments">附件</string>
|
<string name="entry_attachments">附件</string>
|
||||||
@@ -643,7 +643,7 @@
|
|||||||
<string name="auto_type">自動填入</string>
|
<string name="auto_type">自動填入</string>
|
||||||
<string name="info">資訊</string>
|
<string name="info">資訊</string>
|
||||||
<string name="html_about_privacy"><strong>不收集用戶資料。</strong>,此應用程式不連接任何伺服器,僅在裝置上運作,而且完全尊重用戶私穩。</string>
|
<string name="html_about_privacy"><strong>不收集用戶資料。</strong>,此應用程式不連接任何伺服器,僅在裝置上運作,而且完全尊重用戶私穩。</string>
|
||||||
<string name="waiting_challenge_request">正在等待挑戰請求…</string>
|
<string name="waiting_challenge_request">正在等待開發請求…</string>
|
||||||
<string name="waiting_challenge_response">正等待Challenge回應……</string>
|
<string name="waiting_challenge_response">正等待Challenge回應……</string>
|
||||||
<string name="error_XML_malformed">XML格式錯誤。</string>
|
<string name="error_XML_malformed">XML格式錯誤。</string>
|
||||||
<string name="error_challenge_already_requested">已請求Challenge。</string>
|
<string name="error_challenge_already_requested">已請求Challenge。</string>
|
||||||
@@ -665,10 +665,10 @@
|
|||||||
<string name="menu_appearance_settings_summary">主題、顏色、屬性</string>
|
<string name="menu_appearance_settings_summary">主題、顏色、屬性</string>
|
||||||
<string name="unlock">解鎖</string>
|
<string name="unlock">解鎖</string>
|
||||||
<string name="at_least_one_char">從每組中選擇字完</string>
|
<string name="at_least_one_char">從每組中選擇字完</string>
|
||||||
<string name="consider_chars_filter">可以包括</string>
|
<string name="consider_chars_filter">可以包含</string>
|
||||||
<string name="ignore_chars_filter">不要包括</string>
|
<string name="ignore_chars_filter">不要包括</string>
|
||||||
<string name="title_case">標題大小寫</string>
|
<string name="title_case">標題大小寫</string>
|
||||||
<string name="content_description_nav_header">導航列</string>
|
<string name="content_description_nav_header">導航列標題</string>
|
||||||
<string name="education_validate_entry_summary">記得驗證和儲存你的資料庫。
|
<string name="education_validate_entry_summary">記得驗證和儲存你的資料庫。
|
||||||
\n
|
\n
|
||||||
\n如果自動鎖定已啓用,而你又忘記你在更改資料,你可能會失去你的資料。</string>
|
\n如果自動鎖定已啓用,而你又忘記你在更改資料,你可能會失去你的資料。</string>
|
||||||
|
|||||||
@@ -413,7 +413,7 @@
|
|||||||
<string name="database_history">History</string>
|
<string name="database_history">History</string>
|
||||||
<string name="properties">Properties</string>
|
<string name="properties">Properties</string>
|
||||||
<string name="menu_appearance_settings">Appearance</string>
|
<string name="menu_appearance_settings">Appearance</string>
|
||||||
<string name="menu_appearance_settings_summary">Themes, colors, attributes</string>
|
<string name="menu_appearance_settings_summary">Themes, colors, icons, fonts, attributes</string>
|
||||||
<string name="biometric">Biometric</string>
|
<string name="biometric">Biometric</string>
|
||||||
<string name="device_credential">Device credential</string>
|
<string name="device_credential">Device credential</string>
|
||||||
<string name="general">General</string>
|
<string name="general">General</string>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.database.merge
|
|||||||
import com.kunzisoft.keepass.database.element.Attachment
|
import com.kunzisoft.keepass.database.element.Attachment
|
||||||
import com.kunzisoft.keepass.database.element.CustomData
|
import com.kunzisoft.keepass.database.element.CustomData
|
||||||
import com.kunzisoft.keepass.database.element.DateInstant
|
import com.kunzisoft.keepass.database.element.DateInstant
|
||||||
|
import com.kunzisoft.keepass.database.element.DeletedObject
|
||||||
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
|
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
|
||||||
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
|
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
|
||||||
import com.kunzisoft.keepass.database.element.entry.EntryKDB
|
import com.kunzisoft.keepass.database.element.entry.EntryKDB
|
||||||
@@ -32,9 +33,10 @@ import com.kunzisoft.keepass.database.element.node.NodeHandler
|
|||||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeIdInt
|
import com.kunzisoft.keepass.database.element.node.NodeIdInt
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
||||||
|
import com.kunzisoft.keepass.database.element.node.NodeVersioned
|
||||||
import com.kunzisoft.keepass.utils.readAllBytes
|
import com.kunzisoft.keepass.utils.readAllBytes
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
|
|
||||||
class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||||
|
|
||||||
@@ -180,7 +182,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge a KDB> database in a KDBX database,
|
* Merge a KDBX database in a KDBX database,
|
||||||
* Try to take into account the modification date of each element
|
* Try to take into account the modification date of each element
|
||||||
* To make a merge as accurate as possible
|
* To make a merge as accurate as possible
|
||||||
*/
|
*/
|
||||||
@@ -302,32 +304,113 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Manage deleted objects
|
// Manage deleted objects
|
||||||
databaseToMerge.deletedObjects.forEach { deletedObject ->
|
val deletedObjects = databaseToMerge.deletedObjects
|
||||||
val deletedObjectId = deletedObject.uuid
|
deletedObjects.forEach { deletedObject ->
|
||||||
val databaseEntry = database.getEntryById(deletedObjectId)
|
deleteEntry(deletedObject)
|
||||||
val databaseGroup = database.getGroupById(deletedObjectId)
|
deleteGroup(deletedObject, deletedObjects)
|
||||||
val databaseIcon = database.iconsManager.getIcon(deletedObjectId)
|
deleteIcon(deletedObject)
|
||||||
val databaseIconModificationTime = databaseIcon?.lastModificationTime
|
|
||||||
if (databaseEntry != null
|
|
||||||
&& deletedObject.deletionTime.isAfter(databaseEntry.lastModificationTime)) {
|
|
||||||
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
|
|
||||||
}
|
|
||||||
if (databaseGroup != null
|
|
||||||
&& deletedObject.deletionTime.isAfter(databaseGroup.lastModificationTime)) {
|
|
||||||
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
|
|
||||||
}
|
|
||||||
if (databaseIcon != null
|
|
||||||
&& (
|
|
||||||
databaseIconModificationTime == null
|
|
||||||
|| (deletedObject.deletionTime.isAfter(databaseIconModificationTime))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
database.removeCustomIcon(deletedObjectId)
|
|
||||||
}
|
|
||||||
// Attachments are removed and optimized during the database save
|
// Attachments are removed and optimized during the database save
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an entry from the database with the [deletedEntry] id
|
||||||
|
*/
|
||||||
|
private fun deleteEntry(deletedEntry: DeletedObject) {
|
||||||
|
val databaseEntry = database.getEntryById(deletedEntry.uuid)
|
||||||
|
if (databaseEntry != null
|
||||||
|
&& deletedEntry.deletionTime.isAfter(databaseEntry.lastModificationTime)) {
|
||||||
|
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a node is in the list of deleted objects
|
||||||
|
*/
|
||||||
|
private fun Set<DeletedObject>.containsNode(node: NodeVersioned<UUID, GroupKDBX, EntryKDBX>): Boolean {
|
||||||
|
return this.any { it.uuid == node.nodeId.id }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a node is not in the list of deleted objects
|
||||||
|
*/
|
||||||
|
private fun Set<DeletedObject>.notContainsNode(node: NodeVersioned<UUID, GroupKDBX, EntryKDBX>): Boolean {
|
||||||
|
return !this.containsNode(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first parent not deleted
|
||||||
|
*/
|
||||||
|
private fun firstNotDeletedParent(
|
||||||
|
node: NodeVersioned<UUID, GroupKDBX, EntryKDBX>,
|
||||||
|
deletedObjects: Set<DeletedObject>
|
||||||
|
): GroupKDBX? {
|
||||||
|
var parent = node.parent
|
||||||
|
while (parent != null && deletedObjects.containsNode(parent)) {
|
||||||
|
parent = node.parent
|
||||||
|
}
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a group from the database with the [deletedGroup] id
|
||||||
|
* Recursively check whether a group to be deleted contains a node not to be deleted with [deletedObjects]
|
||||||
|
* and move it to the first parent that has not been deleted.
|
||||||
|
*/
|
||||||
|
private fun deleteGroup(deletedGroup: DeletedObject, deletedObjects: Set<DeletedObject>) {
|
||||||
|
val databaseGroup = database.getGroupById(deletedGroup.uuid)
|
||||||
|
if (databaseGroup != null
|
||||||
|
&& deletedGroup.deletionTime.isAfter(databaseGroup.lastModificationTime)) {
|
||||||
|
// Must be in dedicated list to prevent modification collision
|
||||||
|
val entriesToMove = mutableListOf<EntryKDBX>()
|
||||||
|
databaseGroup.getChildEntries().forEach { child ->
|
||||||
|
// If the child entry is not a deleted object,
|
||||||
|
if (deletedObjects.notContainsNode(child)) {
|
||||||
|
entriesToMove.add(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val groupsToMove = mutableListOf<GroupKDBX>()
|
||||||
|
databaseGroup.getChildGroups().forEach { child ->
|
||||||
|
// Move the group to the first parent not deleted
|
||||||
|
// the deleted objects will take care of remove it later
|
||||||
|
groupsToMove.add(child)
|
||||||
|
}
|
||||||
|
// For each node to move, move it
|
||||||
|
// try to move the child entry in the first parent not deleted
|
||||||
|
entriesToMove.forEach { child ->
|
||||||
|
database.removeEntryFrom(child, child.parent)
|
||||||
|
database.addEntryTo(
|
||||||
|
child,
|
||||||
|
firstNotDeletedParent(databaseGroup, deletedObjects)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
groupsToMove.forEach { child ->
|
||||||
|
database.removeGroupFrom(child, child.parent)
|
||||||
|
database.addGroupTo(
|
||||||
|
child,
|
||||||
|
firstNotDeletedParent(databaseGroup, deletedObjects)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Then delete the group
|
||||||
|
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an icon from the database with the [deletedIcon] id
|
||||||
|
*/
|
||||||
|
private fun deleteIcon(deletedIcon: DeletedObject) {
|
||||||
|
val deletedObjectId = deletedIcon.uuid
|
||||||
|
val databaseIcon = database.iconsManager.getIcon(deletedObjectId)
|
||||||
|
val databaseIconModificationTime = databaseIcon?.lastModificationTime
|
||||||
|
if (databaseIcon != null
|
||||||
|
&& (databaseIconModificationTime == null
|
||||||
|
|| (deletedIcon.deletionTime.isAfter(databaseIconModificationTime)))
|
||||||
|
) {
|
||||||
|
database.removeCustomIcon(deletedObjectId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge [customDataToMerge] in [customData]
|
* Merge [customDataToMerge] in [customData]
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class SearchHelper {
|
|||||||
if (searchParameters.searchByDomain) {
|
if (searchParameters.searchByDomain) {
|
||||||
try {
|
try {
|
||||||
stringToCheck.inTheSameDomainAs(word, sameSubDomain = true)
|
stringToCheck.inTheSameDomainAs(word, sameSubDomain = true)
|
||||||
} catch (e: Exception) {
|
} catch (_: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
} else null
|
} else null
|
||||||
@@ -204,10 +204,18 @@ class SearchHelper {
|
|||||||
regex.matches(stringToCheck)
|
regex.matches(stringToCheck)
|
||||||
} else {
|
} else {
|
||||||
specialComparison?.invoke(stringToCheck, searchParameters.searchQuery)
|
specialComparison?.invoke(stringToCheck, searchParameters.searchQuery)
|
||||||
?: stringToCheck.contains(
|
?: run {
|
||||||
searchParameters.searchQuery,
|
// Search with space separator #175
|
||||||
!searchParameters.caseSensitive
|
var searchFound = true
|
||||||
)
|
searchParameters.searchQuery.split(" ").forEach { word ->
|
||||||
|
searchFound = searchFound
|
||||||
|
&& stringToCheck.contains(
|
||||||
|
word,
|
||||||
|
!searchParameters.caseSensitive
|
||||||
|
)
|
||||||
|
}
|
||||||
|
searchFound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ inline fun <reified T : Parcelable> Parcel.readParcelableCompat(): T? = when {
|
|||||||
|
|
||||||
fun <T> Parcel.readParcelableCompat(clazz: Class<T>): T? = when {
|
fun <T> Parcel.readParcelableCompat(clazz: Class<T>): T? = when {
|
||||||
SDK_INT >= 33 -> readParcelable(clazz.classLoader, clazz)
|
SDK_INT >= 33 -> readParcelable(clazz.classLoader, clazz)
|
||||||
else -> @Suppress("DEPRECATION") readParcelable(clazz.classLoader) as? T
|
else -> @Suppress("DEPRECATION", "UNCHECKED_CAST") (readParcelable(clazz.classLoader) as? T)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Serializable> Parcel.readSerializableCompat(): T? = when {
|
inline fun <reified T : Serializable> Parcel.readSerializableCompat(): T? = when {
|
||||||
@@ -120,19 +120,19 @@ fun <K : Parcelable, V : Parcelable> Parcel.writeParcelableMap(map: Map<K, V>, f
|
|||||||
inline fun <reified K : Parcelable, reified V : Parcelable> Parcel.readParcelableMap(): Map<K, V> {
|
inline fun <reified K : Parcelable, reified V : Parcelable> Parcel.readParcelableMap(): Map<K, V> {
|
||||||
val size = readInt()
|
val size = readInt()
|
||||||
val map = HashMap<K, V>(size)
|
val map = HashMap<K, V>(size)
|
||||||
for (i in 0 until size) {
|
(0 until size).forEach { i ->
|
||||||
val key: K? = try {
|
val key: K? = try {
|
||||||
when {
|
when {
|
||||||
SDK_INT >= 33 -> readParcelable(K::class.java.classLoader, K::class.java)
|
SDK_INT >= 33 -> readParcelable(K::class.java.classLoader, K::class.java)
|
||||||
else -> @Suppress("DEPRECATION") readParcelable(K::class.java.classLoader)
|
else -> @Suppress("DEPRECATION") readParcelable(K::class.java.classLoader)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) { null }
|
} catch (_: Exception) { null }
|
||||||
val value: V? = try {
|
val value: V? = try {
|
||||||
when {
|
when {
|
||||||
SDK_INT >= 33 -> readParcelable(V::class.java.classLoader, V::class.java)
|
SDK_INT >= 33 -> readParcelable(V::class.java.classLoader, V::class.java)
|
||||||
else -> @Suppress("DEPRECATION") readParcelable(V::class.java.classLoader)
|
else -> @Suppress("DEPRECATION") readParcelable(V::class.java.classLoader)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) { null }
|
} catch (_: Exception) { null }
|
||||||
if (key != null && value != null)
|
if (key != null && value != null)
|
||||||
map[key] = value
|
map[key] = value
|
||||||
}
|
}
|
||||||
@@ -152,14 +152,14 @@ fun <V : Parcelable> Parcel.writeStringParcelableMap(map: HashMap<String, V>, fl
|
|||||||
inline fun <reified V : Parcelable> Parcel.readStringParcelableMap(): LinkedHashMap<String, V> {
|
inline fun <reified V : Parcelable> Parcel.readStringParcelableMap(): LinkedHashMap<String, V> {
|
||||||
val size = readInt()
|
val size = readInt()
|
||||||
val map = LinkedHashMap<String, V>(size)
|
val map = LinkedHashMap<String, V>(size)
|
||||||
for (i in 0 until size) {
|
(0 until size).forEach { i ->
|
||||||
val key: String? = readString()
|
val key: String? = readString()
|
||||||
val value: V? = try {
|
val value: V? = try {
|
||||||
when {
|
when {
|
||||||
SDK_INT >= 33 -> readParcelable(V::class.java.classLoader, V::class.java)
|
SDK_INT >= 33 -> readParcelable(V::class.java.classLoader, V::class.java)
|
||||||
else -> @Suppress("DEPRECATION") readParcelable(V::class.java.classLoader)
|
else -> @Suppress("DEPRECATION") readParcelable(V::class.java.classLoader)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) { null }
|
} catch (_: Exception) { null }
|
||||||
if (key != null && value != null)
|
if (key != null && value != null)
|
||||||
map[key] = value
|
map[key] = value
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ fun Parcel.writeStringIntMap(map: LinkedHashMap<String, Int>) {
|
|||||||
fun Parcel.readStringIntMap(): LinkedHashMap<String, Int> {
|
fun Parcel.readStringIntMap(): LinkedHashMap<String, Int> {
|
||||||
val size = readInt()
|
val size = readInt()
|
||||||
val map = LinkedHashMap<String, Int>(size)
|
val map = LinkedHashMap<String, Int>(size)
|
||||||
for (i in 0 until size) {
|
(0 until size).forEach { i ->
|
||||||
val key: String? = readString()
|
val key: String? = readString()
|
||||||
val value: Int = readInt()
|
val value: Int = readInt()
|
||||||
if (key != null)
|
if (key != null)
|
||||||
@@ -201,7 +201,7 @@ fun Parcel.writeStringStringMap(map: MutableMap<String, String>) {
|
|||||||
fun Parcel.readStringStringMap(): LinkedHashMap<String, String> {
|
fun Parcel.readStringStringMap(): LinkedHashMap<String, String> {
|
||||||
val size = readInt()
|
val size = readInt()
|
||||||
val map = LinkedHashMap<String, String>(size)
|
val map = LinkedHashMap<String, String>(size)
|
||||||
for (i in 0 until size) {
|
(0 until size).forEach { i ->
|
||||||
val key: String? = readString()
|
val key: String? = readString()
|
||||||
val value: String? = readString()
|
val value: String? = readString()
|
||||||
if (key != null && value != null)
|
if (key != null && value != null)
|
||||||
|
|||||||
6
fastlane/metadata/android/en-US/changelogs/141.txt
Normal file
6
fastlane/metadata/android/en-US/changelogs/141.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
* Updated to API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
|
||||||
|
* Remember last read-only state #2099 #2100 (Thx @rmacklin)
|
||||||
|
* Fix merge deletion #1516
|
||||||
|
* Fix space in search #175
|
||||||
|
* Fix deletable recycle bin #2163
|
||||||
|
* Small fixes
|
||||||
3
fastlane/metadata/android/en-US/changelogs/143.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/143.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
* Fix landscape UI #2198 #2200 (@chenxiaolong)
|
||||||
|
* Fix start loop and flash screen #2201
|
||||||
|
* Small fixes
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
KeePassDX es un <b> Administrador de contraseñas seguro </b> que permite editar <b>datos cifrados en un solo archivo</b> en el formato abierto de KeePass permite <b>completar los formularios de manera segura</b>, no requiere<b>conexión a internet</b> e integra los estándares de diseño de Android. La aplicación es <b> de código abierto, sin publicidad</b>.
|
KeePassDX es un <b>gestor y almacén de contraseñas</b> que permite editar <b>datos cifrados en un único archivo</b> en formato KeePass abierto y <b>rellenar formularios de forma segura</b>, no requiere <b>conexión a Internet</b> e integra los estándares de diseño de Android. La aplicación es <b>de código abierto y sin publicidad</b>.
|
||||||
|
|
||||||
<b>Funciones</b>
|
<b>Funciones</b>
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
KeePassDX - FOSS Administrador de contraseñas
|
KeePassDX - Contraseñas FOSS
|
||||||
|
|||||||
6
fastlane/metadata/android/fr-FR/changelogs/141.txt
Normal file
6
fastlane/metadata/android/fr-FR/changelogs/141.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
* Mise à jour vers API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
|
||||||
|
* Sauvegarde du dernier état lecture seule #2099 #2100 (Thx @rmacklin)
|
||||||
|
* Correction de la suppression lors d'un merge #1516
|
||||||
|
* Correction des espaces dans la recherche #175
|
||||||
|
* Correction de la poubelle supprimable #2163
|
||||||
|
* Petites corrections
|
||||||
3
fastlane/metadata/android/fr-FR/changelogs/143.txt
Normal file
3
fastlane/metadata/android/fr-FR/changelogs/143.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
* Correction de l'interface en paysage #2198 #2200 (@chenxiaolong)
|
||||||
|
* Correction du démarrage en boucle et de l'écran clignotant #2201
|
||||||
|
* Petites corrections
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
KeePassDX имеет <b>открытый исходный код</b> и <b>без рекламы</b>. <b>Многоформатный менеджер паролей KeePass</b> это приложение которое позволяет безопасно сохранять и использовать пароли, ключи и цифровые идентификаторы за счет интеграции стандартов дизайна Android и <b>не требует подключения к Интернету</b>.
|
KeePassDX — это приложение <b> для хранения и управления паролями</b>, которая позволяет редактировать <b>зашифрованные данные в одном файле</b> в открытом формате KeePass, <b>безопасно заполнять формы</b>, <b>не требует подключения к Интернету</b> и соответствует стандартам дизайна Android. Приложение с <b>открытым исходным кодом, без рекламы</b>.
|
||||||
|
|
||||||
<b>Возможности</b>
|
<b>Возможности</b>
|
||||||
|
|
||||||
@@ -16,8 +16,8 @@ KeePassDX имеет <b>открытый исходный код</b> и <b>бе
|
|||||||
- Точное управление настройками.
|
- Точное управление настройками.
|
||||||
- Код написан на родных языках для платформы (Kotlin / Java / JNI / C).
|
- Код написан на родных языках для платформы (Kotlin / Java / JNI / C).
|
||||||
|
|
||||||
Вы можете пожертвовать или купить профессиональную версию чтобы улучшить обслуживание и ускорить разработку нужных вам возможностей: <a href="https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro">KeePass Pro</a>
|
Вы можете пожертвовать или купить профессиональную версию для улучшения обслуживания и быстрой разработки нужных вам возможностей: <a href="https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro">https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro</a>
|
||||||
|
|
||||||
Проект постоянно развивается. Не стесняйтесь проверять статус разработки и следующих обновлений тут: <a href="https://github.com/Kunzisoft/KeePassDX/projects">github.com/Kunzisoft/KeePassDX/projects</a>
|
Проект постоянно развивается. Не стесняйтесь проверять статус разработки следующих обновлений: <a href="https://github.com/Kunzisoft/KeePassDX/projects">https://github.com/Kunzisoft/KeePassDX/projects</a>
|
||||||
|
|
||||||
Сообщить о проблеме:<a href="https://github.com/Kunzisoft/KeePassDX/issues">https://github.com/Kunzisoft/KeePassDX/issues</a>
|
Сообщить о проблеме:<a href="https://github.com/Kunzisoft/KeePassDX/issues">https://github.com/Kunzisoft/KeePassDX/issues</a>
|
||||||
|
|||||||
23
fastlane/metadata/android/tr-TR/full_description.txt
Normal file
23
fastlane/metadata/android/tr-TR/full_description.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
KeePassDX, açık KeePass biçiminde <b>tek bir dosyada şifreli verileri</b> düzenlemeye ve <b>formları güvenli bir şekilde doldurmaya</b> olanak tanıyan bir <b>şifre kasası ve yöneticisi</b> olup, <b>internet bağlantısı gerektirmez</b> ve Android tasarım standartlarını takip eder. Uygulama <b>açık kaynaklıdır ve reklam içermez</b>.
|
||||||
|
|
||||||
|
<b>Özellikler</b>
|
||||||
|
|
||||||
|
- Veri tabanı dosyaları / girdileri ve grupları oluşturun.
|
||||||
|
- AES - Twofish - ChaCha20 - Argon2 algoritması ile .kdb ve .kdbx dosyaları (sürüm 1 ile 4 arası) desteği.
|
||||||
|
- Birçok farklı programla uyumludur (KeePass, KeePassXC, KeeWeb, …).
|
||||||
|
- URI / URL alanlarını hızlı bir şekilde açma ve kopyalama imkanı.
|
||||||
|
- Hızlı kilit açma için biyometrik tanıma (parmak izi / yüz tanıma / …).
|
||||||
|
- İki aşamalı kimlik doğrulama (2FA) için tek kullanımlık şifre yönetimi (HOTP / TOTP).
|
||||||
|
- Temalı Material tasarımı.
|
||||||
|
- Otomatik doldurma ve bütünleşme.
|
||||||
|
- Alan doldurma klavyesi.
|
||||||
|
- Değişken şablonlar.
|
||||||
|
- Her girdinin geçmişi.
|
||||||
|
- Ayarların hassas yönetimi.
|
||||||
|
- Yerel dillerde (Kotlin / Java / JNI / C) yazılmış kod.
|
||||||
|
|
||||||
|
Daha iyi hizmet ve istediğiniz özelliklerin hızlı bir şekilde geliştirilmesi için bağış yapabilir veya pro sürümü satın alabilirsiniz: <a href="https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro">https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro</a>
|
||||||
|
|
||||||
|
Proje sürekli gelişmektedir. Bir sonraki güncellemelerin geliştirme durumuna bakmaktan çekinmeyin: <a href="https://github.com/Kunzisoft/KeePassDX/projects">https://github.com/Kunzisoft/KeePassDX/projects</a>
|
||||||
|
|
||||||
|
Sorunlarınızı şu adrese gönderin: <a href="https://github.com/Kunzisoft/KeePassDX/issues">https://github.com/Kunzisoft/KeePassDX/issues</a>
|
||||||
23
fastlane/metadata/android/zh-TW/full_description.txt
Normal file
23
fastlane/metadata/android/zh-TW/full_description.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
KeePassDX 是一款<b>密碼保險箱和管理器</b>,允許以開放的 KeePass 格式編輯<b>單一檔案中的加密資料</b>,並<b>以安全的方式填寫表單</b>,無需<b>網路連線</b>,並整合了 Android 設計標準。該應用程式<b>開源,無廣告</b>。
|
||||||
|
|
||||||
|
<b>功能</b>
|
||||||
|
|
||||||
|
- 建立資料庫檔案/條目和群組。
|
||||||
|
- 支援 .kdb 和 .kdbx 檔案(版本 1 至 4),並採用 AES - Twofish - ChaCha20 - Argon2 演算法。
|
||||||
|
- 與大多數替代方案(KeePass、KeePassXC、KeeWeb 等)相容。
|
||||||
|
- 允許快速開啟和複製 URI/URL 欄位。
|
||||||
|
- 生物辨識技術,可快速解鎖(指紋/人臉解鎖等)。
|
||||||
|
- 一次性密碼管理 (HOTP / TOTP),用於雙重認證 (2FA)。
|
||||||
|
- 帶主題的 Material Design 設計。
|
||||||
|
- 自動填充和整合。
|
||||||
|
- 字段填充鍵盤。
|
||||||
|
- 動態模板。
|
||||||
|
- 每次輸入的歷史記錄。
|
||||||
|
- 精確的設定管理。
|
||||||
|
- 使用原生語言編寫程式碼 (Kotlin / Java / JNI / C)。
|
||||||
|
|
||||||
|
您可以捐款或購買專業版,以獲得更好的服務並快速開發您想要的功能:<a href="https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro">https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro</a>
|
||||||
|
|
||||||
|
該項目正在不斷發展。請隨時查看後續更新的開發狀態:<a href="https://github.com/Kunzisoft/KeePassDX/projects">https://github.com/Kunzisoft/KeePassDX/projects</a>
|
||||||
|
|
||||||
|
請將問題寄至:<a href="https://github.com/Kunzisoft/KeePassDX/issues">https://github.com/Kunzisoft/KeePassDX/issues</a>
|
||||||
1
fastlane/metadata/android/zh-TW/short_description.txt
Normal file
1
fastlane/metadata/android/zh-TW/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
安全的開源密碼保險箱和管理器
|
||||||
1
fastlane/metadata/android/zh-TW/title.txt
Normal file
1
fastlane/metadata/android/zh-TW/title.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
KeePassDX - FOSS 密碼管理器
|
||||||
Reference in New Issue
Block a user