Merge branch 'release/2.5RC1'

This commit is contained in:
J-Jamet
2020-04-12 20:32:03 +02:00
107 changed files with 1849 additions and 836 deletions

View File

@@ -1,3 +1,14 @@
KeePassDX(2.5beta31)
* Add write permission to keep compatibility with old file managers
* Fix autofill for apps
* Auto search for autofill
* New keyfile input
* Icon to hide keyfile input
* New lock button
* Setting to hide lock button in user interface
* Clickable links in notes
* Fix autofill for key-value pairs
KeePassDX(2.5beta30)
* Fix Lock after screen off (wait 1.5 seconds)
* Upgrade autofill algorithm

View File

@@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 29
versionCode = 30
versionName = "2.5beta30"
versionCode = 31
versionName = "2.5RC1"
multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests"
@@ -97,6 +97,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.biometric:biometric:1.0.1'
implementation "androidx.core:core-ktx:1.2.0"
// To upgrade with style
implementation 'com.google.android.material:material:1.0.0'

View File

@@ -15,7 +15,6 @@
<uses-permission
android:name="android.permission.VIBRATE"/>
<uses-permission
android:maxSdkVersion="18"
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
@@ -138,12 +137,12 @@
<activity android:name="com.kunzisoft.keepass.autofill.AutofillLauncherActivity"
android:configChanges="keyboardHidden" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsAutofillActivity" />
<activity android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
<activity android:name="com.kunzisoft.keepass.magikeyboard.KeyboardLauncherActivity"
android:label="@string/keyboard_name"
android:exported="true">
</activity>
<activity android:name="com.kunzisoft.keepass.settings.MagikIMESettings"
<activity android:name="com.kunzisoft.keepass.settings.MagikeyboardSettingsActivity"
android:label="@string/keyboard_setting_label">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

View File

@@ -52,7 +52,6 @@ import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.settings.SettingsAutofillActivity
import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager
import com.kunzisoft.keepass.timeout.ClipboardHelper
import com.kunzisoft.keepass.timeout.TimeoutHelper
@@ -73,6 +72,7 @@ class EntryActivity : LockingActivity() {
private var historyView: View? = null
private var entryContentsView: EntryContentsView? = null
private var entryProgress: ProgressBar? = null
private var lockView: View? = null
private var toolbar: Toolbar? = null
private var mDatabase: Database? = null
@@ -124,6 +124,11 @@ class EntryActivity : LockingActivity() {
entryContentsView = findViewById(R.id.entry_contents)
entryContentsView?.applyFontVisibilityToFields(PreferencesUtil.fieldFontIsInVisibility(this))
entryProgress = findViewById(R.id.entry_progress)
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
lockAndExit()
}
// Init the clipboard helper
clipboardHelper = ClipboardHelper(this)
@@ -148,6 +153,13 @@ class EntryActivity : LockingActivity() {
override fun onResume() {
super.onResume()
// Show the lock button
lockView?.visibility = if (PreferencesUtil.showLockDatabaseButton(this)) {
View.VISIBLE
} else {
View.GONE
}
// Get Entry from UUID
try {
val keyEntry: NodeId<UUID>? = intent.getParcelableExtra(KEY_ENTRY)
@@ -462,8 +474,7 @@ class EntryActivity : LockingActivity() {
getString(R.string.entry_user_name)))
},
{
// Launch autofill settings
startActivity(Intent(this@EntryActivity, SettingsAutofillActivity::class.java))
performedNextEducation(entryActivityEducation, menu)
})
if (!entryCopyEducationPerformed) {
@@ -526,10 +537,6 @@ class EntryActivity : LockingActivity() {
!mReadOnly && mAutoSaveEnable)
}
}
R.id.menu_lock -> {
lockAndExit()
return true
}
R.id.menu_save_database -> {
mProgressDialogThread?.startDatabaseSave(!mReadOnly)
}

View File

@@ -81,6 +81,7 @@ class EntryEditActivity : LockingActivity(),
private var entryEditContentsView: EntryEditContentsView? = null
private var entryEditAddToolBar: ActionMenuView? = null
private var saveView: View? = null
private var lockView: View? = null
// Education
private var entryEditActivityEducation: EntryEditActivityEducation? = null
@@ -112,6 +113,12 @@ class EntryEditActivity : LockingActivity(),
.show(supportFragmentManager, "DatePickerFragment")
}
}
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
lockAndExit()
}
// Focus view to reinitialize timeout
resetAppTimeoutWhenViewFocusedOrChanged(entryEditContentsView)
@@ -241,6 +248,16 @@ class EntryEditActivity : LockingActivity(),
}
}
override fun onResume() {
super.onResume()
lockView?.visibility = if (PreferencesUtil.showLockDatabaseButton(this)) {
View.VISIBLE
} else {
View.GONE
}
}
private fun populateViewsWithEntry(newEntry: Entry) {
// Don't start the field reference manager, we want to see the raw ref
mDatabase?.stopManageEntry(newEntry)
@@ -416,10 +433,6 @@ class EntryEditActivity : LockingActivity(),
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_lock -> {
lockAndExit()
return true
}
R.id.menu_save_database -> {
mProgressDialogThread?.startDatabaseSave(!mReadOnly)
}

View File

@@ -26,13 +26,11 @@ import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
@@ -48,9 +46,11 @@ import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.AutofillHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.education.FileDatabaseSelectActivityEducation
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_TASK
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.*
@@ -63,7 +63,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
// Views
private var coordinatorLayout: CoordinatorLayout? = null
private var fileListContainer: View? = null
private var fileManagerExplanationButton: View? = null
private var createButtonView: View? = null
private var openDatabaseButtonView: View? = null
@@ -85,12 +85,16 @@ class FileDatabaseSelectActivity : StylishActivity(),
setContentView(R.layout.activity_file_selection)
coordinatorLayout = findViewById(R.id.activity_file_selection_coordinator_layout)
fileListContainer = findViewById(R.id.container_file_list)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
toolbar.title = ""
setSupportActionBar(toolbar)
fileManagerExplanationButton = findViewById(R.id.file_manager_explanation_button)
fileManagerExplanationButton?.setOnClickListener {
UriUtil.gotoUrl(this, R.string.file_manager_explanation_url)
}
// Create button
createButtonView = findViewById(R.id.create_database_button)
if (allowCreateDocumentByStorageAccessFramework(packageManager)) {
@@ -105,8 +109,13 @@ class FileDatabaseSelectActivity : StylishActivity(),
createButtonView?.setOnClickListener { createNewFile() }
mOpenFileHelper = OpenFileHelper(this)
openDatabaseButtonView = findViewById(R.id.open_database_button)
openDatabaseButtonView?.setOnClickListener(mOpenFileHelper?.openFileOnClickViewListener)
openDatabaseButtonView = findViewById(R.id.open_keyfile_button)
openDatabaseButtonView?.apply {
mOpenFileHelper?.openFileOnClickViewListener?.let {
setOnClickListener(it)
setOnLongClickListener(it)
}
}
// History list
val fileDatabaseHistoryRecyclerView = findViewById<RecyclerView>(R.id.file_list)
@@ -121,7 +130,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
databaseFileUri,
UriUtil.parse(fileDatabaseHistoryEntityToOpen.keyFileUri))
}
updateFileListVisibility()
}
mAdapterDatabaseHistory?.setOnFileDatabaseHistoryDeleteListener { fileDatabaseHistoryToDelete ->
// Remove from app database
@@ -130,7 +138,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
fileHistoryDeleted?.let { databaseFileHistoryDeleted ->
mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileHistoryDeleted)
mAdapterDatabaseHistory?.notifyDataSetChanged()
updateFileListVisibility()
}
}
true
@@ -212,7 +219,8 @@ class FileDatabaseSelectActivity : StylishActivity(),
try {
PasswordActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile,
assistStructure)
assistStructure,
intent.getParcelableExtra(KEY_SEARCH_INFO))
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
@@ -224,16 +232,21 @@ class FileDatabaseSelectActivity : StylishActivity(),
private fun launchGroupActivity(readOnly: Boolean) {
EntrySelectionHelper.doEntrySelectionAction(intent,
{
GroupActivity.launch(this@FileDatabaseSelectActivity, readOnly)
GroupActivity.launch(this@FileDatabaseSelectActivity,
readOnly)
},
{
GroupActivity.launchForKeyboardSelection(this@FileDatabaseSelectActivity, readOnly)
GroupActivity.launchForKeyboardSelection(this@FileDatabaseSelectActivity,
readOnly)
// Do not keep history
finish()
},
{ assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
GroupActivity.launchForAutofillResult(this@FileDatabaseSelectActivity, assistStructure, readOnly)
GroupActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
assistStructure,
intent.getParcelableExtra(KEY_SEARCH_INFO),
readOnly)
}
})
}
@@ -245,25 +258,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
overridePendingTransition(0, 0)
}
private fun updateExternalStorageWarning() {
// To show errors
var warning = -1
val state = Environment.getExternalStorageState()
if (state == Environment.MEDIA_MOUNTED_READ_ONLY) {
warning = R.string.read_only_warning
} else if (state != Environment.MEDIA_MOUNTED) {
warning = R.string.warning_unmounted
}
val labelWarningView = findViewById<TextView>(R.id.label_warning)
if (warning != -1) {
labelWarningView.setText(warning)
labelWarningView.visibility = View.VISIBLE
} else {
labelWarningView.visibility = View.INVISIBLE
}
}
override fun onResume() {
val database = Database.getInstance()
if (database.loaded) {
@@ -272,8 +266,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
super.onResume()
updateExternalStorageWarning()
// Construct adapter with listeners
if (PreferencesUtil.showRecentFiles(this)) {
mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
@@ -289,13 +281,11 @@ class FileDatabaseSelectActivity : StylishActivity(),
true
})
mAdapterDatabaseHistory?.notifyDataSetChanged()
updateFileListVisibility()
}
}
} else {
mAdapterDatabaseHistory?.clearDatabaseFileHistoryList()
mAdapterDatabaseHistory?.notifyDataSetChanged()
updateFileListVisibility()
}
// Register progress task
@@ -317,13 +307,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
outState.putParcelable(EXTRA_DATABASE_URI, mDatabaseFileUri)
}
private fun updateFileListVisibility() {
if (mAdapterDatabaseHistory?.itemCount == 0)
fileListContainer?.visibility = View.INVISIBLE
else
fileListContainer?.visibility = View.VISIBLE
}
override fun onAssignKeyDialogPositiveClick(
masterPasswordChecked: Boolean, masterPassword: String?,
keyFileChecked: Boolean, keyFile: Uri?) {
@@ -454,10 +437,13 @@ class FileDatabaseSelectActivity : StylishActivity(),
*/
@RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity, assistStructure: AssistStructure) {
fun launchForAutofillResult(activity: Activity,
assistStructure: AssistStructure,
searchInfo: SearchInfo?) {
AutofillHelper.startActivityForAutofillResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
assistStructure)
assistStructure,
searchInfo)
}
}
}

View File

@@ -62,6 +62,7 @@ import com.kunzisoft.keepass.database.element.node.Type
import com.kunzisoft.keepass.education.GroupActivityEducation
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_COPY_NODES_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_GROUP_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_NODES_TASK
@@ -89,6 +90,7 @@ class GroupActivity : LockingActivity(),
// Views
private var coordinatorLayout: CoordinatorLayout? = null
private var lockView: View? = null
private var toolbar: Toolbar? = null
private var searchTitleView: View? = null
private var toolbarAction: ToolbarAction? = null
@@ -134,6 +136,11 @@ class GroupActivity : LockingActivity(),
groupNameView = findViewById(R.id.group_name)
toolbarAction = findViewById(R.id.toolbar_action)
modeTitleView = findViewById(R.id.mode_title_view)
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
lockAndExit()
}
toolbar?.title = ""
setSupportActionBar(toolbar)
@@ -347,7 +354,7 @@ class GroupActivity : LockingActivity(),
// If it's a search
if (Intent.ACTION_SEARCH == intent.action) {
val searchString = intent.getStringExtra(SearchManager.QUERY)?.trim { it <= ' ' } ?: ""
return mDatabase?.search(searchString)
return mDatabase?.createVirtualGroupFromSearch(searchString)
}
// else a real group
else {
@@ -486,7 +493,7 @@ class GroupActivity : LockingActivity(),
// Build response with the entry selected
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && mDatabase != null) {
mDatabase?.let { database ->
AutofillHelper.buildResponseWhenEntrySelected(this@GroupActivity,
AutofillHelper.buildResponse(this@GroupActivity,
entryVersioned.getEntryInfo(database))
}
}
@@ -632,6 +639,13 @@ class GroupActivity : LockingActivity(),
override fun onResume() {
super.onResume()
// Show the lock button
lockView?.visibility = if (PreferencesUtil.showLockDatabaseButton(this)) {
View.VISIBLE
} else {
View.GONE
}
// Refresh the elements
assignGroupViewElements()
// Refresh suggestions to change preferences
@@ -753,12 +767,11 @@ class GroupActivity : LockingActivity(),
if (!sortMenuEducationPerformed) {
// lockMenuEducationPerformed
toolbar != null
&& toolbar!!.findViewById<View>(R.id.menu_lock) != null
&& groupActivityEducation.checkAndPerformedLockMenuEducation(
toolbar!!.findViewById(R.id.menu_lock),
val lockButtonView = findViewById<View>(R.id.lock_button_icon)
lockButtonView != null
&& groupActivityEducation.checkAndPerformedLockMenuEducation(lockButtonView,
{
onOptionsItemSelected(menu.findItem(R.id.menu_lock))
lockAndExit()
},
{
performedNextEducation(groupActivityEducation, menu)
@@ -777,10 +790,6 @@ class GroupActivity : LockingActivity(),
R.id.menu_search ->
//onSearchRequested();
return true
R.id.menu_lock -> {
lockAndExit()
return true
}
R.id.menu_save_database -> {
mProgressDialogThread?.startDatabaseSave(!mReadOnly)
return true
@@ -956,27 +965,41 @@ class GroupActivity : LockingActivity(),
private const val SEARCH_FRAGMENT_TAG = "SEARCH_FRAGMENT_TAG"
private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY"
private fun buildIntent(context: Context, group: Group?, readOnly: Boolean,
private fun buildIntent(context: Context,
group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
val intent = Intent(context, GroupActivity::class.java)
if (group != null) {
intent.putExtra(GROUP_ID_KEY, group.nodeId)
}
if (searchInfo != null) {
intent.action = Intent.ACTION_SEARCH
val searchQuery = searchInfo.webDomain ?: searchInfo.applicationId
intent.putExtra(SearchManager.QUERY, searchQuery)
}
ReadOnlyHelper.putReadOnlyInIntent(intent, readOnly)
intentBuildLauncher.invoke(intent)
}
private fun checkTimeAndBuildIntent(activity: Activity, group: Group?, readOnly: Boolean,
private fun checkTimeAndBuildIntent(activity: Activity,
group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
buildIntent(activity, group, readOnly, intentBuildLauncher)
buildIntent(activity, group, searchInfo, readOnly, intentBuildLauncher)
}
}
private fun checkTimeAndBuildIntent(context: Context, group: Group?, readOnly: Boolean,
private fun checkTimeAndBuildIntent(context: Context,
group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTime(context)) {
buildIntent(context, group, readOnly, intentBuildLauncher)
buildIntent(context, group, searchInfo, readOnly, intentBuildLauncher)
}
}
@@ -985,11 +1008,9 @@ class GroupActivity : LockingActivity(),
* Standard Launch
* -------------------------
*/
@JvmOverloads
fun launch(context: Context,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
checkTimeAndBuildIntent(context, null, readOnly) { intent ->
checkTimeAndBuildIntent(context, null, null, readOnly) { intent ->
context.startActivity(intent)
}
}
@@ -1000,10 +1021,9 @@ class GroupActivity : LockingActivity(),
* -------------------------
*/
// TODO implement pre search to directly open the direct group
fun launchForKeyboardSelection(context: Context,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
checkTimeAndBuildIntent(context, null, readOnly) { intent ->
checkTimeAndBuildIntent(context, null, null, readOnly) { intent ->
EntrySelectionHelper.startActivityForEntrySelection(context, intent)
}
}
@@ -1013,14 +1033,13 @@ class GroupActivity : LockingActivity(),
* Autofill Launch
* -------------------------
*/
// TODO implement pre search to directly open the direct group
@RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity,
assistStructure: AssistStructure,
searchInfo: SearchInfo? = null,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(activity)) {
checkTimeAndBuildIntent(activity, null, readOnly) { intent ->
AutofillHelper.startActivityForAutofillResult(activity, intent, assistStructure)
checkTimeAndBuildIntent(activity, null, searchInfo, readOnly) { intent ->
AutofillHelper.startActivityForAutofillResult(activity, intent, assistStructure, searchInfo)
}
}
}

View File

@@ -23,6 +23,7 @@ import android.app.Activity
import android.app.assist.AssistStructure
import android.app.backup.BackupManager
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -32,13 +33,11 @@ import android.text.TextWatcher
import android.util.Log
import android.view.*
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
import android.widget.Button
import android.widget.CompoundButton
import android.widget.EditText
import android.widget.TextView
import android.widget.*
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar
import androidx.biometric.BiometricManager
import androidx.core.app.ActivityCompat
import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog
@@ -50,11 +49,13 @@ import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.AutofillHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.biometric.AdvancedUnlockedManager
import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException
import com.kunzisoft.keepass.education.PasswordActivityEducation
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.CIPHER_ENTITY_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
@@ -66,6 +67,7 @@ import com.kunzisoft.keepass.utils.FileDatabaseInfo
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.view.AdvancedUnlockInfoView
import com.kunzisoft.keepass.view.KeyFileSelectionView
import com.kunzisoft.keepass.view.asError
import kotlinx.android.synthetic.main.activity_password.*
import java.io.FileNotFoundException
@@ -77,7 +79,7 @@ open class PasswordActivity : StylishActivity() {
private var containerView: View? = null
private var filenameView: TextView? = null
private var passwordView: EditText? = null
private var keyFileView: EditText? = null
private var keyFileSelectionView: KeyFileSelectionView? = null
private var confirmButtonView: Button? = null
private var checkboxPasswordView: CompoundButton? = null
private var checkboxKeyFileView: CompoundButton? = null
@@ -92,6 +94,7 @@ open class PasswordActivity : StylishActivity() {
private var mRememberKeyFile: Boolean = false
private var mOpenFileHelper: OpenFileHelper? = null
private var mPermissionAsked = false
private var readOnly: Boolean = false
private var mForceReadOnly: Boolean = false
set(value) {
@@ -123,18 +126,23 @@ open class PasswordActivity : StylishActivity() {
confirmButtonView = findViewById(R.id.activity_password_open_button)
filenameView = findViewById(R.id.filename)
passwordView = findViewById(R.id.password)
keyFileView = findViewById(R.id.pass_keyfile)
keyFileSelectionView = findViewById(R.id.keyfile_selection)
checkboxPasswordView = findViewById(R.id.password_checkbox)
checkboxKeyFileView = findViewById(R.id.keyfile_checkox)
checkboxDefaultDatabaseView = findViewById(R.id.default_database)
advancedUnlockInfoView = findViewById(R.id.biometric_info)
infoContainerView = findViewById(R.id.activity_password_info_container)
mPermissionAsked = savedInstanceState?.getBoolean(KEY_PERMISSION_ASKED) ?: mPermissionAsked
readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState)
val browseView = findViewById<View>(R.id.open_database_button)
mOpenFileHelper = OpenFileHelper(this@PasswordActivity)
browseView.setOnClickListener(mOpenFileHelper!!.openFileOnClickViewListener)
keyFileSelectionView?.apply {
mOpenFileHelper?.openFileOnClickViewListener?.let {
setOnClickListener(it)
setOnLongClickListener(it)
}
}
passwordView?.setOnEditorActionListener(onEditorActionListener)
passwordView?.addTextChangedListener(object : TextWatcher {
@@ -147,17 +155,6 @@ open class PasswordActivity : StylishActivity() {
checkboxPasswordView?.isChecked = true
}
})
keyFileView?.setOnEditorActionListener(onEditorActionListener)
keyFileView?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
if (editable.toString().isNotEmpty() && checkboxKeyFileView?.isChecked != true)
checkboxKeyFileView?.isChecked = true
}
})
enableButtonOnCheckedChangeListener = CompoundButton.OnCheckedChangeListener { _, _ ->
enableOrNotTheConfirmationButton()
@@ -260,16 +257,38 @@ open class PasswordActivity : StylishActivity() {
private fun launchGroupActivity() {
EntrySelectionHelper.doEntrySelectionAction(intent,
{
GroupActivity.launch(this@PasswordActivity, readOnly)
GroupActivity.launch(this@PasswordActivity,
readOnly)
},
{
GroupActivity.launchForKeyboardSelection(this@PasswordActivity, readOnly)
GroupActivity.launchForKeyboardSelection(this@PasswordActivity,
readOnly)
// Do not keep history
finish()
},
{ assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
GroupActivity.launchForAutofillResult(this@PasswordActivity, assistStructure, readOnly)
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
AutofillHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
// Response is build
AutofillHelper.buildResponse(this, items)
finish()
},
{
// Here no search info found
GroupActivity.launchForAutofillResult(this@PasswordActivity,
assistStructure,
null,
readOnly)
},
{
// Simply close if database not opened, normally not happened
finish()
}
)
}
})
}
@@ -285,11 +304,12 @@ open class PasswordActivity : StylishActivity() {
}
override fun onResume() {
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
if (Database.getInstance().loaded)
launchGroupActivity()
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
// If the database isn't accessible make sure to clear the password field, if it
// was saved in the instance state
if (Database.getInstance().loaded) {
@@ -305,6 +325,7 @@ open class PasswordActivity : StylishActivity() {
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putBoolean(KEY_PERMISSION_ASKED, mPermissionAsked)
mDatabaseKeyFileUri?.let {
outState.putString(KEY_KEYFILE, it.toString())
}
@@ -319,7 +340,9 @@ open class PasswordActivity : StylishActivity() {
!FileDatabaseInfo(this, it).canWrite
} ?: false
*/
mForceReadOnly = false
mForceReadOnly = mDatabaseFileUri?.let {
!FileDatabaseInfo(this, it).exists
} ?: true
// Post init uri with KeyFile if needed
if (mRememberKeyFile && (mDatabaseKeyFileUri == null || mDatabaseKeyFileUri.toString().isEmpty())) {
@@ -345,7 +368,7 @@ open class PasswordActivity : StylishActivity() {
// Define Key File text
if (mRememberKeyFile) {
populateKeyFileTextView(keyFileUri?.toString())
populateKeyFileTextView(keyFileUri)
}
// Define listeners for default database checkbox and validate button
@@ -459,13 +482,13 @@ open class PasswordActivity : StylishActivity() {
}
}
private fun populateKeyFileTextView(text: String?) {
if (text == null || text.isEmpty()) {
keyFileView?.setText("")
private fun populateKeyFileTextView(uri: Uri?) {
if (uri == null || uri.toString().isEmpty()) {
keyFileSelectionView?.uri = null
if (checkboxKeyFileView?.isChecked == true)
checkboxKeyFileView?.isChecked = false
} else {
keyFileView?.setText(text)
keyFileSelectionView?.uri = uri
if (checkboxKeyFileView?.isChecked != true)
checkboxKeyFileView?.isChecked = true
}
@@ -486,7 +509,7 @@ open class PasswordActivity : StylishActivity() {
private fun verifyCheckboxesAndLoadDatabase(cipherDatabaseEntity: CipherDatabaseEntity? = null) {
val password: String? = passwordView?.text?.toString()
val keyFile: Uri? = UriUtil.parse(keyFileView?.text?.toString())
val keyFile: Uri? = keyFileSelectionView?.uri
verifyCheckboxesAndLoadDatabase(password, keyFile, cipherDatabaseEntity)
}
@@ -499,7 +522,7 @@ open class PasswordActivity : StylishActivity() {
}
private fun verifyKeyFileCheckboxAndLoadDatabase(password: String?) {
val keyFile: Uri? = UriUtil.parse(keyFileView?.text?.toString())
val keyFile: Uri? = keyFileSelectionView?.uri
verifyKeyFileCheckbox(keyFile)
loadDatabase(mDatabaseFileUri, password, mDatabaseKeyFileUri)
}
@@ -571,11 +594,42 @@ open class PasswordActivity : StylishActivity() {
super.onCreateOptionsMenu(menu)
launchEducation(menu)
launchEducation(menu) {
launchCheckPermission()
}
return true
}
// Check permission
private fun launchCheckPermission() {
val writePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE
val permissions = arrayOf(writePermission)
if (Build.VERSION.SDK_INT >= 23
&& !readOnly
&& !mPermissionAsked) {
mPermissionAsked = true
// Check self permission to show or not the dialog
if (toolbar != null
&& ActivityCompat.checkSelfPermission(this, writePermission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, permissions, WRITE_EXTERNAL_STORAGE_REQUEST)
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
WRITE_EXTERNAL_STORAGE_REQUEST -> {
if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE))
Toast.makeText(this, R.string.read_only_warning, Toast.LENGTH_LONG).show()
}
}
}
}
// To fix multiple view education
private var performedEductionInProgress = false
private fun launchEducation(menu: Menu, onEducationFinished: (()-> Unit)? = null) {
@@ -678,7 +732,7 @@ open class PasswordActivity : StylishActivity() {
) { uri ->
if (uri != null) {
mDatabaseKeyFileUri = uri
populateKeyFileTextView(uri.toString())
populateKeyFileTextView(uri)
}
}
}
@@ -703,6 +757,8 @@ open class PasswordActivity : StylishActivity() {
private const val KEY_PASSWORD = "password"
private const val KEY_LAUNCH_IMMEDIATELY = "launchImmediately"
private const val KEY_PERMISSION_ASKED = "KEY_PERMISSION_ASKED"
private const val WRITE_EXTERNAL_STORAGE_REQUEST = 647
private fun buildAndLaunchIntent(activity: Activity, databaseFile: Uri, keyFile: Uri?,
intentBuildLauncher: (Intent) -> Unit) {
@@ -757,13 +813,15 @@ open class PasswordActivity : StylishActivity() {
activity: Activity,
databaseFile: Uri,
keyFile: Uri?,
assistStructure: AssistStructure?) {
assistStructure: AssistStructure?,
searchInfo: SearchInfo?) {
if (assistStructure != null) {
buildAndLaunchIntent(activity, databaseFile, keyFile) { intent ->
AutofillHelper.startActivityForAutofillResult(
activity,
intent,
assistStructure)
assistStructure,
searchInfo)
}
} else {
launch(activity, databaseFile, keyFile)

View File

@@ -35,7 +35,7 @@ import android.widget.CompoundButton
import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.OpenFileHelper
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.view.KeyFileSelectionView
class AssignMasterKeyDialogFragment : DialogFragment() {
@@ -51,9 +51,8 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
private var passwordRepeatTextInputLayout: TextInputLayout? = null
private var passwordRepeatView: TextView? = null
private var keyFileTextInputLayout: TextInputLayout? = null
private var keyFileCheckBox: CompoundButton? = null
private var keyFileView: TextView? = null
private var keyFileSelectionView: KeyFileSelectionView? = null
private var mListener: AssignPasswordDialogListener? = null
@@ -69,16 +68,6 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
}
}
private val keyFileTextWatcher = object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
keyFileCheckBox?.isChecked = true
}
}
interface AssignPasswordDialogListener {
fun onAssignKeyDialogPositiveClick(masterPasswordChecked: Boolean, masterPassword: String?,
keyFileChecked: Boolean, keyFile: Uri?)
@@ -121,13 +110,14 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
passwordRepeatTextInputLayout = rootView?.findViewById(R.id.password_repeat_input_layout)
passwordRepeatView = rootView?.findViewById(R.id.pass_conf_password)
keyFileTextInputLayout = rootView?.findViewById(R.id.keyfile_input_layout)
keyFileCheckBox = rootView?.findViewById(R.id.keyfile_checkox)
keyFileView = rootView?.findViewById(R.id.pass_keyfile)
keyFileSelectionView = rootView?.findViewById(R.id.keyfile_selection)
mOpenFileHelper = OpenFileHelper(this)
rootView?.findViewById<View>(R.id.open_database_button)?.setOnClickListener { view ->
mOpenFileHelper?.openFileOnClickViewListener?.onClick(view) }
keyFileSelectionView?.apply {
setOnClickListener(mOpenFileHelper?.openFileOnClickViewListener)
setOnLongClickListener(mOpenFileHelper?.openFileOnClickViewListener)
}
val dialog = builder.create()
@@ -176,14 +166,12 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
// To check checkboxes if a text is present
passwordView?.addTextChangedListener(passwordTextWatcher)
keyFileView?.addTextChangedListener(keyFileTextWatcher)
}
override fun onPause() {
super.onPause()
passwordView?.removeTextChangedListener(passwordTextWatcher)
keyFileView?.removeTextChangedListener(keyFileTextWatcher)
}
private fun verifyPassword(): Boolean {
@@ -216,11 +204,11 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
if (keyFileCheckBox != null
&& keyFileCheckBox!!.isChecked) {
UriUtil.parse(keyFileView?.text?.toString())?.let { uri ->
keyFileSelectionView?.uri?.let { uri ->
mKeyFile = uri
} ?: run {
error = true
keyFileTextInputLayout?.error = getString(R.string.error_nokeyfile)
keyFileSelectionView?.error = getString(R.string.error_nokeyfile)
}
}
return error
@@ -265,8 +253,7 @@ class AssignMasterKeyDialogFragment : DialogFragment() {
) { uri ->
uri?.let { pathUri ->
keyFileCheckBox?.isChecked = true
keyFileView?.text = pathUri.toString()
keyFileSelectionView?.uri = pathUri
}
}
}

View File

@@ -52,14 +52,22 @@ class OpenFileHelper {
this.fragment = context
}
inner class OpenFileOnClickViewListener : View.OnClickListener {
inner class OpenFileOnClickViewListener : View.OnClickListener, View.OnLongClickListener {
override fun onClick(v: View) {
private fun onAbstractClick(longClick: Boolean = false) {
try {
try {
openActivityWithActionOpenDocument()
} catch(e: Exception) {
openActivityWithActionGetContent()
if (longClick) {
try {
openActivityWithActionGetContent()
} catch (e: Exception) {
openActivityWithActionOpenDocument()
}
} else {
try {
openActivityWithActionOpenDocument()
} catch (e: Exception) {
openActivityWithActionGetContent()
}
}
} catch (e: Exception) {
Log.e(TAG, "Enable to start the file picker activity", e)
@@ -68,6 +76,15 @@ class OpenFileHelper {
showBrowserDialog()
}
}
override fun onClick(v: View) {
onAbstractClick()
}
override fun onLongClick(v: View?): Boolean {
onAbstractClick(true)
return true
}
}
@SuppressLint("InlinedApi")

View File

@@ -28,8 +28,14 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.cursor.EntryCursorKDB
import com.kunzisoft.keepass.database.cursor.EntryCursorKDBX
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.view.strikeOut
@@ -69,8 +75,7 @@ class SearchEntryCursorAdapter(private val context: Context,
}
override fun bindView(view: View, context: Context, cursor: Cursor) {
database.getEntryFrom(cursor)?.let { currentEntry ->
getEntryFrom(cursor)?.let { currentEntry ->
val viewHolder = view.tag as ViewHolder
// Assign image
@@ -98,14 +103,46 @@ class SearchEntryCursorAdapter(private val context: Context,
}
}
private class ViewHolder {
internal var imageViewIcon: ImageView? = null
internal var textViewTitle: TextView? = null
internal var textViewSubTitle: TextView? = null
private fun getEntryFrom(cursor: Cursor): Entry? {
return database.createEntry()?.apply {
database.startManageEntry(this)
entryKDB?.let { entryKDB ->
(cursor as EntryCursorKDB).populateEntry(entryKDB, database.iconFactory)
}
entryKDBX?.let { entryKDBX ->
(cursor as EntryCursorKDBX).populateEntry(entryKDBX, database.iconFactory)
}
database.stopManageEntry(this)
}
}
override fun runQueryOnBackgroundThread(constraint: CharSequence): Cursor? {
return database.searchEntries(context, constraint.toString())
return searchEntries(context, constraint.toString())
}
private fun searchEntries(context: Context, query: String): Cursor? {
var cursorKDB: EntryCursorKDB? = null
var cursorKDBX: EntryCursorKDBX? = null
if (database.type == DatabaseKDB.TYPE)
cursorKDB = EntryCursorKDB()
if (database.type == DatabaseKDBX.TYPE)
cursorKDBX = EntryCursorKDBX()
val searchGroup = database.createVirtualGroupFromSearch(query, SearchHelper.MAX_SEARCH_ENTRY)
if (searchGroup != null) {
// Search in hide entries but not meta-stream
for (entry in searchGroup.getFilteredChildEntries(*Group.ChildFilter.getDefaults(context))) {
entry.entryKDB?.let {
cursorKDB?.addEntry(it)
}
entry.entryKDBX?.let {
cursorKDBX?.addEntry(it)
}
}
}
return cursorKDB ?: cursorKDBX
}
fun getEntryFromPosition(position: Int): Entry? {
@@ -113,9 +150,14 @@ class SearchEntryCursorAdapter(private val context: Context,
val cursor = this.cursor
if (cursor.moveToFirst() && cursor.move(position)) {
pwEntry = database.getEntryFrom(cursor)
pwEntry = getEntryFrom(cursor)
}
return pwEntry
}
private class ViewHolder {
internal var imageViewIcon: ImageView? = null
internal var textViewTitle: TextView? = null
internal var textViewSubTitle: TextView? = null
}
}

View File

@@ -31,9 +31,17 @@ import android.view.autofill.AutofillManager
import android.view.autofill.AutofillValue
import android.widget.RemoteViews
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
@RequiresApi(api = Build.VERSION_CODES.O)
@@ -42,6 +50,7 @@ object AutofillHelper {
private const val AUTOFILL_RESPONSE_REQUEST_CODE = 8165
private const val ASSIST_STRUCTURE = AutofillManager.EXTRA_ASSIST_STRUCTURE
const val KEY_SEARCH_INFO = "KEY_SEARCH_INFO"
fun retrieveAssistStructure(intent: Intent?): AssistStructure? {
intent?.let {
@@ -62,11 +71,28 @@ object AutofillHelper {
return ""
}
private fun buildDataset(context: Context,
entryInfo: EntryInfo,
struct: StructureParser.Result): Dataset? {
internal fun addHeader(responseBuilder: FillResponse.Builder,
packageName: String,
webDomain: String?,
applicationId: String?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (webDomain != null) {
responseBuilder.setHeader(RemoteViews(packageName, R.layout.item_autofill_web_domain).apply {
setTextViewText(R.id.autofill_web_domain_text, webDomain)
})
} else if (applicationId != null) {
responseBuilder.setHeader(RemoteViews(packageName, R.layout.item_autofill_app_id).apply {
setTextViewText(R.id.autofill_app_id_text, applicationId)
})
}
}
}
internal fun buildDataset(context: Context,
entryInfo: EntryInfo,
struct: StructureParser.Result): Dataset? {
val title = makeEntryTitle(entryInfo)
val views = newRemoteViews(context.packageName, title)
val views = newRemoteViews(context, title, entryInfo.icon)
val builder = Dataset.Builder(views)
builder.setId(entryInfo.id)
@@ -86,9 +112,16 @@ object AutofillHelper {
}
/**
* Method to hit when right key is selected
* Build the Autofill response for one entry
*/
fun buildResponseWhenEntrySelected(activity: Activity, entryInfo: EntryInfo) {
fun buildResponse(activity: Activity, entryInfo: EntryInfo) {
buildResponse(activity, ArrayList<EntryInfo>().apply { add(entryInfo) })
}
/**
* Build the Autofill response for many entry
*/
fun buildResponse(activity: Activity, entriesInfo: List<EntryInfo>) {
var setResultOk = false
activity.intent?.extras?.let { extras ->
if (extras.containsKey(ASSIST_STRUCTURE)) {
@@ -96,8 +129,9 @@ object AutofillHelper {
StructureParser(structure).parse()?.let { result ->
// New Response
val responseBuilder = FillResponse.Builder()
val dataset = buildDataset(activity, entryInfo, result)
responseBuilder.addDataset(dataset)
entriesInfo.forEach {
responseBuilder.addDataset(buildDataset(activity, it, result))
}
val mReplyIntent = Intent()
Log.d(activity.javaClass.name, "Successed Autofill auth.")
mReplyIntent.putExtra(
@@ -115,12 +149,48 @@ object AutofillHelper {
}
}
/**
* Utility method to perform actions if item is found or not after an auto search in [database]
*/
fun checkAutoSearchInfo(context: Context,
database: Database,
searchInfo: SearchInfo?,
onItemsFound: (items: List<EntryInfo>) -> Unit,
onItemNotFound: () -> Unit,
onDatabaseClosed: () -> Unit) {
if (database.loaded && TimeoutHelper.checkTime(context)) {
var searchWithoutUI = false
if (PreferencesUtil.isAutofillAutoSearchEnable(context)
&& searchInfo != null) {
// If search provide results
database.createVirtualGroupFromSearch(searchInfo, SearchHelper.MAX_SEARCH_ENTRY)?.let { searchGroup ->
if (searchGroup.getNumberOfChildEntries() > 0) {
searchWithoutUI = true
onItemsFound.invoke(
searchGroup.getChildEntriesInfo(database))
}
}
}
if (!searchWithoutUI) {
onItemNotFound.invoke()
}
} else {
onDatabaseClosed.invoke()
}
}
/**
* Utility method to start an activity with an Autofill for result
*/
fun startActivityForAutofillResult(activity: Activity, intent: Intent, assistStructure: AssistStructure) {
fun startActivityForAutofillResult(activity: Activity,
intent: Intent,
assistStructure: AssistStructure,
searchInfo: SearchInfo?) {
EntrySelectionHelper.addEntrySelectionModeExtraInIntent(intent)
intent.putExtra(ASSIST_STRUCTURE, assistStructure)
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
activity.startActivityForResult(intent, AUTOFILL_RESPONSE_REQUEST_CODE)
}
@@ -139,9 +209,18 @@ object AutofillHelper {
}
}
private fun newRemoteViews(packageName: String, remoteViewsText: String): RemoteViews {
val presentation = RemoteViews(packageName, R.layout.item_autofill_service)
presentation.setTextViewText(R.id.text, remoteViewsText)
private fun newRemoteViews(context: Context,
remoteViewsText: String,
remoteViewsIcon: IconImage? = null): RemoteViews {
val presentation = RemoteViews(context.packageName, R.layout.item_autofill_entry)
presentation.setTextViewText(R.id.autofill_entry_text, remoteViewsText)
if (remoteViewsIcon != null) {
presentation.assignDatabaseIcon(context,
R.id.autofill_entry_icon,
Database.getInstance().drawFactory,
remoteViewsIcon,
ContextCompat.getColor(context, R.color.green))
}
return presentation
}
}

View File

@@ -31,7 +31,7 @@ import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity
import com.kunzisoft.keepass.activities.GroupActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.model.SearchInfo
@RequiresApi(api = Build.VERSION_CODES.O)
class AutofillLauncherActivity : AppCompatActivity() {
@@ -40,13 +40,31 @@ class AutofillLauncherActivity : AppCompatActivity() {
// Pass extra for Autofill (EXTRA_ASSIST_STRUCTURE)
val assistStructure = AutofillHelper.retrieveAssistStructure(intent)
if (assistStructure != null) {
if (Database.getInstance().loaded && TimeoutHelper.checkTime(this))
GroupActivity.launchForAutofillResult(this,
assistStructure)
else {
FileDatabaseSelectActivity.launchForAutofillResult(this,
assistStructure)
// Build search param
val searchInfo = SearchInfo().apply {
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
}
// If database is open
AutofillHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
// Items found
AutofillHelper.buildResponse(this, items)
finish()
},
{
// Show the database UI to select the entry
GroupActivity.launchForAutofillResult(this,
assistStructure)
},
{
// If database not open
FileDatabaseSelectActivity.launchForAutofillResult(this,
assistStructure, searchInfo)
}
)
} else {
setResult(Activity.RESULT_CANCELED)
finish()
@@ -62,10 +80,20 @@ class AutofillLauncherActivity : AppCompatActivity() {
companion object {
fun getAuthIntentSenderForResponse(context: Context): IntentSender {
val intent = Intent(context, AutofillLauncherActivity::class.java)
private const val KEY_SEARCH_APPLICATION_ID = "KEY_SEARCH_APPLICATION_ID"
private const val KEY_SEARCH_DOMAIN = "KEY_SEARCH_DOMAIN"
fun getAuthIntentSenderForResponse(context: Context,
searchInfo: SearchInfo? = null): IntentSender {
return PendingIntent.getActivity(context, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT).intentSender
// Doesn't work with Parcelable (don't know why?)
Intent(context, AutofillLauncherActivity::class.java).apply {
searchInfo?.let {
putExtra(KEY_SEARCH_APPLICATION_ID, it.applicationId)
putExtra(KEY_SEARCH_DOMAIN, it.webDomain)
}
},
PendingIntent.FLAG_CANCEL_CURRENT).intentSender
}
}
}

View File

@@ -22,31 +22,78 @@ package com.kunzisoft.keepass.autofill
import android.os.Build
import android.os.CancellationSignal
import android.service.autofill.*
import androidx.annotation.RequiresApi
import android.util.Log
import android.widget.RemoteViews
import androidx.annotation.RequiresApi
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.model.SearchInfo
@RequiresApi(api = Build.VERSION_CODES.O)
class KeeAutofillService : AutofillService() {
override fun onFillRequest(request: FillRequest, cancellationSignal: CancellationSignal,
override fun onFillRequest(request: FillRequest,
cancellationSignal: CancellationSignal,
callback: FillCallback) {
val fillContexts = request.fillContexts
val latestStructure = fillContexts[fillContexts.size - 1].structure
cancellationSignal.setOnCancelListener { Log.w(TAG, "Cancel autofill.") }
val responseBuilder = FillResponse.Builder()
// Check user's settings for authenticating Responses and Datasets.
val parseResult = StructureParser(latestStructure).parse()
parseResult?.allAutofillIds()?.let { autofillIds ->
StructureParser(latestStructure).parse()?.let { parseResult ->
val searchInfo = SearchInfo().apply {
applicationId = parseResult.applicationId
webDomain = parseResult.domain
}
AutofillHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
val responseBuilder = FillResponse.Builder()
AutofillHelper.addHeader(responseBuilder, packageName,
parseResult.domain, parseResult.applicationId)
items.forEach {
responseBuilder.addDataset(AutofillHelper.buildDataset(this, it, parseResult))
}
callback.onSuccess(responseBuilder.build())
},
{
// Show UI if no search result
showUIForEntrySelection(parseResult, searchInfo, callback)
},
{
// Show UI if database not open
showUIForEntrySelection(parseResult, searchInfo, callback)
}
)
}
}
private fun showUIForEntrySelection(parseResult: StructureParser.Result,
searchInfo: SearchInfo,
callback: FillCallback) {
parseResult.allAutofillIds().let { autofillIds ->
if (autofillIds.isNotEmpty()) {
// If the entire Autofill Response is authenticated, AuthActivity is used
// to generate Response.
val sender = AutofillLauncherActivity.getAuthIntentSenderForResponse(this)
val presentation = RemoteViews(packageName, R.layout.item_autofill_service_unlock)
responseBuilder.setAuthentication(autofillIds, sender, presentation)
val sender = AutofillLauncherActivity.getAuthIntentSenderForResponse(this,
searchInfo)
val responseBuilder = FillResponse.Builder()
val remoteViewsUnlock: RemoteViews = if (!parseResult.domain.isNullOrEmpty()) {
RemoteViews(packageName, R.layout.item_autofill_unlock_web_domain).apply {
setTextViewText(R.id.autofill_web_domain_text, parseResult.domain)
}
} else if (!parseResult.applicationId.isNullOrEmpty()) {
RemoteViews(packageName, R.layout.item_autofill_unlock_app_id).apply {
setTextViewText(R.id.autofill_app_id_text, parseResult.applicationId)
}
} else {
RemoteViews(packageName, R.layout.item_autofill_unlock)
}
responseBuilder.setAuthentication(autofillIds, sender, remoteViewsUnlock)
callback.onSuccess(responseBuilder.build())
}
}

View File

@@ -20,6 +20,7 @@ package com.kunzisoft.keepass.autofill
import android.app.assist.AssistStructure
import android.os.Build
import android.text.InputType
import androidx.annotation.RequiresApi
import android.util.Log
import android.view.View
@@ -36,47 +37,60 @@ internal class StructureParser(private val structure: AssistStructure) {
private var usernameCandidate: AutofillId? = null
fun parse(): Result? {
result = Result()
result?.apply {
usernameCandidate = null
mainLoop@ for (i in 0 until structure.windowNodeCount) {
val windowNode = structure.getWindowNodeAt(i)
/*
title.add(windowNode.title)
windowNode.rootViewNode.webDomain?.let {
webDomain.add(it)
}
*/
if (parseViewNode(windowNode.rootViewNode))
break@mainLoop
}
// If not explicit username field found, add the field just before password field.
if (usernameId == null && passwordId != null && usernameCandidate != null)
usernameId = usernameCandidate
}
try {
result = Result()
result?.apply {
usernameCandidate = null
mainLoop@ for (i in 0 until structure.windowNodeCount) {
val windowNode = structure.getWindowNodeAt(i)
applicationId = windowNode.title.toString().split("/")[0]
Log.d(TAG, "Autofill applicationId: $applicationId")
// Return the result only if password field is retrieved
return if (result?.passwordId != null)
result
else
null
if (parseViewNode(windowNode.rootViewNode))
break@mainLoop
}
// If not explicit username field found, add the field just before password field.
if (usernameId == null && passwordId != null && usernameCandidate != null)
usernameId = usernameCandidate
}
// Return the result only if password field is retrieved
return if (result?.usernameId != null
&& result?.passwordId != null)
result
else
null
} catch (e: Exception) {
return null
}
}
private fun parseViewNode(node: AssistStructure.ViewNode): Boolean {
if (node.autofillId != null) {
val hints = node.autofillHints
if (hints != null && hints.isNotEmpty()) {
if (parseNodeByAutofillHint(node))
// Get the domain of a web app
node.webDomain?.let {
result?.domain = it
Log.d(TAG, "Autofill domain: $it")
}
// Only parse visible nodes
if (node.visibility == View.VISIBLE) {
if (node.autofillId != null
&& node.autofillType == View.AUTOFILL_TYPE_TEXT) {
// Parse methods
val hints = node.autofillHints
if (hints != null && hints.isNotEmpty()) {
if (parseNodeByAutofillHint(node))
return true
} else if (parseNodeByHtmlAttributes(node))
return true
} else {
if (parseNodeByHtmlAttributes(node))
else if (parseNodeByAndroidInput(node))
return true
}
// Recursive method to process each node
for (i in 0 until node.childCount) {
if (parseViewNode(node.getChildAt(i)))
return true
}
}
// Recursive method to process each node
for (i in 0 until node.childCount) {
if (parseViewNode(node.getChildAt(i)))
return true
}
return false
}
@@ -85,22 +99,23 @@ internal class StructureParser(private val structure: AssistStructure) {
val autofillId = node.autofillId
node.autofillHints?.forEach {
when {
it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_USERNAME
|| it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_EMAIL_ADDRESS
|| it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_PHONE -> {
it.equals(View.AUTOFILL_HINT_USERNAME, true)
|| it.equals(View.AUTOFILL_HINT_EMAIL_ADDRESS, true)
|| it.equals(View.AUTOFILL_HINT_PHONE, true)
|| it.equals("usernameOrEmail", true)-> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username hint")
}
it.toLowerCase(Locale.ENGLISH) == View.AUTOFILL_HINT_PASSWORD
|| it.toLowerCase(Locale.ENGLISH).contains("password") -> {
it.equals(View.AUTOFILL_HINT_PASSWORD, true)
|| it.contains("password", true) -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password hint")
return true
}
// Ignore autocomplete="off"
// https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
it.toLowerCase(Locale.ENGLISH) == "off" ||
it.toLowerCase(Locale.ENGLISH) == "on" -> {
it.equals("off", true) ||
it.equals("on", true) -> {
Log.d(TAG, "Autofill web hint")
return parseNodeByHtmlAttributes(node)
}
@@ -121,15 +136,15 @@ internal class StructureParser(private val structure: AssistStructure) {
when (pairAttribute.second.toLowerCase(Locale.ENGLISH)) {
"tel", "email" -> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
Log.d(TAG, "Autofill username web type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
}
"text" -> {
usernameCandidate = autofillId
Log.d(TAG, "Autofill type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
Log.d(TAG, "Autofill username candidate web type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
}
"password" -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
Log.d(TAG, "Autofill password web type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
return true
}
}
@@ -141,8 +156,57 @@ internal class StructureParser(private val structure: AssistStructure) {
return false
}
private fun parseNodeByAndroidInput(node: AssistStructure.ViewNode): Boolean {
val autofillId = node.autofillId
val inputType = node.inputType
if (inputType and InputType.TYPE_CLASS_TEXT != 0) {
when {
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS != 0 -> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username android type: $inputType")
}
inputType and InputType.TYPE_TEXT_VARIATION_NORMAL != 0 ||
inputType and InputType.TYPE_NUMBER_VARIATION_NORMAL != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_PERSON_NAME != 0 -> {
usernameCandidate = autofillId
Log.d(TAG, "Autofill username candidate android type: $inputType")
}
inputType and InputType.TYPE_TEXT_VARIATION_PASSWORD != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD != 0 ||
inputType and InputType.TYPE_NUMBER_VARIATION_PASSWORD != 0 -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password android type: $inputType")
return true
}
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_FILTER != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_PHONETIC != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_URI != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD != 0 -> {
// Type not used
}
else -> {
Log.d(TAG, "Autofill unknown android type: $inputType")
usernameCandidate = autofillId
}
}
}
return false
}
@RequiresApi(api = Build.VERSION_CODES.O)
internal class Result {
var applicationId: String? = null
var domain: String? = null
set(value) {
if (field == null)
field = value
}
var usernameId: AutofillId? = null
set(value) {
if (field == null)

View File

@@ -20,15 +20,11 @@
package com.kunzisoft.keepass.database.element
import android.content.ContentResolver
import android.content.Context
import android.content.res.Resources
import android.database.Cursor
import android.net.Uri
import android.util.Log
import com.kunzisoft.keepass.crypto.keyDerivation.KdfEngine
import com.kunzisoft.keepass.database.action.node.NodeHandler
import com.kunzisoft.keepass.database.cursor.EntryCursorKDB
import com.kunzisoft.keepass.database.cursor.EntryCursorKDBX
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
@@ -49,6 +45,7 @@ import com.kunzisoft.keepass.database.file.output.DatabaseOutputKDB
import com.kunzisoft.keepass.database.file.output.DatabaseOutputKDBX
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.icons.IconDrawableFactory
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.stream.readBytes4ToInt
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
import com.kunzisoft.keepass.utils.SingletonHolder
@@ -137,6 +134,9 @@ class Database {
val version: String
get() = mDatabaseKDB?.version ?: mDatabaseKDBX?.version ?: "-"
val type: Class<*>?
get() = mDatabaseKDB?.javaClass ?: mDatabaseKDBX?.javaClass
val allowDataCompression: Boolean
get() = mDatabaseKDBX != null
@@ -397,54 +397,17 @@ class Database {
false
}
@JvmOverloads
fun search(str: String, max: Int = Integer.MAX_VALUE): Group? {
return mSearchHelper?.search(this, str, max)
fun createVirtualGroupFromSearch(searchQuery: String, max: Int = Integer.MAX_VALUE): Group? {
return mSearchHelper?.createVirtualGroupWithSearchResult(this, searchQuery, max)
}
fun searchEntries(context: Context, query: String): Cursor? {
var cursorKDB: EntryCursorKDB? = null
var cursorKDBX: EntryCursorKDBX? = null
if (mDatabaseKDB != null)
cursorKDB = EntryCursorKDB()
if (mDatabaseKDBX != null)
cursorKDBX = EntryCursorKDBX()
val searchResult = search(query, SearchHelper.MAX_SEARCH_ENTRY)
if (searchResult != null) {
// Search in hide entries but not meta-stream
for (entry in searchResult.getFilteredChildEntries(*Group.ChildFilter.getDefaults(context))) {
entry.entryKDB?.let {
cursorKDB?.addEntry(it)
}
entry.entryKDBX?.let {
cursorKDBX?.addEntry(it)
}
}
}
return cursorKDB ?: cursorKDBX
}
fun getEntryFrom(cursor: Cursor): Entry? {
val iconFactory = mDatabaseKDB?.iconFactory ?: mDatabaseKDBX?.iconFactory ?: IconImageFactory()
return createEntry()?.apply {
startManageEntry(this)
mDatabaseKDB?.let {
entryKDB?.let { entryKDB ->
(cursor as EntryCursorKDB).populateEntry(entryKDB, iconFactory)
}
}
mDatabaseKDBX?.let {
entryKDBX?.let { entryKDBX ->
(cursor as EntryCursorKDBX).populateEntry(entryKDBX, iconFactory)
}
}
stopManageEntry(this)
}
fun createVirtualGroupFromSearch(searchInfo: SearchInfo, max: Int = Integer.MAX_VALUE): Group? {
val query = (if (searchInfo.webDomain != null)
searchInfo.webDomain
else
searchInfo.applicationId)
?: return null
return mSearchHelper?.createVirtualGroupWithSearchResult(this, query, max)
}
@Throws(DatabaseOutputException::class)

View File

@@ -398,6 +398,7 @@ class Entry : Node, EntryVersionedInterface<Group> {
database?.startManageEntry(this)
entryInfo.id = nodeId.toString()
entryInfo.title = title
entryInfo.icon = icon
entryInfo.username = username
entryInfo.password = password
entryInfo.url = url

View File

@@ -28,6 +28,7 @@ import com.kunzisoft.keepass.database.element.group.GroupVersionedInterface
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
import com.kunzisoft.keepass.database.element.node.*
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import java.util.*
import kotlin.collections.ArrayList
@@ -251,6 +252,14 @@ class Group : Node, GroupVersionedInterface<Group, Entry> {
ArrayList()
}
fun getChildEntriesInfo(database: Database): List<EntryInfo> {
val entriesInfo = ArrayList<EntryInfo>()
getChildEntries().forEach { entry ->
entriesInfo.add(entry.getEntryInfo(database))
}
return entriesInfo
}
fun getFilteredChildEntries(vararg filter: ChildFilter): List<Entry> {
val withoutMetaStream = filter.contains(ChildFilter.META_STREAM)
val showExpiredEntries = !filter.contains(ChildFilter.EXPIRED)

View File

@@ -26,7 +26,6 @@ import com.kunzisoft.keepass.database.element.entry.EntryKDB
import com.kunzisoft.keepass.database.element.group.GroupKDB
import com.kunzisoft.keepass.database.element.node.NodeIdInt
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
import com.kunzisoft.keepass.database.element.node.NodeVersioned
import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm
import com.kunzisoft.keepass.stream.NullOutputStream
import java.io.IOException
@@ -262,6 +261,7 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
}
companion object {
val TYPE = DatabaseKDB::class.java
const val BACKUP_FOLDER_TITLE = "Backup"
private const val BACKUP_FOLDER_UNDEFINED_ID = -1

View File

@@ -29,7 +29,8 @@ import com.kunzisoft.keepass.crypto.engine.CipherEngine
import com.kunzisoft.keepass.crypto.keyDerivation.KdfEngine
import com.kunzisoft.keepass.crypto.keyDerivation.KdfFactory
import com.kunzisoft.keepass.crypto.keyDerivation.KdfParameters
import com.kunzisoft.keepass.database.element.*
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.DeletedObject
import com.kunzisoft.keepass.database.element.database.DatabaseKDB.Companion.BACKUP_FOLDER_TITLE
import com.kunzisoft.keepass.database.element.entry.EntryKDBX
import com.kunzisoft.keepass.database.element.group.GroupKDBX
@@ -551,6 +552,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
}
companion object {
val TYPE = DatabaseKDBX::class.java
private val TAG = DatabaseKDBX::class.java.name
private const val DEFAULT_HISTORY_MAX_ITEMS = 10 // -1 unlimited

View File

@@ -26,7 +26,6 @@ import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIterator
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDB
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDBX
import java.util.*
class SearchHelper(private val isOmitBackup: Boolean) {
@@ -36,22 +35,19 @@ class SearchHelper(private val isOmitBackup: Boolean) {
private var incrementEntry = 0
fun search(database: Database, qStr: String, max: Int): Group? {
fun createVirtualGroupWithSearchResult(database: Database, searchQuery: String, max: Int): Group? {
val searchGroup = database.createGroup()
searchGroup?.title = "\"" + qStr + "\""
searchGroup?.title = "\"" + searchQuery + "\""
// Search all entries
val loc = Locale.getDefault()
val finalQStr = qStr.toLowerCase(loc)
incrementEntry = 0
database.rootGroup?.doForEachChild(
object : NodeHandler<Entry>() {
override fun operate(node: Entry): Boolean {
if (incrementEntry >= max)
return false
if (entryContainsString(node, finalQStr, loc)) {
if (entryContainsString(node, searchQuery)) {
searchGroup?.addChildEntry(node)
incrementEntry++
}
@@ -73,7 +69,7 @@ class SearchHelper(private val isOmitBackup: Boolean) {
return searchGroup
}
private fun entryContainsString(entry: Entry, searchString: String, locale: Locale): Boolean {
private fun entryContainsString(entry: Entry, searchString: String): Boolean {
// Entry don't contains string if the search string is empty
if (searchString.isEmpty())
@@ -90,11 +86,10 @@ class SearchHelper(private val isOmitBackup: Boolean) {
iterator?.let {
while (it.hasNext()) {
val str = it.next()
if (str.isNotEmpty()) {
if (str.toLowerCase(locale).contains(searchString)) {
val currentString = it.next()
if (currentString.isNotEmpty()
&& currentString.contains(searchString, true)) {
return true
}
}
}
}

View File

@@ -39,7 +39,7 @@ constructor(private val mEntry: EntryKDB,
title -> mEntry.title
url -> mEntry.url
username -> mEntry.username
comment -> mEntry.notes
notes -> mEntry.notes
else -> ""
}
}
@@ -73,7 +73,7 @@ constructor(private val mEntry: EntryKDB,
title -> mSearchParameters.searchInTitles
url -> mSearchParameters.searchInUrls
username -> mSearchParameters.searchInUserNames
comment -> mSearchParameters.searchInNotes
notes -> mSearchParameters.searchInNotes
else -> true
}
@@ -88,7 +88,7 @@ constructor(private val mEntry: EntryKDB,
private const val title = 0
private const val url = 1
private const val username = 2
private const val comment = 3
private const val notes = 3
private const val maxEntries = 4
}

View File

@@ -22,16 +22,16 @@ package com.kunzisoft.keepass.icons
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import androidx.core.content.res.ResourcesCompat
import androidx.core.widget.ImageViewCompat
import android.util.Log
import android.widget.ImageView
import android.widget.RemoteViews
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.widget.ImageViewCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
@@ -70,6 +70,23 @@ class IconDrawableFactory {
}
}
/**
* Utility method to assign a drawable to a RemoteView and tint it
*/
fun assignDrawableToRemoteViews(superDrawable: SuperDrawable,
remoteViews: RemoteViews,
imageId: Int,
tintColor: Int = Color.BLACK) {
val bitmap = superDrawable.drawable.toBitmap()
// Tint bitmap if it's not a custom icon
if (!superDrawable.custom) {
Canvas(bitmap).drawBitmap(bitmap, 0.0F, 0.0F, Paint().apply {
colorFilter = PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN)
})
}
remoteViews.setImageViewBitmap(imageId, bitmap)
}
/**
* Get the [SuperDrawable] [icon] (from cache, or build it and add it to the cache if not exists yet), then [tint] it with [tintColor] if needed
*/
@@ -233,7 +250,6 @@ class IconDrawableFactory {
*/
fun ImageView.assignDefaultDatabaseIcon(iconFactory: IconDrawableFactory, tintColor: Int = Color.WHITE) {
IconPackChooser.getSelectedIconPack(context)?.let { selectedIconPack ->
iconFactory.assignDrawableToImageView(
iconFactory.getIconSuperDrawable(context,
selectedIconPack.defaultIconId,
@@ -249,9 +265,10 @@ fun ImageView.assignDefaultDatabaseIcon(iconFactory: IconDrawableFactory, tintCo
/**
* Assign a database [icon] to an ImageView and tint it with [tintColor] if needed
*/
fun ImageView.assignDatabaseIcon(iconFactory: IconDrawableFactory, icon: IconImage, tintColor: Int = Color.WHITE) {
fun ImageView.assignDatabaseIcon(iconFactory: IconDrawableFactory,
icon: IconImage,
tintColor: Int = Color.WHITE) {
IconPackChooser.getSelectedIconPack(context)?.let { selectedIconPack ->
iconFactory.assignDrawableToImageView(
iconFactory.getIconSuperDrawable(context,
icon,
@@ -263,3 +280,19 @@ fun ImageView.assignDatabaseIcon(iconFactory: IconDrawableFactory, icon: IconIma
tintColor)
}
}
fun RemoteViews.assignDatabaseIcon(context: Context,
imageId: Int,
iconFactory: IconDrawableFactory,
icon: IconImage,
tintColor: Int = Color.BLACK) {
iconFactory.assignDrawableToRemoteViews(
iconFactory.getIconSuperDrawable(context,
icon,
24,
true,
tintColor),
this,
imageId,
tintColor)
}

View File

@@ -21,6 +21,7 @@ package com.kunzisoft.keepass.model
import android.os.Parcel
import android.os.Parcelable
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.otp.OtpElement
import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD
import java.util.*
@@ -29,6 +30,7 @@ class EntryInfo : Parcelable {
var id: String = ""
var title: String = ""
var icon: IconImage? = null
var username: String = ""
var password: String = ""
var url: String = ""
@@ -41,6 +43,7 @@ class EntryInfo : Parcelable {
private constructor(parcel: Parcel) {
id = parcel.readString() ?: id
title = parcel.readString() ?: title
icon = parcel.readParcelable(IconImage::class.java.classLoader)
username = parcel.readString() ?: username
password = parcel.readString() ?: password
url = parcel.readString() ?: url
@@ -56,6 +59,7 @@ class EntryInfo : Parcelable {
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(id)
parcel.writeString(title)
parcel.writeParcelable(icon, flags)
parcel.writeString(username)
parcel.writeString(password)
parcel.writeString(url)

View File

@@ -0,0 +1,42 @@
package com.kunzisoft.keepass.model
import android.os.Parcel
import android.os.Parcelable
class SearchInfo : Parcelable {
var applicationId: String? = null
var webDomain: String? = null
constructor()
private constructor(parcel: Parcel) {
val readAppId = parcel.readString()
applicationId = if (readAppId.isNullOrEmpty()) null else readAppId
val readDomain = parcel.readString()
webDomain = if (readDomain.isNullOrEmpty()) null else readDomain
}
override fun describeContents(): Int {
return 0
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(applicationId ?: "")
parcel.writeString(webDomain ?: "")
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<SearchInfo> = object : Parcelable.Creator<SearchInfo> {
override fun createFromParcel(parcel: Parcel): SearchInfo {
return SearchInfo(parcel)
}
override fun newArray(size: Int): Array<SearchInfo?> {
return arrayOfNulls(size)
}
}
}
}

View File

@@ -74,7 +74,7 @@ object OtpEntryFields {
// [^&=\s]+=[^&=\s]+(&[^&=\s]+=[^&=\s]+)*
private const val validKeyValue = "[^&=\\s]+"
private const val validKeyValuePair = "$validKeyValue=$validKeyValue"
private const val validKeyValueRegex = "$validKeyValuePair&($validKeyValuePair)*"
private const val validKeyValueRegex = "$validKeyValuePair(&$validKeyValuePair)*"
/**
* Parse fields of an entry to retrieve an OtpElement
@@ -243,21 +243,18 @@ object OtpEntryFields {
val plainText = getField(OTP_FIELD)
if (plainText != null && plainText.isNotEmpty()) {
if (Pattern.matches(validKeyValueRegex, plainText)) {
try {
return try {
// KeeOtp string format
val query = breakDownKeyValuePairs(plainText)
var secretString = query[SEED_KEY]
if (secretString == null)
secretString = ""
otpElement.setBase32Secret(secretString)
otpElement.digits = query[DIGITS_KEY]?.toIntOrNull() ?: OTP_DEFAULT_DIGITS
otpElement.period = query[STEP_KEY]?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
otpElement.setBase32Secret(query[SEED_KEY] ?: "")
otpElement.digits = query[DIGITS_KEY]?.toIntOrNull() ?: OTP_DEFAULT_DIGITS
otpElement.period = query[STEP_KEY]?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
otpElement.type = OtpType.TOTP
return true
otpElement.type = OtpType.TOTP
true
} catch (exception: Exception) {
return false
false
}
} else {
// Malformed

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.widget.Toolbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
class AutofillSettingsActivity : StylishActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_toolbar)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
toolbar.setTitle(R.string.autofill_preference_title)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, AutofillSettingsFragment())
.commit()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> onBackPressed()
}
return super.onOptionsItemSelected(item)
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
@@ -20,16 +20,14 @@
package com.kunzisoft.keepass.settings
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceFragmentCompat
class SettingsAutofillActivity : SettingsActivity() {
import com.kunzisoft.keepass.R
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mTimeoutEnable = false
}
class AutofillSettingsFragment : PreferenceFragmentCompat() {
override fun retrieveMainFragment(): Fragment {
return NestedSettingsFragment.newInstance(NestedSettingsFragment.Screen.FORM_FILLING)
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
// Load the preferences from an XML resource
setPreferencesFromResource(R.xml.preferences_autofill, rootKey)
}
}

View File

@@ -26,7 +26,7 @@ import android.view.MenuItem
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
class MagikIMESettings : StylishActivity() {
class MagikeyboardSettingsActivity : StylishActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -39,7 +39,7 @@ class MagikIMESettings : StylishActivity() {
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, MagikIMESettingsFragment())
.replace(R.id.fragment_container, MagikeyboardSettingsFragment())
.commit()
}
}

View File

@@ -24,7 +24,7 @@ import androidx.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R
class MagikIMESettingsFragment : PreferenceFragmentCompat() {
class MagikeyboardSettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
// Load the preferences from an XML resource

View File

@@ -24,7 +24,6 @@ import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
import com.kunzisoft.keepass.database.element.Database
class MainPreferenceFragment : PreferenceFragmentCompat() {

View File

@@ -160,12 +160,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
}
findPreference<Preference>(getString(R.string.magic_keyboard_preference_key))?.setOnPreferenceClickListener {
startActivity(Intent(context, MagikIMESettings::class.java))
false
}
findPreference<Preference>(getString(R.string.clipboard_explanation_key))?.setOnPreferenceClickListener {
UriUtil.gotoUrl(context!!, R.string.clipboard_explanation_url)
startActivity(Intent(context, MagikeyboardSettingsActivity::class.java))
false
}
@@ -174,6 +169,16 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
false
}
findPreference<Preference>(getString(R.string.settings_autofill_key))?.setOnPreferenceClickListener {
startActivity(Intent(context, AutofillSettingsActivity::class.java))
false
}
findPreference<Preference>(getString(R.string.clipboard_explanation_key))?.setOnPreferenceClickListener {
UriUtil.gotoUrl(context!!, R.string.clipboard_explanation_url)
false
}
// Present in two places
allowCopyPassword()
}

View File

@@ -31,7 +31,6 @@ import com.kunzisoft.androidclearchroma.ChromaUtil
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.lock
import com.kunzisoft.keepass.crypto.keyDerivation.KdfEngine
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
@@ -551,14 +550,10 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment() {
val settingActivity = activity as SettingsActivity?
when (item.itemId) {
R.id.menu_lock -> {
settingActivity?.lock()
return true
}
return when (item.itemId) {
R.id.menu_save_database -> {
settingActivity?.mProgressDialogThread?.startDatabaseSave(!mDatabaseReadOnly)
return true
true
}
else -> {
@@ -566,7 +561,7 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment() {
settingActivity?.let {
MenuUtil.onDefaultMenuOptionsItemSelected(it, item, mDatabaseReadOnly, true)
}
return super.onOptionsItemSelected(item)
super.onOptionsItemSelected(item)
}
}
}

View File

@@ -199,6 +199,12 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.lock_database_back_root_default))
}
fun showLockDatabaseButton(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.lock_database_show_button_key),
context.resources.getBoolean(R.bool.lock_database_show_button_default))
}
fun isAutoSaveDatabaseEnabled(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.enable_auto_save_database_key),
@@ -348,4 +354,10 @@ object PreferencesUtil {
return prefs.getBoolean(context.getString(R.string.keyboard_key_sound_key),
context.resources.getBoolean(R.bool.keyboard_key_sound_default))
}
fun isAutofillAutoSearchEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.autofill_auto_search_key),
context.resources.getBoolean(R.bool.autofill_auto_search_default))
}
}

View File

@@ -26,6 +26,8 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment
@@ -47,6 +49,7 @@ open class SettingsActivity
private var coordinatorLayout: CoordinatorLayout? = null
private var toolbar: Toolbar? = null
private var lockView: View? = null
companion object {
@@ -84,6 +87,11 @@ open class SettingsActivity
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
lockAndExit()
}
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, retrieveMainFragment())
@@ -154,6 +162,23 @@ open class SettingsActivity
keyFile: Uri?) {
}
private fun hideOrShowLockButton(key: NestedSettingsFragment.Screen) {
if (PreferencesUtil.showLockDatabaseButton(this)) {
when (key) {
NestedSettingsFragment.Screen.DATABASE,
NestedSettingsFragment.Screen.DATABASE_MASTER_KEY,
NestedSettingsFragment.Screen.DATABASE_SECURITY -> {
lockView?.visibility = View.VISIBLE
}
else -> {
lockView?.visibility = View.GONE
}
}
} else {
lockView?.visibility = View.GONE
}
}
override fun onBackPressed() {
// this if statement is necessary to navigate through nested and main fragments
if (supportFragmentManager.backStackEntryCount == 0) {
@@ -162,6 +187,7 @@ open class SettingsActivity
supportFragmentManager.popBackStack()
}
toolbar?.setTitle(R.string.settings)
hideOrShowLockButton(NestedSettingsFragment.Screen.APPLICATION)
}
private fun replaceFragment(key: NestedSettingsFragment.Screen) {
@@ -173,6 +199,7 @@ open class SettingsActivity
.commit()
toolbar?.title = NestedSettingsFragment.retrieveTitle(resources, key)
hideOrShowLockButton(key)
}
override fun onNestedPreferenceSelected(key: NestedSettingsFragment.Screen) {

View File

@@ -20,6 +20,7 @@ package com.kunzisoft.keepass.view
import android.content.Context
import android.graphics.Color
import android.text.util.Linkify
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
@@ -71,8 +72,8 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
private val urlContainerView: View
private val urlView: TextView
private val commentContainerView: View
private val commentView: TextView
private val notesContainerView: View
private val notesView: TextView
private val extrasContainerView: View
private val extrasView: ViewGroup
@@ -120,8 +121,8 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
urlContainerView = findViewById(R.id.entry_url_container)
urlView = findViewById(R.id.entry_url)
commentContainerView = findViewById(R.id.entry_notes_container)
commentView = findViewById(R.id.entry_notes)
notesContainerView = findViewById(R.id.entry_notes_container)
notesView = findViewById(R.id.entry_notes)
extrasContainerView = findViewById(R.id.extra_strings_container)
extrasView = findViewById(R.id.extra_strings)
@@ -289,15 +290,17 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
fun assignComment(comment: String?) {
if (comment != null && comment.isNotEmpty()) {
commentContainerView.visibility = View.VISIBLE
commentView.apply {
notesContainerView.visibility = View.VISIBLE
notesView.apply {
text = comment
if (fontInVisibility)
applyFontVisibility()
}
try {
Linkify.addLinks(notesView, Linkify.ALL)
} catch (e: Exception) {}
} else {
commentContainerView.visibility = View.GONE
notesContainerView.visibility = View.GONE
}
}

View File

@@ -200,12 +200,16 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
val customFieldsArray = ArrayList<Field>()
// Add extra fields from views
entryExtraFieldsContainer.let {
for (i in 0 until it.childCount) {
val view = it.getChildAt(i) as EntryEditCustomField
val key = view.label
val value = view.value
val protect = view.isProtected
customFieldsArray.add(Field(key, ProtectedString(protect, value)))
try {
for (i in 0 until it.childCount) {
val view = it.getChildAt(i) as EntryEditCustomField
val key = view.label
val value = view.value
val protect = view.isProtected
customFieldsArray.add(Field(key, ProtectedString(protect, value)))
}
} catch (exception: Exception) {
// Extra field container contains another type of view
}
}
return customFieldsArray
@@ -215,11 +219,14 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
* Add a new view to fill in the information of the customized field and focus it
*/
fun addEmptyCustomField() {
val entryEditCustomField = EntryEditCustomField(context).apply {
setFontVisibility(fontInVisibility)
requestFocus()
// Fix current custom field before adding a new one
if (isValid()) {
val entryEditCustomField = EntryEditCustomField(context).apply {
setFontVisibility(fontInVisibility)
requestFocus()
}
entryExtraFieldsContainer.addView(entryEditCustomField)
}
entryExtraFieldsContainer.addView(entryEditCustomField)
}
/**
@@ -254,26 +261,34 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
* @return ErrorValidation An error with a message or a validation without message
*/
fun isValid(): Boolean {
var isValid = true
// Validate password
if (entryPasswordView.text.toString() != entryConfirmationPasswordView.text.toString()) {
entryPasswordLayoutView.error = context.getString(R.string.error_pass_match)
isValid = false
return false
} else {
entryPasswordLayoutView.error = null
}
// Validate extra fields
entryExtraFieldsContainer.let {
for (i in 0 until it.childCount) {
val entryEditCustomField = it.getChildAt(i) as EntryEditCustomField
if (!entryEditCustomField.isValid()) {
isValid = false
try {
val customFieldLabelSet = HashSet<String>()
for (i in 0 until it.childCount) {
val entryEditCustomField = it.getChildAt(i) as EntryEditCustomField
if (customFieldLabelSet.contains(entryEditCustomField.label)) {
entryEditCustomField.setError(R.string.error_label_exists)
return false
}
customFieldLabelSet.add(entryEditCustomField.label)
if (!entryEditCustomField.isValid()) {
return false
}
}
} catch (exception: Exception) {
return false
}
}
return isValid
return true
}
}

View File

@@ -30,6 +30,7 @@ import android.widget.CompoundButton
import android.widget.EditText
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.StringRes
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.security.ProtectedString
@@ -84,14 +85,20 @@ class EntryEditCustomField @JvmOverloads constructor(context: Context,
fun isValid(): Boolean {
// Validate extra field
if (label.isEmpty()) {
labelLayoutView.error = context.getString(R.string.error_string_key)
setError(R.string.error_string_key)
return false
} else {
labelLayoutView.error = null
setError(null)
}
return true
}
fun setError(@StringRes errorId: Int?) {
labelLayoutView.error = if (errorId == null) null else {
context.getString(errorId)
}
}
fun setFontVisibility(applyFontVisibility: Boolean) {
if (applyFontVisibility)
valueView.applyFontVisibility()

View File

@@ -0,0 +1,60 @@
package com.kunzisoft.keepass.view
import android.content.Context
import android.net.Uri
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.documentfile.provider.DocumentFile
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
class KeyFileSelectionView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0)
: ConstraintLayout(context, attrs, defStyle) {
private var mUri: Uri? = null
private val keyFileNameInputLayout: TextInputLayout
private val keyFileNameView: TextView
private val keyFileOpenView: ImageView
init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater?.inflate(R.layout.view_keyfile_selection, this)
keyFileNameInputLayout = findViewById(R.id.input_entry_keyfile)
keyFileNameView = findViewById(R.id.keyfile_name)
keyFileOpenView = findViewById(R.id.keyfile_open_button)
}
override fun setOnClickListener(l: OnClickListener?) {
super.setOnClickListener(l)
keyFileNameView.setOnClickListener(l)
}
override fun setOnLongClickListener(l: OnLongClickListener?) {
super.setOnLongClickListener(l)
keyFileNameView.setOnLongClickListener(l)
}
var error: CharSequence?
get() = keyFileNameInputLayout.error
set(value) {
keyFileNameInputLayout.error = value
}
var uri: Uri?
get() {
return mUri
}
set(value) {
mUri = value
keyFileNameView.text = value?.let {
DocumentFile.fromSingleUri(context, value)?.name ?: ""
} ?: ""
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimaryDark" android:state_pressed="true" />
<item android:color="@color/grey_dark" android:state_enabled="false" />
<item android:color="?android:windowBackground" android:state_enabled="true" />
</selector>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/white"
tools:targetApi="lollipop">
<item>
<shape>
<corners
android:topLeftRadius="0dp"
android:topRightRadius="40dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"/>
<solid android:color="?android:attr/windowBackground"/>
</shape>
</item>
</ripple>

View File

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

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true">
<shape>
<corners
android:topLeftRadius="0dp"
android:topRightRadius="40dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"/>
<padding
android:left="4dp"
android:right="12dp"
android:top="18dp"
android:bottom="8dp"/>
<solid android:color="@color/grey_dark"/>
</shape>
</item>
<item>
<shape>
<corners
android:topLeftRadius="0dp"
android:topRightRadius="40dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"/>
<padding
android:left="4dp"
android:right="12dp"
android:top="18dp"
android:bottom="8dp"/>
<solid android:color="@color/grey"/>
</shape>
</item>
</selector>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/white">
<item>
<shape>
<stroke
android:width="1dp"
android:color="@color/green" />
<corners
android:topLeftRadius="0dp"
android:topRightRadius="40dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"/>
<solid
android:color="@color/transparent"/>
</shape>
</item>
</selector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM11,19.93c-3.95,-0.49 -7,-3.85 -7,-7.93 0,-0.62 0.08,-1.21 0.21,-1.79L9,15v1c0,1.1 0.9,2 2,2v1.93zM17.9,17.39c-0.26,-0.81 -1,-1.39 -1.9,-1.39h-1v-3c0,-0.55 -0.45,-1 -1,-1L8,12v-2h2c0.55,0 1,-0.45 1,-1L11,7h2c1.1,0 2,-0.9 2,-2v-0.41c2.93,1.19 5,4.06 5,7.41 0,2.08 -0.8,3.97 -2.1,5.39z"/>
</vector>

View File

@@ -20,6 +20,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -31,7 +32,6 @@
android:layout_height="@dimen/toolbar_parallax_height">
<com.google.android.material.appbar.CollapsingToolbarLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -126,4 +126,10 @@
</androidx.core.widget.NestedScrollView>
<include
layout="@layout/view_button_lock"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="start|bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -102,6 +102,12 @@
</androidx.core.widget.NestedScrollView>
<include
layout="@layout/view_button_lock"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="start|bottom" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/entry_edit_validate"
android:layout_width="match_parent"

View File

@@ -24,45 +24,40 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAutofill="noExcludeDescendants"
android:background="?attr/colorPrimaryDark"
tools:targetApi="o">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/content_description_background"
android:background="@drawable/background_repeat"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/activity_file_selection_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/background_repeat"
android:backgroundTint="?attr/colorPrimary"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/file_selection_buttons_container">
<androidx.core.widget.NestedScrollView
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="@dimen/toolbar_parallax_height">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<LinearLayout
android:id="@+id/file_selection_title_container"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
app:layout_collapseMode="parallax"
android:layout_gravity="center_horizontal|bottom"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent"
android:paddingLeft="24dp"
android:paddingStart="24dp"
android:paddingRight="24dp"
android:paddingEnd="24dp"
android:paddingTop="48dp"
android:paddingBottom="24dp"
android:layout_marginBottom="36dp">
android:paddingBottom="48dp">
<TextView
android:id="@+id/file_selection_title_part_1"
android:layout_width="wrap_content"
@@ -110,63 +105,49 @@
android:gravity="center"
android:text="@string/app_name_part3"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:background="?attr/colorPrimary" />
<TextView android:id="@+id/label_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginStart="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:layout_marginEnd="@dimen/default_margin"
android:layout_marginBottom="@dimen/default_margin"
android:gravity="center"
android:textColor="?attr/textColorInverse"
app:layout_constraintTop_toBottomOf="@+id/file_selection_title_container"
android:visibility="gone" />
<LinearLayout
android:id="@+id/container_file_list"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_margin="24dp"
android:elevation="6dp"
android:background="?attr/colorPrimaryDark"
android:visibility="invisible"
app:layout_constraintWidth_percent="@dimen/content_percent"
app:layout_constraintTop_toBottomOf="@+id/label_warning"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical">
<TextView
android:id="@+id/file_list_title"
android:layout_width="match_parent"
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="?attr/toolbarAppearance"
app:layout_constraintTop_toTopOf="parent"
android:elevation="4dp"
app:layout_collapseMode="pin"
android:popupTheme="?attr/toolbarPopupAppearance" />
<FrameLayout
android:layout_width="48dp"
android:layout_height="?attr/actionBarSize"
android:padding="12dp"
android:elevation="4dp"
android:layout_gravity="top|start"
app:layout_collapseMode="pin">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/file_manager_explanation_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
style="@style/KeepassDXStyle.TextAppearance.Title"
android:background="?attr/colorPrimary"
android:textColor="?android:attr/textColorHintInverse"
android:text="@string/open_recent"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/file_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
android:layout_gravity="center"
android:src="@drawable/ic_folder_open_white_24dp"
app:tint="?android:attr/textColorHintInverse"
android:contentDescription="@string/about"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/file_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="insideOverlay"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent"
android:elevation="4dp"
android:background="@color/transparent"
android:theme="?attr/toolbarAppearance"
android:popupTheme="?attr/toolbarPopupAppearance" />
<FrameLayout
android:id="@+id/file_selection_buttons_container"
android:layout_width="0dp"
@@ -182,7 +163,7 @@
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/open_database_button"
android:id="@+id/open_keyfile_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/select_database_file"
@@ -210,6 +191,11 @@
android:paddingEnd="24dp"
android:text="@string/create_keepass_file"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="top"
android:background="?attr/colorPrimaryDark"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -140,12 +140,19 @@
android:background="?android:attr/windowBackground" />
</LinearLayout>
<include
layout="@layout/view_button_lock"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_anchor="@+id/node_list_container"
app:layout_anchorGravity="start|bottom" />
<com.kunzisoft.keepass.view.AddNodeButtonView
android:id="@+id/add_node_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@+id/node_list_container"
app:layout_anchorGravity="right|bottom" />
app:layout_anchorGravity="end|bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.kunzisoft.keepass.view.ToolbarAction

View File

@@ -162,58 +162,33 @@
</RelativeLayout>
<!-- File Input -->
<RelativeLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container_key_file"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/keyfile_checkox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:paddingBottom="20dp"
android:contentDescription="@string/content_description_keyfile_checkbox"
android:focusable="false"
android:layout_alignBottom="@+id/input_entry_keyfile"
android:gravity="center_vertical"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_entry_keyfile"
android:layout_width="wrap_content"
<com.kunzisoft.keepass.view.KeyFileSelectionView
android:id="@+id/keyfile_selection"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/keyfile_checkox"
app:layout_constraintEnd_toEndOf="parent"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:layout_toEndOf="@+id/keyfile_checkox"
android:layout_toRightOf="@+id/keyfile_checkox"
android:layout_toLeftOf="@+id/open_database_button"
android:layout_toStartOf="@+id/open_database_button">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/pass_keyfile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:hint="@string/entry_keyfile"
android:inputType="textUri"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:imeOptions="actionDone"
android:maxLines="1"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/open_database_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:layout_alignBottom="@+id/input_entry_keyfile"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:contentDescription="@string/content_description_open_file"
android:focusable="true"
android:src="@drawable/ic_folder_white_24dp"
android:tint="?attr/colorAccent"/>
</RelativeLayout>
android:importantForAutofill="no" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -239,7 +214,7 @@
android:paddingEnd="24dp"
android:paddingRight="24dp"
style="@style/KeepassDXStyle.TextAppearance.TinyText"
android:text="@string/warning_database_read_only"
android:text="@string/warning_database_link_revoked"
android:textColor="?attr/textColorInverse"
android:background="?attr/colorAccent"
app:layout_constraintBottom_toTopOf="@+id/activity_password_info_delimiter"

View File

@@ -17,8 +17,9 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -38,4 +39,12 @@
android:layout_height="match_parent" />
</LinearLayout>
<include
layout="@layout/view_button_lock"
android:layout_width="48dp"
android:layout_height="48dp"
android:visibility="gone"
android:layout_gravity="start|bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -44,6 +44,7 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/nodes_list"
android:contentDescription="@string/content_description_node_children"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground" />

View File

@@ -109,44 +109,14 @@
android:layout_height="wrap_content"
android:text="@string/entry_keyfile"/>
<RelativeLayout
<com.kunzisoft.keepass.view.KeyFileSelectionView
android:id="@+id/keyfile_selection"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/open_database_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:contentDescription="@string/content_description_open_file"
android:layout_alignTop="@+id/keyfile_input_layout"
android:layout_alignBottom="@+id/keyfile_input_layout"
android:padding="12dp"
android:src="@drawable/ic_folder_white_24dp"
android:tint="?attr/colorAccent" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/keyfile_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/open_database_button"
android:layout_toStartOf="@+id/open_database_button"
android:importantForAccessibility="no"
android:importantForAutofill="no"
app:passwordToggleEnabled="true"
app:passwordToggleTint="?attr/colorAccent">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/pass_keyfile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:hint="@string/hint_keyfile"
android:maxLines="1"
android:singleLine="true"/>
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/keyfile_checkox"
app:layout_constraintEnd_toEndOf="parent" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?><!--
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/green"
android:minHeight="24dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/autofill_app_id_icon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:contentDescription="@string/about"
android:src="@drawable/ic_apps_white_24dp"/>
<TextView
android:id="@+id/autofill_app_id_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="@color/white"
android:layout_gravity="center"
android:paddingRight="12dp"
android:paddingEnd="12dp"
android:paddingLeft="12dp"
android:paddingStart="12dp" />
</LinearLayout>

View File

@@ -22,7 +22,7 @@
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
android:id="@+id/autofill_entry_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@@ -30,17 +30,17 @@
android:layout_marginEnd="12dp"
android:layout_marginLeft="12dp"
android:layout_marginStart="12dp"
android:src="@drawable/ic_key_white_24dp"
android:tint="@color/green"/>
android:contentDescription="@string/content_description_entry_icon"
android:src="@drawable/ic_key_white_24dp" />
<TextView
android:id="@+id/text"
android:id="@+id/autofill_entry_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingRight="12dp"
android:paddingEnd="12dp"
android:paddingLeft="12dp"
android:paddingStart="12dp"
android:paddingLeft="0dp"
android:paddingStart="0dp"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
</LinearLayout>

View File

@@ -16,32 +16,27 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:minHeight="48dp"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:contentDescription="@string/app_name"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/autofill_sign_in_prompt"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:layout_gravity="center"
android:paddingRight="12dp"
android:paddingEnd="12dp"
android:paddingLeft="12dp"
android:paddingStart="12dp"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
</LinearLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?><!--
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="@layout/item_autofill_app_id"/>
<include
layout="@layout/item_autofill_unlock"/>
</LinearLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?><!--
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="@layout/item_autofill_web_domain"/>
<include
layout="@layout/item_autofill_unlock"/>
</LinearLayout>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?><!--
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/green"
android:minHeight="24dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/autofill_web_domain_icon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:contentDescription="@string/about"
android:src="@drawable/ic_web_white_24dp"/>
<TextView
android:id="@+id/autofill_web_domain_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="@color/white"
android:layout_gravity="center"
android:paddingRight="12dp"
android:paddingEnd="12dp"
android:paddingLeft="12dp"
android:paddingStart="12dp" />
</LinearLayout>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout
android:id="@+id/lock_button"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/lock_button_background"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="-2dp"
android:layout_marginLeft="-2dp"
android:layout_marginBottom="-2dp"
tools:targetApi="lollipop"
android:elevation="4dp"
style="@style/KeepassDXStyle.Special.Button.Background"
android:layout_gravity="bottom|start"
android:contentDescription="@string/menu_lock" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/lock_button_stroke"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="-2dp"
android:layout_marginLeft="-2dp"
android:layout_marginBottom="-2dp"
tools:targetApi="lollipop"
android:elevation="4dp"
style="@style/KeepassDXStyle.Special.Button.Stroke"
android:layout_gravity="bottom|start"
android:contentDescription="@string/menu_lock" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/lock_button_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:paddingBottom="6dp"
android:paddingTop="16dp"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingEnd="12dp"
android:paddingRight="12dp"
tools:targetApi="lollipop"
android:elevation="4dp"
android:src="@drawable/ic_lock_white_24dp"
android:tint="?android:attr/textColorPrimary"
android:layout_gravity="bottom|start"
android:contentDescription="@string/menu_lock" />
</FrameLayout>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container_key_file"
android:layout_marginBottom="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAutofill="noExcludeDescendants"
tools:ignore="UnusedAttribute">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_entry_keyfile"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/keyfile_open_button">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/keyfile_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:hint="@string/entry_keyfile"
android:inputType="textPassword"
android:focusable="false"
android:cursorVisible="false"
android:focusableInTouchMode="false"
android:imeOptions="actionDone"
android:maxLines="1"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/keyfile_open_button"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="12dp"
android:contentDescription="@string/content_description_open_file"
android:focusable="true"
android:background="@drawable/background_item_selection"
android:src="@drawable/ic_folder_white_24dp"
android:tint="?attr/colorAccent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -19,11 +19,6 @@
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_lock"
android:icon="@drawable/ic_lock_white_24dp"
android:title="@string/menu_lock"
android:orderInCategory="81"
app:showAsAction="always" />
<item android:id="@+id/menu_save_database"
android:icon="@drawable/ic_save_white_24dp"
android:title="@string/menu_save_database"

View File

@@ -166,13 +166,11 @@
<string name="menu_open_file_read_and_write">قابل للتعديل</string>
<string name="select_database_file">فتح قاعدة بيانات موجودة</string>
<string name="create_keepass_file">انشاء قاعدة بيانات</string>
<string name="open_recent">قواعد البيانات الاخيرة</string>
<string name="omit_backup_search_title">لا تبحثفي مدخلات النسخ الاحتياطي</string>
<string name="progress_title">قيد العمل…</string>
<string name="read_only_warning">KeePassDX يحتاج صلاحية الكتابة من اجل تعديل قاعدة البيانات.</string>
<string name="encryption_explanation">خوارزمية تشفير جميع البيانات.</string>
<string name="unsupported_db_version">قاعدة بيانات غير مدعومة.</string>
<string name="warning_unmounted">اربط بطاقة الذاكرة لإنشاء او تحميل قاعدة بيانات.</string>
<string name="build_label">بناء %1$s</string>
<string name="encrypted_value_stored">تم حفظ كلمة السر المشفرة</string>
<string name="no_credentials_stored">قاعدة البيانات لا تمتلك كلمة سر.</string>

View File

@@ -107,7 +107,6 @@
<string name="never">Mai</string>
<string name="no_results">Cap resultat de cerca</string>
<string name="no_url_handler">Sense gestor per aquesta url.</string>
<string name="open_recent">Obre base de dades recent :</string>
<string name="omit_backup_search_title">No cerquis entrades a còpia de seguretat ni paperera</string>
<string name="omit_backup_search_summary">Omet els grups \'Còpia de seguretat\' i paperera dels resultats de cerca</string>
<string name="progress_create">Creant nova base de dades&#8230;</string>
@@ -128,7 +127,6 @@
<string name="underline">Subratllat</string>
<string name="unsupported_db_version">Versió de la base de dades no suportada.</string>
<string name="uppercase">Majúscules</string>
<string name="warning_unmounted">La teva tarja SD no està muntada al teu dispositiu. No podràs carregar ni guardar una base de dades.</string>
<string name="version_label">Versió %1$s</string>
<string name="education_unlock_summary">Introdueix una contrasenya i/o un arxiu clau per desbloquejar la base de dades.</string>

View File

@@ -113,7 +113,6 @@
<string name="never">Nikdy</string>
<string name="no_results">Žádné výsledky hledání</string>
<string name="no_url_handler">Pro otevření tohoto URL nainstalujte webový prohlížeč.</string>
<string name="open_recent">Nedávno otevřené databáze</string>
<string name="omit_backup_search_title">Neprohledávat položky v záloze</string>
<string name="omit_backup_search_summary">Vynechat skupiny „Záloha“ a \"Koš\" z výsledků vyhledávání</string>
<string name="progress_create">Vytvářím novou databázi…</string>
@@ -137,7 +136,6 @@
<string name="unsupported_db_version">Nepodporovaná verze databáze.</string>
<string name="uppercase">Velká písmena</string>
<string name="version_label">Verze %1$s</string>
<string name="warning_unmounted">Připojit paměťovou kartu pro založení a otevření databáze.</string>
<string name="education_unlock_summary">Databázi odemknete zadáním hesla a/nebo souboru s klíčem.
\n
\nNezapomeňte si po každé úpravě zazálohovat kopii svého .kdbx souboru na bezpečné místo.</string>
@@ -197,8 +195,8 @@
<string name="sort_last_access_time">Přístup</string>
<string name="warning">Varování</string>
<string name="warning_password_encoding">Nepoužívejte v hesle pro databázový soubor znaky mimo znakovou sadu Latin-1 (nepoužívejte znaky s diakritikou).</string>
<string name="warning_empty_password">Opravdu chcete ponechat databázi nechráněnou (bez hesla)?</string>
<string name="warning_no_encryption_key">Opravdu nechcete používat šifrovací klíč?</string>
<string name="warning_empty_password">Pokračovat bez ochrany odemknutím heslem\?</string>
<string name="warning_no_encryption_key">Pokračovat bez šifrovacího klíče\?</string>
<string name="configure_biometric">Biometrická pobídka je zařízením podporována, ale není nastavena.</string>
<string name="open_biometric_prompt_unlock_database">Otevři biometrickou pobídku k otevření databáze</string>
<string name="encrypted_value_stored">Šifrované heslo uloženo</string>
@@ -231,7 +229,7 @@
<string name="biometric_unlock_enable_summary">Nechá otevřít databázi snímáním biometrického údaje</string>
<string name="biometric_delete_all_key_title">Smazat šifrovací klíče</string>
<string name="biometric_delete_all_key_summary">Smazat všechny šifrovací klíče související s biometrickým rozlišením</string>
<string name="biometric_delete_all_key_warning">Opravdu chcete smazat všechny klíče související s biometrickým rozlišením\?</string>
<string name="biometric_delete_all_key_warning">Smazat všechny šifrovací klíče související s biometrickým rozlišením\?</string>
<string name="unavailable_feature_text">Tuto funkci se nedaří spustit.</string>
<string name="unavailable_feature_version">Verze %1$s vámi používaného systému Android nevyhovuje minimální verzi %2$s.</string>
<string name="unavailable_feature_hardware">Hardware nebyl rozpoznán.</string>
@@ -280,7 +278,7 @@
<string name="education_biometric_summary">Propojte své heslo a otisk prstu pro rychlé odemykání databáze.</string>
<string name="education_entry_edit_title">Upravit položku</string>
<string name="education_entry_edit_summary">Přidejte ke své položce vlastní kolonky. Společná data mohou být sdílena mezi více různými kolonkami.</string>
<string name="education_generate_password_title">Vytvořte k záznamu silné heslo.</string>
<string name="education_generate_password_title">Vytvořit silné heslo</string>
<string name="education_generate_password_summary">Vygenerujte silné heslo pro svou položku, definujte je podle kritérií formuláře, a nezapomeňte na bezpečné heslo.</string>
<string name="education_entry_new_field_title">Přidat vlastní kolonky</string>
<string name="education_entry_new_field_summary">Registrovat další kolonku, zadat hodnotu a volitelně ji ochránit.</string>
@@ -407,7 +405,7 @@
<string name="menu_security_settings">Nastavení zabezpečení</string>
<string name="menu_master_key_settings">Nastavení hlavního klíče</string>
<string name="contains_duplicate_uuid">Databáze obsahuje duplikátní UUID.</string>
<string name="contains_duplicate_uuid_procedure">Prověřením toho dialogu opraví KeePassDX chybu (založením nového UUID pro duplikáty) a bude pokračovat.</string>
<string name="contains_duplicate_uuid_procedure">Opravit chybu založením nového UUID pro duplikáty a pokračovat\?</string>
<string name="database_opened">Databáze otevřena</string>
<string name="clipboard_explanation_summary">Kopírujte pole záznamů pomocí schránky Vašeho zařízení</string>
<string name="advanced_unlock_explanation_summary">K snadnějšímu otevření databáze použijte pokročilé odemknutí</string>
@@ -433,24 +431,24 @@
<string name="menu_save_database">Uložit databázi</string>
<string name="menu_empty_recycle_bin">Vysypat koš</string>
<string name="command_execution">Provádím příkaz…</string>
<string name="warning_permanently_delete_nodes">Jste si jisti, že chcete natrvalo smazat vybrané uzly\?</string>
<string name="warning_permanently_delete_nodes">Natrvalo smazat vybrané uzly\?</string>
<string name="keystore_not_accessible">Úložiště klíčů není řádně inicializováno.</string>
<string name="credential_before_click_biometric_button">Zadejte heslo než kliknete na tlačítko biometriky.</string>
<string name="recycle_bin_group_title">Skupina Koš</string>
<string name="enable_auto_save_database_title">Uložit databázi automaticky</string>
<string name="enable_auto_save_database_summary">Automaticky uloží databázi po důležité akci (pouze v režimu \"Zápis\")</string>
<string name="enable_auto_save_database_summary">Uložit databázi po každé důležité akci (v režimu \"Zápis\")</string>
<string name="entry_attachments">Připojené soubory</string>
<string name="menu_restore_entry_history">Obnovit historii</string>
<string name="menu_delete_entry_history">Smazat historii</string>
<string name="keyboard_auto_go_action_title">Akce auto-klíče</string>
<string name="keyboard_auto_go_action_summary">Automatická akce klíče Jít po stisknutí klíče Pole</string>
<string name="keyboard_auto_go_action_summary">Akce klíče \"Jít\" po stisknutí klíče \"Položka\"</string>
<string name="download_attachment">Stáhnout %1$s</string>
<string name="download_initialization">Zahajuji…</string>
<string name="download_progression">Probíhá: %1$d%</string>
<string name="download_progression">Probíhá: %1$d&#37;</string>
<string name="download_finalization">Dokončuji…</string>
<string name="download_complete">Ukončeno! Klepnout pro otevření souboru.</string>
<string name="hide_expired_entries_title">Skrýt propadlé záznamy</string>
<string name="hide_expired_entries_summary">Propadlé záznamy budou skryty</string>
<string name="hide_expired_entries_summary">Propadlé záznamy jsou skryty</string>
<string name="contact">Kontakt</string>
<string name="contribution">Příspěvky</string>
<string name="feedback">Feedback</string>
@@ -465,7 +463,14 @@
<string name="hide_broken_locations_title">Skrýt špatné odkazy na databáze</string>
<string name="hide_broken_locations_summary">Skrýt špatné odkazy v seznamu nedávných databází</string>
<string name="warning_database_read_only">Udělit právo zápisu pro uložení změn v databázi</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft je &lt;strong&gt;otevřený software&lt;/strong&gt; a &lt;strong&gt;bey reklam&lt;/strong&gt;.
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft je &lt;strong&gt;svobodný software&lt;/strong&gt; a &lt;strong&gt;bey reklam&lt;/strong&gt;.
\nJe poskytován jak je, pod licencí &lt;strong&gt;GPLv3&lt;/strong&gt;, bez jakékoli záruky.</string>
<string name="html_about_contribution">Abychom si &lt;strong&gt;udrželi svoji svobodu&lt;/strong&gt;, &lt;strong&gt;opravili chyby&lt;/strong&gt;,&lt;strong&gt;doplnili funkce&lt;/strong&gt; a &lt;strong&gt;byli vždy aktivní&lt;/strong&gt;, počítáme s Vaším &lt;strong&gt;přispěním&lt;/strong&gt;.</string>
<string name="error_create_database">Nedaří se vytvořit soubor s databází.</string>
<string name="entry_add_attachment">Přidat přílohu</string>
<string name="discard">Zahodit</string>
<string name="discard_changes">Zahodit změny\?</string>
<string name="validate">Ověřit</string>
<string name="education_setup_OTP_summary">Nastavit správu One-Time hesla (HOTP / TOTP) pro založení tokenu požadovaného pro dvoufázové ověření (2FA).</string>
<string name="education_setup_OTP_title">Nastavit OTP</string>
</resources>

View File

@@ -112,7 +112,6 @@
<string name="never">Aldrig</string>
<string name="no_results">Ingen søgeresultater</string>
<string name="no_url_handler">Installer en web-browser til at åbne URL.</string>
<string name="open_recent">Seneste databaser</string>
<string name="omit_backup_search_title">Gennemsøg ikke backup poster</string>
<string name="omit_backup_search_summary">Udelader \"Sikkerhedskopiering\" og \"Papirkurv\" - grupper fra søgeresultater</string>
<string name="progress_create">Opretter ny database…</string>
@@ -135,7 +134,6 @@
<string name="underline">Understregning</string>
<string name="unsupported_db_version">Database-versionen er ikke understøttet.</string>
<string name="uppercase">Store bogstaver</string>
<string name="warning_unmounted">Monter hukommelseskortet for at oprette eller indlæse en database.</string>
<string name="version_label">Version %1$s</string>
<string name="education_unlock_summary">Angiv en adgangskode og/eller en nøglefil til at låse databasen op.
\n
@@ -197,7 +195,7 @@
<string name="warning">Advarsel</string>
<string name="warning_password_encoding">Undgå adgangskodetegn uden for tekstkodningsformatet i databasefilen (ukendte tegn konverteres til samme bogstav).</string>
<string name="warning_empty_password">Bekræft brug af ingen adgangskode til beskyttelse mod oplåsning\?</string>
<string name="warning_no_encryption_key">Bekræft ingen brug af en krypteringsnøgle?</string>
<string name="warning_no_encryption_key">Fortsæt uden krypteringsnøgle\?</string>
<string name="configure_biometric">Biometrisk prompt understøttes, men er ikke konfigureret.</string>
<string name="open_biometric_prompt_unlock_database">Åbn den biometriske prompt for at låse databasen op</string>
<string name="encrypted_value_stored">Krypteret adgangskode er gemt</string>
@@ -230,7 +228,7 @@
<string name="biometric_unlock_enable_summary">Lader dig scanne din biometrisk for at åbne databasen</string>
<string name="biometric_delete_all_key_title">Slet krypteringsnøgler</string>
<string name="biometric_delete_all_key_summary">Slet alle krypteringsnøgler, der er relateret til fingeraftryk</string>
<string name="biometric_delete_all_key_warning">Bekræft sletning af alle nøgler, der er relateret til fingeraftryksgenkendelse\?</string>
<string name="biometric_delete_all_key_warning">Slet alle nøgler, der er relateret til fingeraftryksgenkendelse\?</string>
<string name="unavailable_feature_text">Funktionen kunne ikke startes.</string>
<string name="unavailable_feature_version">Android-version %1$s opfylder ikke minimum versionskrav %2$s.</string>
<string name="unavailable_feature_hardware">Kunne ikke finde den tilsvarende hardware.</string>
@@ -279,7 +277,7 @@
<string name="education_biometric_summary">Link adgangskoden til det scannede fingeraftryk for hurtigt at låse databasen op.</string>
<string name="education_entry_edit_title">Rediger posten</string>
<string name="education_entry_edit_summary">Rediger post med brugerdefinerede felter. Pool data kan refereres mellem forskellige indtastningsfelter.</string>
<string name="education_generate_password_title">Opret en stærk adgangskode til posten.</string>
<string name="education_generate_password_title">Opret en stærk adgangskode</string>
<string name="education_generate_password_summary">Generer en stærk kodeord til at forbinde elementet, definer det i henhold til kriteriet for formularen og glem ikke et sikkert kodeord.</string>
<string name="education_entry_new_field_title">Tilføj brugerdefinerede felter</string>
<string name="education_entry_new_field_summary">Registrer et ekstra felt, tilføj en værdi og beskyt det eventuelt.</string>
@@ -323,7 +321,7 @@
<string name="keyboard_label">Magikeyboard (KeePassDX)</string>
<string name="keyboard_setting_label">Magikeyboard indstillinger</string>
<string name="keyboard_entry_category">Post</string>
<string name="keyboard_entry_timeout_title">Timeout</string>
<string name="keyboard_entry_timeout_title">Udløbstid</string>
<string name="keyboard_notification_entry_title">Meddelelsesinfo</string>
<string name="keyboard_notification_entry_summary">Vis en meddelelse, når en post er til rådighed</string>
<string name="keyboard_notification_entry_content_title_text">Post</string>
@@ -375,7 +373,7 @@
<string name="error_create_database_file">Kan ikke oprette database med denne adgangskode og nøglefil.</string>
<string name="menu_advanced_unlock_settings">Avanceret oplåsning</string>
<string name="biometric_prompt_store_credential_title">Gem biometrisk genkendelse</string>
<string name="biometric_prompt_store_credential_message">ADVARSEL: Brug af biometrisk genkendelse fritager ikke for at kende hovedadgangskode.</string>
<string name="biometric_prompt_store_credential_message">Advarsel: hovedadgangskoden skal stadig huskes, hvis der bruges biometrisk genkendelse.</string>
<string name="biometric_prompt_extract_credential_title">Åbn database med biometrisk genkendelse</string>
<string name="biometric_prompt_extract_credential_message">Uddrag databasens legitimationsoplysninger med biometriske data</string>
<string name="biometric">Biometrisk</string>
@@ -406,7 +404,7 @@
<string name="menu_security_settings">Sikkerhedsindstillinger</string>
<string name="menu_master_key_settings">Indstillinger for hovednøgle</string>
<string name="contains_duplicate_uuid">Databasen indeholder dublerede UUID\'er.</string>
<string name="contains_duplicate_uuid_procedure">Ved at godkende dialogboksen, vil KeePassDX løse problemet (ved at generere nye UUID\'er for dubletter) og fortsætte.</string>
<string name="contains_duplicate_uuid_procedure">Løs problemet ved at generere nye UUID\'er for dubletter til at fortsætte\?</string>
<string name="database_opened">Database åbnet</string>
<string name="clipboard_explanation_summary">Kopier indtastningsfelter ved hjælp af enhedens udklipsholder</string>
<string name="advanced_unlock_explanation_summary">Brug avanceret oplåsning for at gøre det lettere at åbne en database</string>
@@ -432,12 +430,12 @@
<string name="menu_save_database">Gem database</string>
<string name="menu_empty_recycle_bin">Tøm papirkurven</string>
<string name="command_execution">Udfører kommandoen…</string>
<string name="warning_permanently_delete_nodes">Bekræft sletning ad de markerede noder permanent\?</string>
<string name="warning_permanently_delete_nodes">Slet markerede noder permanent\?</string>
<string name="keystore_not_accessible">Nøglelageret er ikke korrekt initialiseret.</string>
<string name="credential_before_click_biometric_button">Skriv adgangskoden, før der klikkes på den biometriske knap.</string>
<string name="recycle_bin_group_title">Papirkurvsgruppe</string>
<string name="enable_auto_save_database_title">Gem automatisk database</string>
<string name="enable_auto_save_database_summary">Gem automatisk databasen efter en vigtig handling (kun i tilstanden \"Modificerbar\")</string>
<string name="enable_auto_save_database_summary">Gem databasen efter hver en vigtig handling (i tilstanden \"Modificerbar\")</string>
<string name="entry_attachments">Vedhæftninger</string>
<string name="menu_restore_entry_history">Gendan historik</string>
<string name="menu_delete_entry_history">Slet historik</string>
@@ -445,11 +443,11 @@
<string name="keyboard_auto_go_action_summary">Handling af Gå-tasten udføres automatisk, efter der er trykket på en Felt nøgle</string>
<string name="download_attachment">Hent %1$s</string>
<string name="download_initialization">Initialiserer…</string>
<string name="download_progression">I gang: %1$d%</string>
<string name="download_progression">I gang: %1$d&#37;</string>
<string name="download_finalization">Færdiggørelse…</string>
<string name="download_complete">Komplet! Tryk for at åbne filen.</string>
<string name="hide_expired_entries_title">Skjul udløbne poster</string>
<string name="hide_expired_entries_summary">Udløbne poster vil blive skjult</string>
<string name="hide_expired_entries_summary">Udløbne poster er skjult</string>
<string name="contact">Kontakt</string>
<string name="contribution">Bidrag</string>
<string name="feedback">Tilbagemelding</string>
@@ -467,4 +465,11 @@
<string name="hide_broken_locations_title">Skjule brudte databaselinks</string>
<string name="hide_broken_locations_summary">Skjul brudte links på listen over seneste databaser</string>
<string name="warning_database_read_only">Giv fil skriveadgang for at gemme databasændringer</string>
<string name="education_setup_OTP_summary">Opsætning af engangsadgangskodestyring (HOTP / TOTP) for at generere et token anmodet om tofaktorautentisering (2FA).</string>
<string name="education_setup_OTP_title">Opsætning af OTP</string>
<string name="error_create_database">Databasefilen kunne ikke oprettes.</string>
<string name="entry_add_attachment">Tilføj vedhæng</string>
<string name="discard">Kassér</string>
<string name="discard_changes">Kasser ændringer\?</string>
<string name="validate">Valider</string>
</resources>

View File

@@ -20,8 +20,11 @@
Translations from BoDEAN
Translations from Matthias Dill
Translations from David Ramiro
--><resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="feedback">Feedback</string>
-->
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="contact">Kontakt</string>
<string name="contribution">Mitwirken</string>
<string name="feedback">Rückmeldung</string>
<string name="homepage">Webseite</string>
<string name="about_description">Android-Implementierung des Passwortmanagers KeePass</string>
<string name="accept">Akzeptieren</string>
@@ -42,12 +45,13 @@
<string name="clipboard_timeout">Zwischenablage-Timeout</string>
<string name="clipboard_timeout_summary">Dauer der Speicherung in der Zwischenablage</string>
<string name="select_to_copy">%1$s in die Zwischenablage kopieren</string>
<string name="retrieving_db_key">Datenbank-Schlüsseldatei erzeugen </string>
<string name="retrieving_db_key">Datenbank-Schlüsseldatei erzeugen…</string>
<string name="database">Datenbank</string>
<string name="decrypting_db">Entschlüsselung der Datenbankinhalte </string>
<string name="decrypting_db">Entschlüsselung der Datenbankinhalte…</string>
<string name="default_checkbox">Als Standard-Datenbank verwenden</string>
<string name="digits">Zahlen</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft. Alle Rechte vorbehalten. Die Nutzung der Software erfolgt auf eigene Verantwortung und ohne jegliche Garantie. Die Applikation ist frei und wird unter den Bedingungen der GNU GPL Version 3 (oder später) verbreitet und lizenziert.</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft ist &lt;strong&gt;quelloffen&lt;/strong&gt; und &lt;strong&gt;ohne Werbung&lt;/strong&gt;.\nDie Nutzung der Software erfolgt auf eigene Verantwortung und ohne jegliche Garantie. Die Applikation wird unter den Bedingungen der &lt;strong&gt;GPLv3&lt;/strong&gt; lizenziert.</string>
<string name="html_about_contribution">Damit wir &lt;strong&gt;unsere Unabhängigkeit erhalten&lt;/strong&gt;, &lt;strong&gt;Fehler korrigieren&lt;/strong&gt;, &lt;strong&gt;Funktionen hinzufügen&lt;/strong&gt; und &lt;strong&gt;weiterhin aktiv bleiben&lt;/strong&gt; können, zählen wir auf Ihren &lt;strong&gt;Beitrag&lt;/strong&gt;.</string>
<string name="select_database_file">Vorhandene Datenbank öffnen</string>
<string name="entry_accessed">Letzter Zugriff</string>
<string name="entry_cancel">Abbrechen</string>
@@ -97,7 +101,7 @@
<string name="length">Länge</string>
<string name="list_size_title">Größe der Listenelemente</string>
<string name="list_size_summary">Schriftgröße der Listenelemente</string>
<string name="loading_database">Datenbank wird geladen </string>
<string name="loading_database">Datenbank wird geladen…</string>
<string name="lowercase">Kleinbuchstaben</string>
<string name="hide_password_title">Passwort verstecken</string>
<string name="hide_password_summary">Passwörter standardmäßig mit (***) maskieren</string>
@@ -118,11 +122,12 @@
<string name="never">Nie</string>
<string name="no_results">Keine Suchergebnisse</string>
<string name="no_url_handler">Bitte einen Webbrowser installieren, um diese URL zu öffnen.</string>
<string name="open_recent">Zuletzt geöffnete Datenbanken</string>
<string name="omit_backup_search_title">Papierkorb/Sicherungen nicht durchsuchen</string>
<string name="omit_backup_search_summary">Die Gruppen „Sicherung“ und „Papierkorb“ werden bei der Suche nicht berücksichtigt</string>
<string name="progress_create">Neue Datenbank anlegen …</string>
<string name="progress_title">Ausführen …</string>
<string name="auto_focus_search_title">Schnellsuche</string>
<string name="auto_focus_search_summary">Beim Öffnen einer Datenbank eine Suche veranlassen</string>
<string name="progress_create">Neue Datenbank anlegen…</string>
<string name="progress_title">Ausführen…</string>
<string name="protection">Sicherheit</string>
<string name="read_only">Schreibgeschützt</string>
<string name="read_only_warning">KeePassDX benötigt Schreibrechte, um etwas an der Datenbank zu ändern.</string>
@@ -131,7 +136,7 @@
<string name="root">Start</string>
<string name="rounds">Schlüsseltransformationen</string>
<string name="rounds_explanation">Zusätzliche Schlüsseltransformationen bieten einen besseren Schutz gegen Wörterbuch- oder Brute-Force-Angriffe. Allerdings dauert dann auch das Laden und Speichern der Datenbank entsprechend länger.</string>
<string name="saving_database">Datenbank wird gespeichert </string>
<string name="saving_database">Datenbank wird gespeichert…</string>
<string name="space">Leerzeichen</string>
<string name="search_label">Suchen</string>
<string name="sort_db">Natürliche Sortierung</string>
@@ -144,7 +149,6 @@
<string name="uppercase">Großbuchstaben</string>
<string name="warning">Warnung</string>
<string name="warning_password_encoding">Passwortzeichen in der Datenbank vermeiden, die kein Text-Encoding-Format besitzen (nicht erkannte Zeichen werden in denselben Buchstaben umgewandelt).</string>
<string name="warning_unmounted">Die Speicher einbinden, um eine Datenbank erstellen oder laden zu können.</string>
<string name="version_label">Version %1$s</string>
<string name="education_unlock_summary">Geben Sie das Passwort und/oder die Schlüsseldatei ein, um Ihre Datenbank zu entsperren.
\n
@@ -175,7 +179,6 @@
<string name="lock_database_screen_off_title">Bildschirmsperre</string>
<string name="lock_database_screen_off_summary">Datenbank sperren, wenn der Bildschirm ausgeschaltet wird</string>
<string name="create_keepass_file">Neue Datenbank erstellen</string>
<string name="style_choose_title">App-Design</string>
<string name="assign_master_key">Hauptschlüssel zuweisen</string>
<string name="path">Pfad</string>
<string name="file_name">Dateiname</string>
@@ -195,7 +198,6 @@
<string name="general">Allgemein</string>
<string name="open_biometric_prompt_store_credential">Biometrische Abfrage öffnen, um Anmeldedaten zu speichern.</string>
<string name="no_credentials_stored">Diese Datenbank hat noch kein Passwort.</string>
<string name="style_choose_summary">App-Design, das in der App genutzt wird</string>
<string name="encryption">Verschlüsselung</string>
<string name="key_derivation_function">Schlüsselableitungsfunktion</string>
<string name="extended_ASCII">Erweiterte ASCII</string>
@@ -266,7 +268,7 @@
<string name="education_biometric_summary">Verknüpft Ihr Passwort mit Ihrer gescannten Biometrie, um Ihre Datenbank schnell zu entsperren.</string>
<string name="education_entry_edit_title">Eintrag bearbeiten</string>
<string name="education_entry_edit_summary">Bearbeiten Sie Ihren Eintrag mit persönlichen Feldern. Persönliche Felder können mit Querverweisen aus anderen Einträgen ergänzt werden.</string>
<string name="education_generate_password_title">Ein starkes Passwort für den Eintrag erstellen.</string>
<string name="education_generate_password_title">Ein starkes Passwort erstellen</string>
<string name="education_generate_password_summary">Erzeugung eines starken Passworts, das mit dem Eintrag verknüpft wird, nach Kriterien, die einfach in einem Formular festgelegt werden. Dabei an die Passwortsicherheit denken.</string>
<string name="education_entry_new_field_title">Benutzerdefinierte Felder hinzufügen</string>
<string name="education_entry_new_field_summary">Tragen Sie ein zusätzliches Feld ein, fügen Sie einen Wert hinzu und schützen Sie es optional.</string>
@@ -281,7 +283,7 @@
<string name="education_sort_summary">Auswählen, wie Einträge und Gruppen sortiert werden.</string>
<string name="education_donation_title">Mitmachen</string>
<string name="education_donation_summary">Mithelfen, um Stabilität und Sicherheit zu verbessern und weitere Funktionen zu ermöglichen.</string>
<string name="html_text_ad_free">Anders als viele andere Passwortmanager ist dieser &lt;strong&gt;werbefrei&lt;/strong&gt;, &lt;strong&gt;quelloffen&lt;/strong&gt; und unter <stark>Copyleft lizenziert</stark>. &lt;strong&gt;Es werden keine persönlichen Daten gesammelt&lt;/strong&gt;, in welcher Form auch immer, egal welche Version (kostenlos oder pro) Sie verwenden.</string>
<string name="html_text_ad_free">Anders als viele andere Passwortmanager ist dieser &lt;strong&gt;werbefrei&lt;/strong&gt;, &lt;strong&gt;quelloffen&lt;/strong&gt; und unter &lt;strong&gt;Copyleft lizenziert&lt;/strong&gt;. Es werden keine persönlichen Daten gesammelt, in welcher Form auch immer, egal welche Version (kostenlos oder pro) Sie verwenden.</string>
<string name="html_text_buy_pro">Mit dem Kauf der Pro-Version erhält man Zugang zu dieser &lt;strong&gt;visuellen Funktion&lt;/strong&gt; und unterstützt insbesondere &lt;strong&gt;die Umsetzung gemeinschaftlicher Projektarbeiten.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Dieser &lt;strong&gt;visuelle Stil&lt;/strong&gt; wurde wegen Ihrer Großzügigkeit freigeschaltet.</string>
<string name="html_text_donation">Um unsere Freiheit zu bewahren und immer aktiv zu bleiben, zählen wir auf Ihren &lt;strong&gt;Beitrag.&lt;/strong&gt;</string>
@@ -297,8 +299,8 @@
<string name="encryption_chacha20">ChaCha20</string>
<string name="kdf_AES">AES</string>
<string name="kdf_Argon2">Argon2</string>
<string name="icon_pack_choose_title">Symbolepaket</string>
<string name="icon_pack_choose_summary">In der App verwendetes Symbolepaket</string>
<string name="icon_pack_choose_title">Symbolpaket</string>
<string name="icon_pack_choose_summary">In der App verwendetes Symbolpaket</string>
<string name="error_move_folder_in_itself">Eine Gruppe kann nicht in sich selbst verschoben werden.</string>
<string name="menu_copy">Kopieren</string>
<string name="menu_move">Verschieben</string>
@@ -344,7 +346,15 @@
<string name="keyboard_key_vibrate_title">Vibrierende Tastendrücke</string>
<string name="keyboard_key_sound_title">Hörbare Tastendrücke</string>
<string name="selection_mode">Auswahlmodus</string>
<string name="do_not_kill_app">Nicht die App beenden …</string>
<string name="remember_database_locations_title">Speicherort der Datenbanken</string>
<string name="remember_database_locations_summary">Speicherort der Datenbanken merken</string>
<string name="remember_keyfile_locations_title">Speicherort der Schlüsseldateien</string>
<string name="remember_keyfile_locations_summary">Speicherort der Schlüssel zu Datenbanken merken</string>
<string name="show_recent_files_title">Zuletzt verwendete Dateien anzeigen</string>
<string name="show_recent_files_summary">Speicherort zuletzt verwendeter Datenbanken anzeigen</string>
<string name="hide_broken_locations_title">Defekte Datenbankverknüpfungen ausblenden</string>
<string name="hide_broken_locations_summary">Nicht funktionierende Verknüpfungen in der Liste der zuletzt verwendeten Datenbanken ausblenden</string>
<string name="do_not_kill_app">Nicht die App beenden…</string>
<string name="lock_database_back_root_summary">Datenbank sperren, wenn auf dem Hauptbildschirm der Zurück-Button gedrückt wird</string>
<string name="clear_clipboard_notification_title">Beim Schließen löschen</string>
<string name="recycle_bin">Papierkorb</string>
@@ -410,7 +420,7 @@
<string name="menu_security_settings">Sicherheits-Einstellungen</string>
<string name="menu_master_key_settings">Hauptschlüssel-Einstellungen</string>
<string name="contains_duplicate_uuid">Die Datenbank enthält UUID-Duplikate.</string>
<string name="contains_duplicate_uuid_procedure">Durch die Validierung dieses Dialogs wird KeePassDX das Problem (durch Erzeugung neuer UUIDs für Duplikate) beheben und weiter ausgeführt.</string>
<string name="contains_duplicate_uuid_procedure">Problem lösen, indem neue UUIDs für Duplikate generiert werden und danach fortfahren\?</string>
<string name="database_opened">Datenbank geöffnet</string>
<string name="clipboard_explanation_summary">Eintragsfelder mithilfe der Zwischenablage des Geräts kopieren</string>
<string name="advanced_unlock_explanation_summary">Erweitertes Entsperren verwenden, um eine Datenbank einfacher zu öffnen.</string>
@@ -435,13 +445,13 @@
<string name="error_save_database">Die Datenbank konnte nicht gespeichert werden.</string>
<string name="menu_save_database">Datenbank speichern</string>
<string name="menu_empty_recycle_bin">Papierkorb leeren</string>
<string name="command_execution">Befehl ausführen </string>
<string name="command_execution">Befehl ausführen…</string>
<string name="warning_permanently_delete_nodes">Sind Sie sicher, dass Sie die ausgewählten Knoten dauerhaft löschen möchten\?</string>
<string name="keystore_not_accessible">Der Schlüsselspeicher ist nicht richtig initialisiert.</string>
<string name="credential_before_click_biometric_button">Geben Sie das Passwort ein, bevor Sie auf den Biometrie-Button klicken.</string>
<string name="recycle_bin_group_title">Papierkorb-Gruppe</string>
<string name="enable_auto_save_database_title">Datenbank automatisch speichern</string>
<string name="enable_auto_save_database_summary">Automatisches Speichern der Datenbank nach einer wichtigen Aktion (nur im Modus \"Bearbeiten\")</string>
<string name="enable_auto_save_database_summary">Automatisches Speichern der Datenbank nach einer wichtigen Aktion (im Modus \"Bearbeiten\")</string>
<string name="entry_attachments">Anhänge</string>
<string name="menu_restore_entry_history">Historie wiederherstellen</string>
<string name="menu_delete_entry_history">Historie löschen</string>
@@ -449,9 +459,28 @@
<string name="keyboard_auto_go_action_summary">Aktion der Go-Taste, die automatisch nach dem Drücken einer Feldtaste ausgeführt wird</string>
<string name="download_attachment">%1$s herunterladen</string>
<string name="download_initialization">Initialisieren…</string>
<string name="download_progression">Fortschritt: %1$d%</string>
<string name="download_finalization">Fertigstellung</string>
<string name="download_progression">Fortschritt: %1$d&#37;</string>
<string name="download_finalization">Fertigstellen</string>
<string name="download_complete">Vollständig! Tippen Sie, um die Datei zu öffnen.</string>
<string name="hide_expired_entries_title">Abgelaufene Einträge ausblenden</string>
<string name="hide_expired_entries_summary">Abgelaufene Einträge werden ausgeblendet</string>
<string name="style_choose_title">App-Design</string>
<string name="style_choose_summary">App-Design, das in der App genutzt wird</string>
<string-array name="list_style_names">
<item>Hell</item>
<item>Dunkel</item>
<item>Schwarz</item>
<item>Klassisch Dunkel</item>
<item>Himmel und Meer</item>
<item>Roter Vulkan</item>
<item>Purple Pro</item>
</string-array>
<string name="warning_database_read_only">Datei Schreibrechte gewähren, um Datenbankänderungen zu speichern</string>
<string name="education_setup_OTP_summary">Einrichten einer Einmal-Passwortverwaltung (HOTP / TOTP), um ein Token zu generieren, das für die Zwei-Faktor-Authentifizierung (2FA) angefordert wird.</string>
<string name="education_setup_OTP_title">Einrichten von OTP</string>
<string name="error_create_database">Es ist nicht möglich, eine Datenbankdatei zu erstellen.</string>
<string name="entry_add_attachment">Anhang hinzufügen</string>
<string name="discard">Verwerfen</string>
<string name="discard_changes">Änderungen verwerfen\?</string>
<string name="validate">Validieren</string>
</resources>

View File

@@ -113,7 +113,6 @@
<string name="never">Ποτέ</string>
<string name="no_results">Δεν βρέθηκαν αποτελέσματα αναζήτησης</string>
<string name="no_url_handler">Εγκαταστήστε ένα πρόγραμμα περιήγησης για να ανοίξετε αυτήν τη διεύθυνση URL.</string>
<string name="open_recent">Πρόσφατες βάσεις δεδομένων</string>
<string name="omit_backup_search_title">Να μην γίνει αναζήτηση μέσα από τις καταχωρήσεις αντιγραφών ασφαλείας</string>
<string name="omit_backup_search_summary">Παράληψη ομάδας \"Αντίγραφο Ασφαλείας\" και \"Κάδος Ανακύκλωσης\" από τα αποτελέσματα αναζήτησης</string>
<string name="progress_create">Δημιουργία νέας βάσης δεδομένων…</string>
@@ -136,7 +135,6 @@
<string name="underline">Υπογράμμιση</string>
<string name="unsupported_db_version">Μη υποστηριζόμενη έκδοση βάσης δεδομένων.</string>
<string name="uppercase">Κεφαλαία</string>
<string name="warning_unmounted">Μοντάρετε την κάρτα μνήμης για να δημιουργήσετε ή να φορτώσετε μια βάση δεδομένων.</string>
<string name="version_label">Έκδοση %1$s</string>
<string name="education_unlock_summary">Καταχωρίστε τον κωδικό πρόσβασης και /ή το αρχείο-κλειδί για να ξεκλειδώσετε τη βάση δεδομένων σας.
\n

View File

@@ -105,7 +105,6 @@
<string name="never">Nunca</string>
<string name="no_results">Sin resultado de búsqueda</string>
<string name="no_url_handler">Instale un navegador web para abrir este URL.</string>
<string name="open_recent">Bases de datos recientes</string>
<string name="omit_backup_search_title">No buscar en las entradas de respaldo</string>
<string name="omit_backup_search_summary">Omite los grupos «Respaldo» y «Papelera de reciclaje» de los resultados de búsqueda</string>
<string name="progress_create">Creando nueva base de datos…</string>
@@ -125,7 +124,6 @@
<string name="underline">Subrayado</string>
<string name="unsupported_db_version">No se admite esta versión de la base de datos.</string>
<string name="uppercase">Mayúsculas</string>
<string name="warning_unmounted">Monte la tarjeta SD para crear o cargar una base de datos.</string>
<string name="version_label">Versión %1$s</string>
<string name="education_unlock_summary">Introduzca una contraseña y/o un archivo de clave para desbloquear su base de datos.</string>
<string-array name="timeout_options">

View File

@@ -115,7 +115,6 @@
<string name="never">Inoiz ez</string>
<string name="no_results">Emaitzarik gabeko bilaketa</string>
<string name="no_url_handler">URL kudatzeko euskarririk ez.</string>
<string name="open_recent">Duela gutxiko datubasea ireki :</string>
<string name="omit_backup_search_title">Ez bilatu segurtasun kopiaren sarreretan</string>
<string name="omit_backup_search_summary">Kendu segurtasun kopien taldea bilaketen emaitzetatik (.kdb fitxategie dagokie bakarrik)</string>
<string name="progress_create">Datubase berria sortzen…</string>
@@ -137,7 +136,6 @@
<string name="underline">Azpimarratu</string>
<string name="unsupported_db_version">Euskarririk gabeko datubase bertsioa.</string>
<string name="uppercase">Maiuskulak</string>
<string name="warning_unmounted">Une honetan zure sd txartela ez dago montatua zure dispositiboan. Ezingo duzu zure datubasea kargatu edo sortu.</string>
<string name="version_label">Bertsioa %1$s</string>
<string name="education_unlock_summary">Sartu pasahitz eta / edo gako fitxategi bat zure datubasea desblokeatzeko.</string>

View File

@@ -114,7 +114,6 @@
<string name="never">Ei koskaan</string>
<string name="no_results">Ei hakutuloksia</string>
<string name="no_url_handler">Tälle URL:lle ei ole käsittelijää.</string>
<string name="open_recent">Avaa viimeisin salasanatietokanta :</string>
<string name="omit_backup_search_title">Älä etsi varmuuskopioista eikä roskakorista</string>
<string name="omit_backup_search_summary">Poista \'Varmuuskopiot\' ja roskakori hakutuloksista</string>
<string name="progress_create">Luodaan uutta tietokantaa&#8230;</string>
@@ -136,7 +135,6 @@
<string name="underline">Alleviivattu</string>
<string name="unsupported_db_version">Ei-tuettu salasanatietokannan versio.</string>
<string name="uppercase">Isot kirjaimet</string>
<string name="warning_unmounted">SD-korttia ei löydy. Et voi ladata tai tallentaa salasanatietokantaa.</string>
<string name="version_label">Versio %1$s</string>
<string name="education_unlock_summary">Syötä salasana ja/tai avaintiedosto avataksesi tietokantasi.</string>

View File

@@ -16,7 +16,8 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--><resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
-->
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="feedback">Commentaires</string>
<string name="homepage">Page daccueil</string>
<string name="about_description">Implémentation Android du gestionnaire de mots de passe KeePass</string>
@@ -49,7 +50,7 @@
<string name="decrypting_db">Déchiffrement du contenu de la base de données…</string>
<string name="default_checkbox">Utiliser comme base de données par défaut</string>
<string name="digits">Chiffres</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft est &lt;strong&gt;libre&lt;/strong&gt; et &lt;strong&gt;sans publicité&lt;/strong&gt;. \nIl est fourni tel quel, sous la licence &lt;strong&gt;GPLv3&lt;/strong&gt;, sans aucune garantie.</string>
<string name="html_about_licence"> Key Derivation Functions </string>
<string name="entry_accessed">Dernier accès</string>
<string name="entry_cancel">Annuler</string>
<string name="entry_notes">Notes</string>
@@ -123,7 +124,6 @@
<string name="no_results">Aucun résultat</string>
<string name="no_url_handler">Installer un navigateur Web pour ouvrir cette URL.</string>
<string name="select_database_file">Ouvrir une base de données existante</string>
<string name="open_recent">Bases de données récentes</string>
<string name="omit_backup_search_title">Ne pas rechercher dans les entrées sauvegardées</string>
<string name="omit_backup_search_summary">Omet les groupes «Sauvegarde» et «Corbeille» des résultats de recherche</string>
<string name="progress_create">Création dune nouvelle base de données…</string>
@@ -162,9 +162,8 @@
<string name="uppercase">Majuscules</string>
<string name="warning">Alerte</string>
<string name="warning_password_encoding">Éviter les caractères en dehors du format de codage de caractères du fichier de base de données (les caractères non reconnus sont convertis en une même lettre).</string>
<string name="warning_unmounted">Monter la carte mémoire pour créer ou charger une base de données.</string>
<string name="warning_empty_password">Ne voulez-vous vraiment aucune protection de déverrouillage par mot de passe\?</string>
<string name="warning_no_encryption_key">Êtes-vous sûr de ne vouloir utiliser aucune clé de chiffrement\?</string>
<string name="warning_empty_password">Continuer sans protection de déverrouillage par mot de passe\?</string>
<string name="warning_no_encryption_key">Continuer sans clé de chiffrement\?</string>
<string name="version_label">Version %1$s</string>
<string name="configure_biometric">La reconnaissance biométrique est prise en charge mais nest pas configurée.</string>
<string name="open_biometric_prompt_unlock_database">Ouvrir linvite biométrique pour déverrouiller la base de données</string>
@@ -198,7 +197,7 @@
<string name="biometric_unlock_enable_summary">Permet de numériser votre empreinte biométrique pour ouvrir la base de données</string>
<string name="biometric_delete_all_key_title">Supprimer les clés de chiffrement</string>
<string name="biometric_delete_all_key_summary">Supprime toutes les clés de chiffrement liées à la reconnaissance biométrique</string>
<string name="biometric_delete_all_key_warning">Êtes-vous sûr de vouloir supprimer toutes les clés liées à la reconnaissance biométrique\?</string>
<string name="biometric_delete_all_key_warning">Supprimer toutes les clés de chiffrement liées à la reconnaissance biométrique\?</string>
<string name="unavailable_feature_text">Impossible de démarrer cette fonctionnalité.</string>
<string name="unavailable_feature_version">Votre version dAndroid %1$s est inférieure à la version minimale %2$s requise.</string>
<string name="unavailable_feature_hardware">Impossible de trouver le matériel correspondant.</string>
@@ -243,7 +242,7 @@
<string name="education_biometric_summary">Associe votre mot de passe à votre empreinte biométrique numérisée pour déverrouiller rapidement votre base de données.</string>
<string name="education_entry_edit_title">Modifier lentrée</string>
<string name="education_entry_edit_summary">Modifie votre entrée avec des champs personnalisés. La collection des données peut être référencée entre différents champs de lentrée.</string>
<string name="education_generate_password_title">Créer un mot de passe fort pour votre entrée.</string>
<string name="education_generate_password_title">Créer un mot de passe fort</string>
<string name="education_generate_password_summary">Générez un mot de passe fort à associer avec votre entrée, définissez-le facilement en fonction des critères du formulaire et noubliez pas de sécuriser votre mot de passe.</string>
<string name="education_entry_new_field_title">Ajoutez des champs personnalisés</string>
<string name="education_entry_new_field_summary">Enregistrez un champ additionnel, ajoutez une valeur et facultativement le protéger.</string>
@@ -416,7 +415,7 @@
<string name="menu_security_settings">Paramètres de sécurité</string>
<string name="menu_master_key_settings">Paramètres de la clé maîtresse</string>
<string name="contains_duplicate_uuid">La base de données contient des doublons dUUID.</string>
<string name="contains_duplicate_uuid_procedure">En validant cette boîte de dialogue, KeePassDX corrigera le problème (en générant de nouveaux UUID pour les doublons) et continuera.</string>
<string name="contains_duplicate_uuid_procedure">Résoudre le problème en générant de nouveaux UUID pour les doublons et continuer\?</string>
<string name="database_opened">Base de données ouverte</string>
<string name="clipboard_explanation_summary">Copie les champs dune entrée à laide du presse-papier de votre appareil</string>
<string name="advanced_unlock_explanation_summary">Utilise le déverrouillage avancé pour ouvrir plus facilement une base de données</string>
@@ -442,24 +441,24 @@
<string name="menu_save_database">Enregistrer la base de données</string>
<string name="menu_empty_recycle_bin">Vider la corbeille</string>
<string name="command_execution">Exécution de la commande…</string>
<string name="warning_permanently_delete_nodes">Êtes-vous sûr de vouloir supprimer définitivement les nœuds sélectionnés\?</string>
<string name="warning_permanently_delete_nodes">Supprimer définitivement les nœuds sélectionnés\?</string>
<string name="keystore_not_accessible">Le magasin de clés nest pas correctement initialisé.</string>
<string name="credential_before_click_biometric_button">Saisissez le mot de passe avant de cliquer sur le bouton biométrique.</string>
<string name="recycle_bin_group_title">Groupe de la corbeille</string>
<string name="enable_auto_save_database_title">Enregistrement automatique de la base de données</string>
<string name="enable_auto_save_database_summary">Enregistre automatiquement la base de données après une action importante (uniquement en mode «Modifiable»)</string>
<string name="enable_auto_save_database_summary">Enregistre la base de données après chaque action importante (en mode « Modifiable »)</string>
<string name="entry_attachments">Attachements</string>
<string name="menu_restore_entry_history">Restaurer l\'historique</string>
<string name="menu_delete_entry_history">Effacer l\'historique</string>
<string name="keyboard_auto_go_action_title">Action de touche auto</string>
<string name="keyboard_auto_go_action_summary">Action de la touche Go effectuée automatiquement après avoir appuyé sur une touche de champ</string>
<string name="keyboard_auto_go_action_summary">Action de la touche « Go » après avoir appuyé sur une touche « Champ »</string>
<string name="download_attachment">Téléchargement %1$s</string>
<string name="download_initialization">Initialisation…</string>
<string name="download_progression">En cours : %1$d%</string>
<string name="download_progression">En cours : %1$d&#37;</string>
<string name="download_finalization">Finalisation…</string>
<string name="download_complete">Terminé ! Appuyer pour ouvrir le fichier.</string>
<string name="hide_expired_entries_title">Masquer les entrées expirées</string>
<string name="hide_expired_entries_summary">Les entrées expirées seront masquées</string>
<string name="hide_expired_entries_summary">Les entrées expirées sont cachées</string>
<string name="contact">Contact</string>
<string name="contribution">Contribution</string>
<string name="html_about_contribution">Afin de &lt;strong&gt;garder notre liberté&lt;/strong&gt;, &lt;strong&gt;corriger les bugs&lt;/strong&gt;, &lt;strong&gt;ajouter des fonctionnalités&lt;/strong&gt; et &lt;strong&gt;être toujours actif&lt;/strong&gt;, nous comptons sur votre &lt;strong&gt;contribution&lt;/strong&gt;.</string>
@@ -474,4 +473,11 @@
<string name="hide_broken_locations_title">Masquer les liens rompus de base de données</string>
<string name="hide_broken_locations_summary">Masquer les liens rompus dans la liste des bases de données récentes</string>
<string name="warning_database_read_only">Accorder un accès en écriture au fichier pour enregistrer les modifications de la base de données</string>
<string name="education_setup_OTP_summary">Définir le mot de passe à usage unique (temporel ou évènementiel) pour générer un jeton demandé par lauthentification à deux facteurs (A2F).</string>
<string name="education_setup_OTP_title">Définir lOTP</string>
<string name="error_create_database">Impossible de créer le fichier de base de données.</string>
<string name="entry_add_attachment">Ajouter une pièce jointe</string>
<string name="discard">Abandonner</string>
<string name="discard_changes">Abandonner les modifications\?</string>
<string name="validate">Valider</string>
</resources>

View File

@@ -132,7 +132,6 @@
<string name="no_url_handler">Instalirajte web preglednik da bi ste otvorili ovaj URL.</string>
<string name="select_database_file">Otvori postojeću bazu podataka</string>
<string name="create_keepass_file">Kreiraj novu bazu podataka</string>
<string name="open_recent">Nedavne baze podataka</string>
<string name="omit_backup_search_title">Ne pretražuj kopije unosa</string>
<string name="progress_create">Kreiranje nove baze podataka…</string>
<string name="protection">Zaštita</string>

View File

@@ -114,7 +114,6 @@
<string name="never">Soha</string>
<string name="no_results">Nincs találat</string>
<string name="no_url_handler">Telepítsen egy webböngészőt az URL megnyitásához.</string>
<string name="open_recent">Korábbi adatbázisok</string>
<string name="omit_backup_search_title">Ne keressen a biztonsági mentésekben</string>
<string name="omit_backup_search_summary">A „Biztonsági mentés” csoport kihagyása a keresésből (csak a .kdb fájlokra érvényes)</string>
<string name="progress_create">Új adatbázis létrehozása…</string>
@@ -140,7 +139,6 @@
<string name="uppercase">Nagybetűs</string>
<string name="warning">Figyelmeztetés</string>
<string name="warning_password_encoding">Kerülje a Latin-1 karakterkészlettől eltérő jelszókaraktereket a .kbd fájlokban, mert ugyanarra a betűre lesznek átalakítva.</string>
<string name="warning_unmounted">Csatolja az SD kártyát, hogy adatbázist hozzon létre vagy töltsön be.</string>
<string name="version_label">Verzió: %1$s</string>
<string name="configure_biometric">Az ujjlenyomat-leolvasás támogatott, de nincs beállítva.</string>
<string name="open_biometric_prompt_unlock_database">Ujjlenyomat-leolvasás</string>

View File

@@ -44,7 +44,7 @@
<string name="decrypting_db">Decodifica contenuto database…</string>
<string name="default_checkbox">Usa come database predefinito</string>
<string name="digits">Numeri</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft è un programma &lt;strong&gt;open source&lt;/strong&gt; e &lt;strong&gt;senza pubblicità&lt;/strong&gt;.
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft è un programma &lt;strong&gt;libero&lt;/strong&gt; e &lt;strong&gt;senza pubblicità&lt;/strong&gt;.
\nViene distribuito sotto le condizioni della licenza &lt;strong&gt;GPL versione 3&lt;/strong&gt; o successiva, senza alcuna garanzia.</string>
<string name="entry_notes">Note</string>
<string name="select_database_file">Apri un database esistente</string>
@@ -78,13 +78,13 @@
<string name="file_not_found_content">File non trovato. Prova a riaprirlo dal tuo gestore di file.</string>
<string name="file_browser">Gestore file</string>
<string name="generate_password">Genera password</string>
<string name="hint_conf_pass">conferma password</string>
<string name="hint_generated_password">password generata</string>
<string name="hint_conf_pass">Conferma password</string>
<string name="hint_generated_password">Password generata</string>
<string name="hint_group_name">Nome gruppo</string>
<string name="hint_keyfile">File chiave</string>
<string name="hint_length">lunghezza</string>
<string name="hint_length">Lunghezza</string>
<string name="password">Password</string>
<string name="hint_pass">password</string>
<string name="hint_pass">Password</string>
<string name="install_from_play_store">Installa dal Play Store</string>
<string name="install_from_f_droid">Installa dal F-Droid</string>
<string name="invalid_credentials">Non è possibile leggere le credenziali. Se questo dovesse riaccadere, il file del databese potrebbe essere corrotto.</string>
@@ -115,7 +115,6 @@
<string name="never">Mai</string>
<string name="no_results">Nessun risultato di ricerca</string>
<string name="no_url_handler">Installa un browser web per aprire questo URL.</string>
<string name="open_recent">Database recenti</string>
<string name="omit_backup_search_title">Non cercare nelle voci di backup</string>
<string name="omit_backup_search_summary">Ometti i gruppi \"Backup\" e \"Cestino\" dai risultati di ricerca</string>
<string name="progress_create">Creazione nuovo database…</string>
@@ -139,12 +138,11 @@
<string name="uppercase">Maiuscole</string>
<string name="warning">Attenzione</string>
<string name="warning_password_encoding">Evita password con caratteri al di fuori del formato di codifica del testo nel file di database (i caratteri non riconosciuti vengono convertiti nella stessa lettera).</string>
<string name="warning_unmounted">Monta la scheda di memoria per poter creare o caricare un database.</string>
<string name="version_label">Versione %1$s</string>
<string name="configure_biometric">La scansione di impronte è supportata ma non impostata.</string>
<string name="open_biometric_prompt_unlock_database">Scansione impronte</string>
<string name="encrypted_value_stored">Password criptata salvata</string>
<string name="biometric_invalid_key">Lettura dell\'impronta fallita. Ripristina la tua password.</string>
<string name="biometric_invalid_key">Impossibile leggere la chiave biometrica. Eliminala e ripeti la procedura di riconoscimento.</string>
<string name="biometric_scanning_error">Problema impronta: %1$s</string>
<string name="open_biometric_prompt_store_credential">Usa l\'impronta per salvare questa password</string>
<string name="no_credentials_stored">Questo database non ha ancora alcuna password.</string>
@@ -200,8 +198,8 @@
<string name="sort_creation_time">Creazione</string>
<string name="sort_last_modify_time">Modifica</string>
<string name="sort_last_access_time">Accesso</string>
<string name="warning_empty_password">Vuoi veramente che non ci sia una password di sblocco\?</string>
<string name="warning_no_encryption_key">Sei sicuro di non volere usare una chiave di cifratura?</string>
<string name="warning_empty_password">Continuare senza aver impostato una password di sblocco \?</string>
<string name="warning_no_encryption_key">Continuare senza una chiave di cifratura\?</string>
<string name="biometric_not_recognized">Impronta non riconosciuta</string>
<string name="database_history">Cronologia</string>
<string name="menu_appearance_settings">Aspetto</string>
@@ -223,10 +221,10 @@
<string name="lock_database_screen_off_summary">Blocca il database quando lo schermo è spento</string>
<string name="advanced_unlock">Impronta digitale</string>
<string name="biometric_unlock_enable_title">Scansione di impronte</string>
<string name="biometric_unlock_enable_summary">Consente la scansione di impronte per aprire il database</string>
<string name="biometric_unlock_enable_summary">Consente la scansione biometrica per aprire il database</string>
<string name="biometric_delete_all_key_title">Elimina chiavi di cifratura</string>
<string name="biometric_delete_all_key_summary">Elimina tutte le chiavi di cifratura relative al riconoscimento dell\'impronta</string>
<string name="biometric_delete_all_key_warning">Sei sicuro di volere eliminare tutte le chiavi relative alle impronte?</string>
<string name="biometric_delete_all_key_warning">Eliminare tutte le chiavi di cifrature associate al riconoscimento biometrico \?</string>
<string name="unavailable_feature_text">Impossibile avviare questa funzione.</string>
<string name="unavailable_feature_version">La tua versione di Android %1$s non è la minima %2$s richiesta.</string>
<string name="unavailable_feature_hardware">L\'hardware relativo non è stato trovato.</string>
@@ -236,7 +234,7 @@
<string name="create_keepass_file">Crea un nuovo database</string>
<string name="full_file_path_enable_title">Percorso file</string>
<string name="full_file_path_enable_summary">Visualizza il percorso file completo</string>
<string name="recycle_bin_title">Usa il cestino</string>
<string name="recycle_bin_title">Uso del Cestino</string>
<string name="recycle_bin_summary">Sposta i gruppi e le voci nel gruppo \"Cestino\" prima di eliminarlo</string>
<string name="monospace_font_fields_enable_title">Carattere campi</string>
<string name="monospace_font_fields_enable_summary">Cambia il carattere usato nei campi per una migliore visibilità</string>
@@ -405,6 +403,51 @@
<string name="menu_save_database">Salva il database</string>
<string name="menu_empty_recycle_bin">Svuota il cestino</string>
<string name="command_execution">Esecuzione del comando…</string>
<string name="warning_permanently_delete_nodes">Sei sicuro di voler eliminare definitivamente i nodi selezionati\?</string>
<string name="warning_permanently_delete_nodes">Vuoi eliminare definitivamente i nodi selezionati\?</string>
<string name="entry_attachments">Allegati</string>
<string name="auto_focus_search_summary">Richiedi una ricerca quando un database viene aperto</string>
<string name="auto_focus_search_title">Ricerca rapida</string>
<string name="menu_delete_entry_history">Cancella cronologia</string>
<string name="menu_restore_entry_history">Ripristina cronologia</string>
<string name="html_about_contribution">Per poter &lt;strong&gt;mantenere la nostra libertà&lt;/strong&gt;, &lt;strong&gt;risolvere bug&lt;/strong&gt;, &lt;strong&gt;aggiungere funzionalità&lt;/strong&gt; ed &lt;strong&gt;essere sempre attivi&lt;/strong&gt;, facciamo affidamento sul tuo &lt;strong&gt;contributo&lt;/strong&gt;.</string>
<string name="contact">Contatto</string>
<string name="biometric_prompt_extract_credential_title">Apri il database con il riconoscimento biometrico</string>
<string name="biometric_prompt_store_credential_title">Salva il riconoscimento biometrico</string>
<string name="keystore_not_accessible">Il keystore non è inizializzato correttamente.</string>
<string name="menu_master_key_settings">Impostazioni della chiave principale</string>
<string name="master_key">Chiave principale</string>
<string name="contribution">Contribuisci</string>
<string name="biometric_prompt_store_credential_message">Attenzione: Devi comunque ricordarti la password principale anche se usi il riconoscimento biometrico.</string>
<string name="warning_database_read_only">Garantisci il permesso di scrittura per salvare i cambiamenti del database</string>
<string name="hide_broken_locations_summary">Nascondi link corrotti nella lista dei database recenti</string>
<string name="hide_broken_locations_title">Nascondi i link di database corrotti</string>
<string name="show_recent_files_summary">Mostra le posizioni dei database recenti</string>
<string name="show_recent_files_title">Mostra file recenti</string>
<string name="remember_keyfile_locations_title">Salva la posizione dei keyfile</string>
<string name="remember_database_locations_summary">Ricorda la posizione dei database</string>
<string name="remember_database_locations_title">Salva posizione dei database</string>
<string name="contains_duplicate_uuid_procedure">Per continuare, risolvi il problema generando nuovi UUIDs per i duplicati \?</string>
<string name="error_create_database">Impossibile creare il file del database.</string>
<string name="entry_add_attachment">Aggiungi allegato</string>
<string name="discard">Scarta</string>
<string name="discard_changes">Scartare i cambiamenti\?</string>
<string name="validate">Convalida</string>
<string name="max_history_size_title">Dimensione massima</string>
<string name="max_history_items_title">Numero massimo</string>
<string name="biometric_auto_open_prompt_title">Apri automaticamente prompt biometrico</string>
<string name="max_history_size_summary">Limita la dimensione (in byte) della cronologia per voce</string>
<string name="max_history_items_summary">Limita il numero di elementi della cronologia per voce</string>
<string name="recycle_bin_group_title">Gruppo cestino</string>
<string name="database_data_compression_summary">La compressione dei dati riduce le dimensioni del database.</string>
<string name="database_data_compression_title">Compressione dati</string>
<string name="biometric_auto_open_prompt_summary">Apri automaticamente il prompt biometrico quando viene definita una chiave biometrica per un database</string>
<string name="advanced_unlock_explanation_summary">Utilizza lo sblocco avanzato per aprire il database più facilmente</string>
<string name="clipboard_explanation_summary">Copia i campi di immissione utilizzando gli appunti del tuo dispositivo</string>
<string name="database_opened">Database aperto</string>
<string name="biometric">Biometrico</string>
<string name="credential_before_click_biometric_button">Digitare la password prima di fare clic sul pulsante biometrico.</string>
<string name="biometric_prompt_extract_credential_message">Estrai le credenziali del database con dati biometrici</string>
<string name="settings_database_force_changing_master_key_title">Forza rinnovo</string>
<string name="settings_database_recommend_changing_master_key_summary">Consigliato cambiare la chiave principale (giorni)</string>
<string name="settings_database_recommend_changing_master_key_title">Rinnovo raccomandato</string>
</resources>

View File

@@ -111,7 +111,6 @@
<string name="never">אף פעם</string>
<string name="no_results">אין תוצאות חיפוש</string>
<string name="no_url_handler">אין מטפל לכתובת url זו.</string>
<string name="open_recent">פתח מסד נתונים אחרון :</string>
<string name="omit_backup_search_title">אל תחפש ערכי גיבוי</string>
<string name="omit_backup_search_summary">הורד את קבוצת \"גיבוי\" מתוצאות חיפוש (תואם רק לקבצי kdb)</string>
<string name="progress_create">צור מסד נתונים חדש…</string>
@@ -130,7 +129,6 @@
<string name="underline">קו תחתון</string>
<string name="unsupported_db_version">גרסת מסד נתונים לא נתמכת.</string>
<string name="uppercase">רישית</string>
<string name="warning_unmounted">כרטיס ה-SD במצב לקריאה בלבד. אתה לא תוכל לשמור או ליצור במסד הנתונים.</string>
<string name="version_label">גרסה %1$s</string>
<string name="education_unlock_summary">הזן סיסמה ו/או קובץ מפתח כדי לפתוח את מסד הנתונים.</string>
<string-array name="timeout_options">

View File

@@ -103,7 +103,6 @@
<string name="never">期限なし</string>
<string name="no_results">検索結果に該当するものはありません。</string>
<string name="no_url_handler">このURLを処理できません。</string>
<string name="open_recent">以前使用したデータベースを開く:</string>
<string name="omit_backup_search_title">検索対象から除外</string>
<string name="omit_backup_search_summary">\"バックアップ\"と\"ごみ箱\"を検索対象から除外します</string>
<string name="progress_create">データベースファイルを作成中…</string>
@@ -123,7 +122,6 @@
<string name="underline">アンダーライン (_)</string>
<string name="unsupported_db_version">このバージョンのデータベースはサポートされていません。</string>
<string name="uppercase">英数大文字</string>
<string name="warning_unmounted">SDカードがマウントされていません。データベースの読込や作成ができません。</string>
<string name="version_label">バージョン %1$s</string>
<string name="education_unlock_summary">データベースに設定したパスワードを入力するかキーファイルを選択してください。</string>
<string-array name="timeout_options">

View File

@@ -137,7 +137,6 @@
<string name="no_url_handler">이 URL을 열기 위해 웹 브라우저를 설치하십시오.</string>
<string name="select_database_file">가지고 있는 데이터베이스 열기</string>
<string name="create_keepass_file">새 데이터베이스 생성</string>
<string name="open_recent">최근 데이터베이스</string>
<string name="omit_backup_search_title">백업 항목 검색하지 않기</string>
<string name="progress_create">새 데이터베이스 생성 중…</string>
<string name="progress_title">작업 중…</string>

View File

@@ -86,7 +86,6 @@
<string name="lowercase">Mažosios raidės</string>
<string name="minus">Minusas</string>
<string name="underline">Pabraukimas</string>
<string name="open_recent">Atidaryti naujausią duomenų bazę </string>
<string name="default_checkbox">Naudoti šią duomenų bazę kaip numatytąją</string>
<string name="hide_password_summary">Slėpti slaptažodžius pagal nutylėjimą</string>
<string name="invalid_algorithm">Neteisingas algoritmas.</string>

View File

@@ -94,7 +94,6 @@
<string name="never">Nekad</string>
<string name="no_results">Nav meklēšanas rezultātu</string>
<string name="no_url_handler">Neizdevās atvērt saiti.</string>
<string name="open_recent">Atvērt pēdējo datu bāzi :</string>
<string name="omit_backup_search_title">Nemeklēt kopijās un atkritnē</string>
<string name="omit_backup_search_summary">Izlaist kopijas un atkritni no meklēšanas rezultātiem</string>
<string name="progress_create">Izveido jaunu datu bāzi…</string>
@@ -116,7 +115,6 @@
<string name="underline">Pasvītrojums</string>
<string name="unsupported_db_version">Neatbalstīta datu bāzes versija.</string>
<string name="uppercase">Lielie burti</string>
<string name="warning_unmounted">Nav SD kartes. Darbības ar datu bāzi nav iespējamas.</string>
<string name="version_label">Versija %1$s</string>
<string name="education_unlock_summary">Ievadiet paroli/atslēgas failu, lai atbloķētu savu datu bāzi.</string>

View File

@@ -16,7 +16,8 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--><resources>
-->
<resources>
<string name="feedback">Tilbakemelding</string>
<string name="homepage">Hjemmeside</string>
<string name="about_description">Android-implementasjon av KeePass-passordsbehandleren</string>
@@ -48,7 +49,8 @@
<string name="decrypting_db">Dekrypterer databaseinnhold…</string>
<string name="default_checkbox">Bruk dette som forvalgt database</string>
<string name="digits">Siffer</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft kommer uten noen form for garanti. Dette er fri programvare, og du er velkommen til å redistribuere det i henhold til vilkårene i GPL versjon 3 eller senere.</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft er &lt;strong&gt;fri programvare&lt;/strong&gt;, og &lt;strong&gt;reklamefritt&lt;/strong&gt;.
\nDet tilbys som det er, i hendhold til &lt;strong&gt;GPL versjon 3 eller senere&lt;/strong&gt;, uten noen garantier.</string>
<string name="entry_accessed">Brukt</string>
<string name="entry_cancel">Avbryt</string>
<string name="entry_notes">Kommentarer</string>
@@ -135,7 +137,6 @@
<string name="no_results">Ingen søkeresultater</string>
<string name="no_url_handler">Kan ikke håndtere denne nettadressen.</string>
<string name="select_database_file">Velg en eksisterende database</string>
<string name="open_recent">Nylige databaser</string>
<string name="omit_backup_search_title">Ikke søk gjennom sikkerhetskopioppføringer</string>
<string name="omit_backup_search_summary">Utelat \"Sikkerhetskopi\"-gruppen fra søkeresultater (har kunn innvirkning på .kdb-filer)</string>
<string name="progress_create">Oppretter ny database…</string>
@@ -174,7 +175,6 @@
<string name="uppercase">Store bokstaver</string>
<string name="warning">Advarsel</string>
<string name="warning_password_encoding">Unngå passordtegn utenfor tekstkodingsformat i databasefil (ukjente tegn blir konvertert til samme bokstav).</string>
<string name="warning_unmounted">SD-kortet ditt er ikke montert på enheten din. Du vil ikke kunne laste inne eller opprette din database.</string>
<string name="warning_empty_password">Ønsker du virkelig å bruke en tom streng som ditt passord?</string>
<string name="warning_no_encryption_key">Er du sikker på at du ønsker å bruke en krypteringsnøkkel?</string>
<string name="version_label">Versjon %1$s</string>
@@ -382,8 +382,8 @@
<string name="error_disallow_no_credentials">Minst én identitetsdetalj må angis.</string>
<string name="error_copy_group_here">Du kan ikke kopiere en gruppe hit.</string>
<string name="error_otp_secret_key">Hemmelig nøkkel må være i Base32-format.</string>
<string name="error_otp_digits">"Symbolet må inneholde %1$d til %2$d siffer."</string>
<string name="invalid_db_same_uuid">%1$d med samme UUID %2$s finnes allerede.</string>
<string name="error_otp_digits">Symbolet må inneholde %1$d til %2$d siffer.</string>
<string name="invalid_db_same_uuid">%1$s med samme UUID %2$s finnes allerede.</string>
<string name="creating_database">Oppretter database…</string>
<string name="menu_security_settings">Sikkerhetsinnstillinger</string>
<string name="menu_master_key_settings">Hovednøkkelinnstillinger</string>
@@ -408,4 +408,8 @@
<string name="download_finalization">Fullfører…</string>
<string name="download_complete">Fullført. Trykk for å åpne filen.</string>
<string name="hide_expired_entries_title">Skjul utløpte oppføringer</string>
<string name="auto_focus_search_title">Hurtigsøk</string>
<string name="entry_add_attachment">Legg til vedlegg</string>
<string name="contribution">Bidrag</string>
<string name="contact">Kontakt</string>
</resources>

View File

@@ -105,7 +105,6 @@
<string name="never">Nooit</string>
<string name="no_results">Geen zoekresultaten</string>
<string name="no_url_handler">Installeer een webbrowser om deze URL te openen.</string>
<string name="open_recent">Recente databanken</string>
<string name="omit_backup_search_title">Back-upitems niet doorzoeken</string>
<string name="omit_backup_search_summary">Hiermee worden groepen \"Back-up\" en \"Prullenbak\" uit de zoekresultaten weggelaten</string>
<string name="progress_create">Bezig met creëren van nieuwe databank…</string>
@@ -125,7 +124,6 @@
<string name="underline">Onderstrepen</string>
<string name="unsupported_db_version">Niet-ondersteunde databankversie.</string>
<string name="uppercase">Hoofdletters</string>
<string name="warning_unmounted">Koppel de SD-kaart aan om een databank te creëren of laden.</string>
<string name="version_label">Versie %1$s</string>
<string name="education_unlock_summary">Geef het wachtwoord en/of sleutelbestand op om je databank te ontgrendelen.
\n
@@ -278,7 +276,7 @@
<string name="education_new_node_summary">Voeg items toe om je digitale identiteiten te beheren.
\n
\nVoeg groepen toe (groepen zijn gelijk aan mappen) om items in je databank te organiseren.</string>
<string name="education_search_title">"Doorzoek al je items"</string>
<string name="education_search_title">Doorzoek al je items</string>
<string name="education_search_summary">Doorzoek items op titel, gebruikersnaam of andere velden om wachtwoorden te vinden.</string>
<string name="education_biometric_title">Ontgrendel de databank met je vingerafdruk</string>
<string name="education_biometric_summary">Koppel je wachtwoord en vingerafdruk om de databank snel te ontgrendelen.</string>

View File

@@ -104,7 +104,6 @@
<string name="never">Aldri</string>
<string name="no_results">Ingen søkjeresultat</string>
<string name="no_url_handler">Ingen behandlar for denne adressa.</string>
<string name="open_recent">Opna nyleg brukt database :</string>
<string name="omit_backup_search_title">Søk ikkje i kopipostane eller søppelbøtta</string>
<string name="omit_backup_search_summary">Søkjeresultatet inneheld ikkje oppføringar frå \'Backup\' eller søppelbøtta</string>
<string name="progress_create">Lager ny database …</string>
@@ -124,7 +123,6 @@
<string name="underline">Understreking</string>
<string name="unsupported_db_version">Kan ikkje bruka databaseutgåva.</string>
<string name="uppercase">Store bokstavar</string>
<string name="warning_unmounted">SD-kortet er ikkje montert i eininga di. Du kan verken henta eller laga databasen din.</string>
<string name="version_label">Utgåve %1$s</string>
<string name="education_unlock_summary">Skriv inn passordet og/eller nøkkelfil for å låsa opp databasen.</string>

View File

@@ -102,7 +102,6 @@
<string name="never">Nigdy</string>
<string name="no_results">Brak wyników wyszukiwania</string>
<string name="no_url_handler">Zainstaluj przeglądarkę internetową, aby otworzyć ten adres URL.</string>
<string name="open_recent">Ostatnio używana baza danych</string>
<string name="omit_backup_search_title">Nie wyszukuj wpisów kopii zapasowej</string>
<string name="omit_backup_search_summary">Pomija grupy \"Kopia zapasowa\" i \"Kosz\" z wyników wyszukiwania</string>
<string name="progress_create">Tworzenie nowej bazy danych…</string>
@@ -122,7 +121,6 @@
<string name="underline">Podkreślenie</string>
<string name="unsupported_db_version">Nieobsługiwana wersja bazy danych.</string>
<string name="uppercase">Wielkie litery</string>
<string name="warning_unmounted">Zainstaluj kartę pamięci, aby utworzyć lub załadować bazę danych.</string>
<string name="education_unlock_summary">prowadź hasło i/lub plik klucza, aby odblokować bazę danych.
\n
\nUtwórz kopię zapasową pliku bazy danych w bezpiecznym miejscu po każdej zmianie.</string>
@@ -152,8 +150,9 @@
<string name="clipboard_error">Niektóre urządzenia nie pozwalają aplikacjom korzystać ze schowka.</string>
<string name="clipboard_error_clear">Nie można wyczyścić schowka</string>
<string name="clipboard_swipe_clean">Przesuń, by wyczyścić schowek</string>
<string name="html_about_licence">KeePassDX © %1 $d Kunzisoft jest &lt;strong&gt;open source&lt;/strong&gt; i &lt;strong&gt;bez reklam&lt;/strong&gt;.
<string name="html_about_licence">KeePassDX © %1 $d Kunzisoft jest &lt;strong&gt;wolnym programem&lt;/strong&gt; i &lt;strong&gt;bez reklam&lt;/strong&gt;.
\nJest on dostarczany w stanie, zgodnie z licencją &lt;strong&gt;GPLv3&lt;/strong&gt; bez żadnych gwarancji.</string>
>>>>>>> translations
<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_KDF_memory">Nie można załadować klucza. Spróbuj zmniejszyć użycie pamięć KDF.</string>
@@ -196,8 +195,8 @@
<string name="warning_password_encoding">Unikaj znaków hasła spoza formatu kodowania tekstu w pliku bazy danych (nierozpoznane znaki są konwertowane na tę samą literę).</string>
<string name="sort_recycle_bin_bottom">Kosz na dole</string>
<string name="sort_title">Tytuł</string>
<string name="warning_empty_password">Czy naprawdę nie chcesz ochrony przed odblokowaniem hasła\?</string>
<string name="warning_no_encryption_key">Czy na pewno nie chcesz używać żadnego klucza szyfrowania?</string>
<string name="warning_empty_password">Kontynuować bez ochrony odblokowującej hasło\?</string>
<string name="warning_no_encryption_key">Kontynuować bez klucza szyfrowania\?</string>
<string name="version_label">Wersja %1$s</string>
<string name="configure_biometric">Skanowanie odcisków palców jest obsługiwane, ale nie skonfigurowane.</string>
<string name="encrypted_value_stored">Zapisano zaszyfrowane hasło</string>
@@ -232,7 +231,7 @@
<string name="biometric_unlock_enable_summary">Umożliwia zeskanowanie danych biometrycznych w celu otwarcia bazy danych</string>
<string name="biometric_delete_all_key_title">Usuń klucze szyfrowania</string>
<string name="biometric_delete_all_key_summary">Usuń wszystkie klucze szyfrowania związane z rozpoznawaniem linii papilarnych</string>
<string name="biometric_delete_all_key_warning">Czy na pewno chcesz usunąć wszystkie klucze związane z rozpoznawaniem linii papilarnych\?</string>
<string name="biometric_delete_all_key_warning">Czy usunąć wszystkie klucze szyfrowania związane z rozpoznawaniem biometrycznym\?</string>
<string name="unavailable_feature_text">Nie można uruchomić tej funkcji.</string>
<string name="unavailable_feature_version">Twoja wersja Androida %1$s nie spełnia wymaganej minimalnej wersji %2$s.</string>
<string name="unavailable_feature_hardware">Nie można znaleźć odpowiedniego sprzętu.</string>
@@ -281,7 +280,7 @@
<string name="education_biometric_summary">Połącz swoje hasło z zeskanowanym odciskiem palca, aby szybko odblokować bazę danych.</string>
<string name="education_entry_edit_title">Edytuj wpis</string>
<string name="education_entry_edit_summary">Edytuj swój wpis za pomocą pól niestandardowych. Dane puli mogą być przywoływane między różnymi polami wprowadzania.</string>
<string name="education_generate_password_title">Utwórz silne hasło do swojego wpisu.</string>
<string name="education_generate_password_title">Utwórz silne hasło</string>
<string name="education_generate_password_summary">Wygeneruj silne hasło, które będzie kojarzyć się z Twoim wpisem, łatwo zdefiniuj je zgodnie z kryteriami formularza i nie zapomnij o bezpiecznym haśle.</string>
<string name="education_entry_new_field_title">Dodaj niestandardowe pola</string>
<string name="education_entry_new_field_summary">Zarejestruj dodatkowe pole, dodaj wartość i opcjonalnie chroń je.</string>
@@ -420,7 +419,7 @@
<string name="error_otp_period">Okres musi wynosić od %1$d do %2$d sekund.</string>
<string name="error_otp_digits">Token musi zawierać cyfry od %1$d do %2$d.</string>
<string name="invalid_db_same_uuid">%1$s o tym samym identyfikatorze UUID %2$s już istnieje.</string>
<string name="contains_duplicate_uuid_procedure">Weryfikując to okno dialogowe, KeePassDX rozwiąże problem (poprzez wygenerowanie nowych UUID dla duplikatów) i będzie kontynuował.</string>
<string name="contains_duplicate_uuid_procedure">Rozwiązać problem poprzez stworzenie nowych identyfikatory UUID duplikatów, aby kontynuować\?</string>
<string name="clipboard_explanation_summary">Skopiuj pola wprowadzania danych za pomocą schowka urządzenia</string>
<string name="advanced_unlock_explanation_summary">Użyj zaawansowanego odblokowywania w celu łatwiejszego otwierania bazy danych</string>
<string name="database_data_compression_summary">Kompresja danych zmniejsza rozmiar bazy danych.</string>
@@ -433,24 +432,24 @@
<string name="menu_save_database">Zapisz bazę danych</string>
<string name="menu_empty_recycle_bin">Opróżnij kosz</string>
<string name="command_execution">Wykonywanie polecenia…</string>
<string name="warning_permanently_delete_nodes">Czy na pewno chcesz trwale usunąć wybrane węzły\?</string>
<string name="warning_permanently_delete_nodes">Czy trwale usunąć wybrane węzły\?</string>
<string name="keystore_not_accessible">Magazyn kluczy nie został poprawnie zainicjowany.</string>
<string name="credential_before_click_biometric_button">Wpisz hasło przed kliknięciem przycisku biometrycznego.</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_summary">Automatycznie zapisz bazę danych po ważnym działaniu (tylko w trybie „Modyfikowalnym”)</string>
<string name="enable_auto_save_database_summary">Zapisz bazę danych po każdym ważnym działaniu (w trybie „Modyfikowalnym”)</string>
<string name="entry_attachments">Załączniki</string>
<string name="menu_restore_entry_history">Przywróć 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_summary">Działanie klawisza Go wykonywane jest automatycznie po naciśnięciu klawisza Field</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_initialization">Inicjowanie…</string>
<string name="download_progression">W trakcie realizacji: %1$d%</string>
<string name="download_progression">W trakcie realizacji: %1$d&#37;</string>
<string name="download_finalization">Kończę…</string>
<string name="download_complete">Kompletny! Stuknij, aby otworzyć plik.</string>
<string name="hide_expired_entries_title">Ukryj wygasłe wpisy</string>
<string name="hide_expired_entries_summary">Wygasłe wpisy zostaną ukryte</string>
<string name="hide_expired_entries_summary">Wygasłe wpisy są ukryte</string>
<string name="contact">Kontakt</string>
<string name="html_about_contribution">Aby &lt;strong&gt;zachować naszą wolność&lt;/strong&gt;, &lt;strong&gt;sprawdzać błędy&lt;/strong&gt;, &lt;strong&gt;dodać funkcje&lt;/strong&gt; i &lt;strong&gt;by być zawsze aktywnym&lt;/strong&gt;, liczymy na twój &lt;strong&gt;wkład&lt;/strong&gt;.</string>
<string name="auto_focus_search_title">Szybkie wyszukiwanie</string>
@@ -465,4 +464,11 @@
<string name="hide_broken_locations_summary">Ukryj uszkodzone łącza na liście najnowszych baz danych</string>
<string name="warning_database_read_only">Przyznaj dostęp do zapisu pliku, aby zapisać zmiany w bazie danych</string>
<string name="contribution">Wkład</string>
<string name="education_setup_OTP_summary">Skonfiguruj zarządzanie hasłem jednorazowym (HOTP / TOTP), aby wygenerować token wymagany do uwierzytelniania dwuskładnikowego (2FA).</string>
<string name="education_setup_OTP_title">Konfiguracja OTP</string>
<string name="error_create_database">Nie można utworzyć pliku bazy danych.</string>
<string name="entry_add_attachment">Dodaj załącznik</string>
<string name="discard">Odrzuć</string>
<string name="discard_changes">Odrzucić zmiany\?</string>
<string name="validate">Walidacja</string>
</resources>

View File

@@ -103,7 +103,6 @@
<string name="never">Nunca</string>
<string name="no_results">Sem resultados na busca</string>
<string name="no_url_handler">Instale um navegador para abrir esta URL.</string>
<string name="open_recent">Bancos de dados recentes</string>
<string name="omit_backup_search_title">Não procurar por entradas no backup ou na lixeira</string>
<string name="omit_backup_search_summary">Omite os grupos \"Backup\" e \"Lixeira\" dos resultados da busca</string>
<string name="progress_create">Criando novo banco de dados…</string>
@@ -123,7 +122,6 @@
<string name="underline">Sublinhado</string>
<string name="unsupported_db_version">Versão de banco de dados não suportada.</string>
<string name="uppercase">Letras maiúsculas</string>
<string name="warning_unmounted">Monte o cartão SD para criar ou abrir um banco de dados.</string>
<string name="version_label">Versão %1$s</string>
<string name="education_unlock_summary">Entre com a senha e/ou com o caminho para o arquivo-chave do banco de dados.
\n

View File

@@ -115,7 +115,6 @@
<string name="never">Nunca</string>
<string name="no_results">A pesquisa não obteve resultados</string>
<string name="no_url_handler">Instale um navegador para abrir esta URL.</string>
<string name="open_recent">Bancos de dados recentes</string>
<string name="omit_backup_search_title">Não procurar por entradas no backup ou na lixeira</string>
<string name="omit_backup_search_summary">Omite os grupos \"Backup\" e \"Lixeira\" dos resultados da busca</string>
<string name="progress_create">A criar nova base de dados…</string>
@@ -141,7 +140,6 @@
<string name="uppercase">Maiúsculas</string>
<string name="warning">Aviso</string>
<string name="warning_password_encoding">Evite caracteres fora do formato de codificação do ficheiro do banco (todos os caracteres não reconhecidos são convertidos para a mesma letra).</string>
<string name="warning_unmounted">Monte o cartão SD para criar ou abrir um banco de dados.</string>
<string name="version_label">Versão %1$s</string>
<string name="education_unlock_summary">Entre com a palavra-passe e/ou com o caminho para o ficheiro-chave do banco de dados.
\n

View File

@@ -43,7 +43,7 @@
<string name="content_description_update_from_list">Actualizați</string>
<string name="content_description_remove_from_list">Elimina</string>
<string name="content_description_keyboard_close_fields">Câmpuri închise</string>
<string name="select_to_copy">%1$s is either \\\"Nume\\\" si \\\"Parola\\\".</string>
<string name="select_to_copy">Selectați pentru a copia %1$s în clipboard</string>
<string name="retrieving_db_key">Obtinerea cheii bazei de date…</string>
<string name="database">Baza de date</string>
<string name="decrypting_db">Decriptarea continutului bazei de date.…</string>
@@ -167,16 +167,15 @@
<string name="minus">Minus</string>
<string name="never">Niciodata</string>
<string name="no_results">Nu există Rezultate</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft is &lt;strong&gt;sursa deschisa&lt;strong&gt; and &lt;strong&gt;fara publicitate&lt;strong&gt;.
\nEste prevăzut așa cum este, sub &lt;strong&gt;GPLv3&lt;strong&gt; licenta,fara nici un fel de garantie.</string>
<string name="html_about_contribution">In oridine sa &lt;strong&gt;pastram libertatea noastra &lt;strong&gt;, &lt;strong&gt;fix bugs&lt;strong&gt;, &lt;strong&gt;adăugați funcții&lt;strong&gt; si&lt;strong&gt;sa fie intotdeauna activ&lt;strong&gt;", ne bazam pe "&lt;strong&gt;contributie.&lt;strong&gt;</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft is &lt;strong&gt;sursa deschisa&lt;strong&gt; and &lt;strong&gt;fara publicitate&lt;/strong&gt;.
\nEste prevăzut așa cum este, sub &lt;strong&gt;GPLv3&lt;/strong&gt; licenta, fara nici un fel de garantie.</string>
<string name="html_about_contribution">In oridine sa &lt;strong&gt;pastram libertatea noastra&lt;/strong&gt;, &lt;strong&gt;fix bugs&lt;/strong&gt;, &lt;strong&gt;adăugați funcții&lt;/strong&gt; si&lt;strong&gt;sa fie intotdeauna activ&lt;strong&gt;, ne bazam pe &lt;strong&gt;contributie&lt;/strong&gt;.</string>
<string name="hide_password_title">Ascundeți parolele</string>
<string name="hide_password_summary">Mascați parolele (***) în mod implicit</string>
<string name="about">Despre</string>
<string name="no_url_handler">Instalați un browser web pentru a deschide această adresă URL.</string>
<string name="select_database_file">Deschide baza de date existentă</string>
<string name="create_keepass_file">Creați o bază de date nouă</string>
<string name="open_recent">Baze de date recente</string>
<string name="progress_create">Crearea noii baze de date …</string>
<string name="progress_title">Lucrând …</string>
<string name="protection">Protecție</string>
@@ -217,7 +216,6 @@
<string name="uppercase">Cu majuscule</string>
<string name="warning">Avertizare</string>
<string name="warning_password_encoding">Evitați caracterele parole în afara formatului de codare a textului în fișierul bazei de date (caracterele nerecunoscute sunt convertite în aceeași literă).</string>
<string name="warning_unmounted">Montați cardul de memorie pentru a crea sau încărca o bază de date.</string>
<string name="warning_empty_password">Chiar nu doriți nicio protecție de deblocare a parolei\?</string>
<string name="warning_no_encryption_key">Ești sigur că nu vrei să folosești nicio cheie de criptare\?</string>
<string name="warning_permanently_delete_nodes">Sigur doriți să ștergeți definitiv nodurile selectate\?</string>
@@ -394,7 +392,7 @@
<string name="html_text_buy_pro">Cumpărând versiunea pro, veți avea acces la acest &lt;strong&gt; stil vizual &lt;/strong&gt; și vă va ajuta în special &lt;strong&gt; implementarea proiectelor comunitare. &lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Acest &lt;strong&gt; stil vizual &lt;/strong&gt; este disponibil datorită generozității tale.</string>
<string name="html_text_donation">Pentru a ne păstra libertatea și pentru a fi mereu activi, ne bazăm pe contribuția dvs. &lt;strong&gt;. &lt;/strong&gt;</string>
<string name="html_text_dev_feature">Această caracteristică este &lt;strong&gt; în curs de dezvoltare &lt;/strong&gt; și necesită ca contribuția dvs &lt;strong&gt; să fie disponibilă în curând.</string>
<string name="html_text_dev_feature">Această caracteristică este &lt;strong&gt; în curs de dezvoltare&lt;/strong&gt; și necesită ca &lt;strong&gt;contribuția&lt;/strong&gt; dvs să fie disponibilă în curând.</string>
<string name="html_text_dev_feature_buy_pro">Cumpărând versiunea &lt;strong&gt; pro &lt;/strong&gt;,</string>
<string name="html_text_dev_feature_contibute">Prin &lt;strong&gt; contribuție &lt;/strong&gt;,</string>
<string name="html_text_dev_feature_encourage">încurajezi dezvoltatorii să creeze &lt;strong&gt; funcții noi &lt;/strong&gt; și să &lt;strong&gt; remedieze erori &lt;/strong&gt; în conformitate cu observațiile tale.</string>
@@ -405,7 +403,7 @@
<string name="contribute">Contribuie</string>
<string name="download_attachment">Descărcați %1$s</string>
<string name="download_initialization">Inițializare …</string>
<string name="download_progression">In progress: %1$d%</string>
<string name="download_progression">In progress: %1$d&#37;</string>
<string name="download_finalization">Finalizare …</string>
<string name="download_complete">Complet! Atingeți pentru a deschide fișierul.</string>
<string name="encryption_rijndael">Rijndael (AES)</string>

View File

@@ -43,7 +43,7 @@
<string name="decrypting_db">Расшифровка базы…</string>
<string name="default_checkbox">База по умолчанию</string>
<string name="digits">Цифры</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft с &lt;strong&gt;открытым исходным кодом&lt;/strong&gt; и &lt;strong&gt;без рекламы&lt;/strong&gt;.
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft — это &lt;strong&gt;свободное программное обеспечение&lt;/strong&gt; и &lt;strong&gt;без рекламы&lt;/strong&gt;.
\nРаспространяется под лицензией &lt;strong&gt;GPLv3&lt;/strong&gt; без каких-либо гарантий.</string>
<string name="select_database_file">Открыть существующую базу</string>
<string name="entry_accessed">Доступ</string>
@@ -115,7 +115,6 @@
<string name="never">Никогда</string>
<string name="no_results">Совпадения не найдены</string>
<string name="no_url_handler">Установите браузер, чтобы открыть этот URL.</string>
<string name="open_recent">Недавно открытые базы</string>
<string name="omit_backup_search_title">Не искать в резервных копиях</string>
<string name="omit_backup_search_summary">Не искать в группах \"Резервирование\" и \"Корзина\"</string>
<string name="progress_create">Создание новой базы…</string>
@@ -141,7 +140,6 @@
<string name="uppercase">ЗАГЛАВНЫЕ</string>
<string name="warning">Внимание</string>
<string name="warning_password_encoding">Избегайте использования в пароле символов вне кодировки текста в файле базы, так как эти символы будут преобразованы в одинаковый символ.</string>
<string name="warning_unmounted">Подключите хранилище для создания или загрузки базы.</string>
<string name="version_label">Версия %1$s</string>
<string name="configure_biometric">Биометрия поддерживается, но не настроена.</string>
<string name="open_biometric_prompt_unlock_database">Ожидание биометрического ключа для разблокировки базы</string>
@@ -205,8 +203,8 @@
<string name="sort_groups_before">Сначала группы</string>
<string name="sort_recycle_bin_bottom">\"Корзина\" внизу</string>
<string name="sort_title">Название записи</string>
<string name="warning_empty_password">Вы действительно не хотите использовать пароль для защиты базы\?</string>
<string name="warning_no_encryption_key">Вы действительно не хотите использовать ключ шифрования?</string>
<string name="warning_empty_password">Продолжить без пароля для защиты базы\?</string>
<string name="warning_no_encryption_key">Продолжить без ключа шифрования\?</string>
<string name="biometric_not_recognized">Биометрический ключ не распознан</string>
<string name="database_history">История</string>
<string name="menu_appearance_settings">Внешний вид</string>
@@ -232,7 +230,7 @@
<string name="biometric_unlock_enable_summary">Включить разблокировку базы при помощи биометрического ключа</string>
<string name="biometric_delete_all_key_title">Удалить ключи шифрования</string>
<string name="biometric_delete_all_key_summary">Удалить все ключи шифрования, связанные с распознаванием биометрического ключа</string>
<string name="biometric_delete_all_key_warning">Вы уверены, что хотите удалить все ключи, связанные с биометрическим ключом\?</string>
<string name="biometric_delete_all_key_warning">Удалить все ключи шифрования, связанные с биометрическим распознаванием\?</string>
<string name="unavailable_feature_text">Невозможно запустить эту функцию.</string>
<string name="unavailable_feature_version">Ваша версия Android %1$s ниже минимально необходимой %2$s.</string>
<string name="unavailable_feature_hardware">Соответствующее оборудование не найдено.</string>
@@ -281,7 +279,7 @@
<string name="education_search_summary">Ищите записи по названию, имени или другим полям для быстрого доступа к своим паролям.</string>
<string name="education_entry_edit_title">Редактируйте записи</string>
<string name="education_entry_edit_summary">Редактируйте записи с настраиваемыми полями. Возможны перекрёстные ссылки между полями разных записей.</string>
<string name="education_generate_password_title">Создайте надёжный пароль для записи.</string>
<string name="education_generate_password_title">Создайте надёжный пароль</string>
<string name="education_generate_password_summary">Создайте надёжный пароль, связанный с записью, легко настраиваемый под критерии формы. И не забудьте главный пароль от базы.</string>
<string name="education_entry_new_field_title">Добавляйте настраиваемые поля</string>
<string name="education_entry_new_field_summary">Зарегистрируйте дополнительное поле, добавьте значение и при необходимости защитите его.</string>
@@ -388,14 +386,14 @@
<string name="security">Безопасность</string>
<string name="entry_history">История</string>
<string name="entry_setup_otp">Настройка одноразового пароля</string>
<string name="otp_type">Тип одноразового пароля</string>
<string name="otp_type">Тип OTP</string>
<string name="otp_secret">Секретный ключ</string>
<string name="otp_period">Время (в секундах)</string>
<string name="otp_counter">Счётчик</string>
<string name="otp_digits">Цифры</string>
<string name="otp_algorithm">Алгоритм</string>
<string name="entry_otp">Одноразовый пароль</string>
<string name="error_invalid_OTP">Недействительный секретный ключ одноразового пароля.</string>
<string name="entry_otp">OTP</string>
<string name="error_invalid_OTP">Некорректный OTP.</string>
<string name="error_disallow_no_credentials">Должен быть установлен, по крайней мере, один пароль.</string>
<string name="error_copy_group_here">Вы не можете копировать группу сюда.</string>
<string name="error_otp_secret_key">Секретный ключ должен быть в формате BASE32.</string>
@@ -407,7 +405,7 @@
<string name="menu_security_settings">Настройки безопасности</string>
<string name="menu_master_key_settings">Настройки главного пароля</string>
<string name="contains_duplicate_uuid">База содержит повторяющиеся UUID.</string>
<string name="contains_duplicate_uuid_procedure">Если вы разрешите, KeePassDX исправит проблему (путём создания новых UUID для дубликатов) и продолжит работу.</string>
<string name="contains_duplicate_uuid_procedure">Исправить проблему путём создания новых UUID для дубликатов и продолжить работу\?</string>
<string name="database_opened">База открыта</string>
<string name="clipboard_explanation_summary">Копирование полей ввода с помощью буфера обмена устройства</string>
<string name="advanced_unlock_explanation_summary">Использовать дополнительную разблокировку для более лёгкого открытия базы данных</string>
@@ -433,20 +431,20 @@
<string name="menu_save_database">Сохранить базу</string>
<string name="menu_empty_recycle_bin">Очистить \"корзину\"</string>
<string name="command_execution">Выполнение команды…</string>
<string name="warning_permanently_delete_nodes">Вы уверены, что хотите навсегда удалить выбранные узлы\?</string>
<string name="warning_permanently_delete_nodes">Безвозвратно удалить выбранные узлы\?</string>
<string name="keystore_not_accessible">Хранилище ключей не инициализировано должным образом.</string>
<string name="credential_before_click_biometric_button">Введите пароль перед нажатием кнопки биометрии.</string>
<string name="recycle_bin_group_title">Группа \"корзины\"</string>
<string name="enable_auto_save_database_title">Автосохранение базы</string>
<string name="enable_auto_save_database_summary">Автоматическое сохранение базы после каждого важного действия (только в \"режиме записи\")</string>
<string name="enable_auto_save_database_summary">Сохранять базу после каждого важного действия (в \"режиме записи\")</string>
<string name="entry_attachments">Вложения</string>
<string name="menu_restore_entry_history">Восстановить историю</string>
<string name="menu_delete_entry_history">Удалить историю</string>
<string name="keyboard_auto_go_action_title">Автоматическое действие кнопки</string>
<string name="keyboard_auto_go_action_summary">Выполнять команду \"Ввод\" автоматически после нажатия кнопки заполнения поля</string>
<string name="keyboard_auto_go_action_summary">Выполнять команду \"Ввод\" после нажатия кнопки заполнения поля</string>
<string name="download_attachment">Скачать %1$s</string>
<string name="download_initialization">Инициализация…</string>
<string name="download_progression">Выполнение: %1$d%</string>
<string name="download_progression">Выполнение: %1$d&#37;</string>
<string name="download_finalization">Завершение…</string>
<string name="download_complete">Готово! Нажмите, чтобы открыть файл.</string>
<string name="hide_expired_entries_title">Скрывать устаревшие записи</string>
@@ -465,4 +463,11 @@
<string name="hide_broken_locations_title">Скрывать отсутствующие</string>
<string name="hide_broken_locations_summary">Не показывать неработающие ссылки в списке последних открытых баз</string>
<string name="warning_database_read_only">Необходимо разрешение на запись в файл для сохранения изменений базы</string>
<string name="validate">Проверить</string>
<string name="discard_changes">Отменить изменения\?</string>
<string name="discard">Отменить</string>
<string name="entry_add_attachment">Добавить вложение</string>
<string name="error_create_database">Невозможно создать файл базы.</string>
<string name="education_setup_OTP_title">Настройте OTP</string>
<string name="education_setup_OTP_summary">Настройте управление одноразовыми паролями (HOTP / TOTP) для создания токена, запрашиваемого при двухфакторной аутентификации (2FA).</string>
</resources>

View File

@@ -103,7 +103,6 @@
<string name="never">Nikdy</string>
<string name="no_results">Žiadne výsledky hľadania</string>
<string name="no_url_handler">Žiaden manažér pre url.</string>
<string name="open_recent">Otvoriť poslednú databázu :</string>
<string name="omit_backup_search_title">Neprehľadávať položky</string>
<string name="omit_backup_search_summary">Vynechať skupinu \'Backup\' a Recycle Bin z výsledkov hľadania</string>
<string name="progress_create">Vytváram novú databázu…</string>
@@ -123,7 +122,6 @@
<string name="underline">Podčiarknuté</string>
<string name="unsupported_db_version">Nepodporovaná verzia databázy.</string>
<string name="uppercase">Veľké písmená</string>
<string name="warning_unmounted">Vaša SD karta nie je momentálne pripojená k zariadeniu. Nemôžete načítať, alebo vytvoriť databázu.</string>
<string name="version_label">Version %1$s</string>
<string name="education_unlock_summary">Vložte heslo a / alebo keyfile pre odomknutie databázy.</string>
<string-array name="timeout_options">

View File

@@ -114,7 +114,6 @@
<string name="never">Aldrig</string>
<string name="no_results">Inget sökresultat</string>
<string name="no_url_handler">Installera en webbläsare för att öppna denna URL.</string>
<string name="open_recent">Senast öppnade databaser</string>
<string name="omit_backup_search_title">Sök inte efter backup-poster</string>
<string name="omit_backup_search_summary">Utelämnar poster i grupperna \"Backup\" och \"Papperskorg\"</string>
<string name="progress_create">Skapar ny databas…</string>
@@ -136,7 +135,6 @@
<string name="underline">Understreck</string>
<string name="unsupported_db_version">Databasversionen stöds ej.</string>
<string name="uppercase">Versaler</string>
<string name="warning_unmounted">Montera SD-kortet för att skapa eller ladda in en databas.</string>
<string name="version_label">Version %1$s</string>
<string name="education_unlock_summary">Ange lösenord och/eller nyckelfil för att öppna databasen.
\n

View File

@@ -16,7 +16,8 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--><resources>
-->
<resources>
<string name="feedback">Geri Bildirim</string>
<string name="homepage">Ana sayfa</string>
<string name="about_description">KeePass parola yöneticisinin Android uygulaması</string>
@@ -64,7 +65,8 @@
<string name="decrypting_db">Veritabanı içeriği deşifre ediliyor…</string>
<string name="default_checkbox">Varsayılan veritabanı olarak kullan</string>
<string name="digits">Rakamlar</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft kesinlikle bir garanti vermez. Bu, libre yazılımıdır ve GPL sürüm 3 veya üzeri şartlar altında yeniden dağıtmanız mümkündür.</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft &lt;strong&gt;özgür yazılımdır&lt;/strong&gt; ve &lt;strong&gt;reklam içermez&lt;/strong&gt;.
\n&lt;strong&gt;GPLv3&lt;/strong&gt; lisansı altında sağlanmaktadır, herhangi bir garanti vermez.</string>
<string name="entry_expires">Süre sonu</string>
<string name="entry_keyfile">Anahtar dosya</string>
<string name="error_arc4">Arcfour akış şifresi desteklenmiyor.</string>
@@ -76,7 +78,7 @@
<string name="error_pass_gen_type">En az bir parola oluşturma türü seçilmelidir.</string>
<string name="error_pass_match">Parolalar uyuşmuyor.</string>
<string name="error_rounds_too_large">\"Dönüşüm turları\" çok yüksek. 2147483648\'e ayarlayın.</string>
<string name="error_string_key">Her dizenin bir alan adı olmalıdır.</string>
<string name="error_string_key">Her dizginin bir alan adı olmalıdır.</string>
<string name="error_wrong_length">\"Uzunluk\" alanına pozitif bir tam sayı girin.</string>
<string name="error_autofill_enable_service">Otomatik doldurma hizmeti etkinleştirilemedi.</string>
<string name="error_move_folder_in_itself">Bir grubu kendine taşıyamazsın.</string>
@@ -135,7 +137,6 @@
<string name="no_url_handler">Bu URL\'u açmak için bir web tarayıcısı yükleyin.</string>
<string name="select_database_file">Mevcut veritabanını</string>
<string name="create_keepass_file">Yeni veritabanı oluştur</string>
<string name="open_recent">Son veritabanları</string>
<string name="omit_backup_search_title">Yedek girişleri arama</string>
<string name="omit_backup_search_summary">Arama sonuçlarından \"Yedekleme\" ve \"Geri dönüşüm kutusu\" gruplarını atlar</string>
<string name="progress_create">Yeni veritabanı oluştur…</string>
@@ -175,9 +176,8 @@
<string name="uppercase">Büyük harf</string>
<string name="warning">Uyarı</string>
<string name="warning_password_encoding">Veritabanı dosyasındaki metin kodlama formatının dışındaki parola karakterlerinden kaçının (tanınmayan karakterler benzer harfe dönüştürülür).</string>
<string name="warning_unmounted">Bir veritabanı oluşturmak veya yüklemek için hafıza kartını takın.</string>
<string name="warning_empty_password">Gerçekten parolasız açma koruması mı istiyorsunuz\?</string>
<string name="warning_no_encryption_key">Herhangi bir şifreleme anahtarı kullanmak istemediğinize emin misiniz\?</string>
<string name="warning_empty_password">Parola kilidi koruması olmadan devam edilsin mi\?</string>
<string name="warning_no_encryption_key">Şifreleme anahtarı olmadan devam edilsin mi\?</string>
<string name="version_label">Sürüm %1$s</string>
<string name="build_label">Yapı %1$s</string>
<string name="configure_biometric">Parmak izi taraması desteklenir, ancak kurulmaz.</string>
@@ -212,7 +212,7 @@
<string name="biometric_unlock_enable_summary">Veritabanını açmak için biyometriklerinizi taramanızı sağlar</string>
<string name="biometric_delete_all_key_title">Şifreleme anahtarlarını silin</string>
<string name="biometric_delete_all_key_summary">Parmak izi tanıma ile ilgili tüm şifreleme anahtarlarını silin</string>
<string name="biometric_delete_all_key_warning">Parmak izi tanıma ile ilgili tüm tuşları silmek istediğinizden emin misiniz\?</string>
<string name="biometric_delete_all_key_warning">Biyometrik tanıma ile ilgili tüm şifreleme anahtarları silinsin mi\?</string>
<string name="unavailable_feature_text">Bu özellik başlatılamadı.</string>
<string name="unavailable_feature_version">Android sürümünüz %1$s, gerekli minimum %2$s sürümünü karşılamıyor.</string>
<string name="unavailable_feature_hardware">İlgili donanım bulunamadı.</string>
@@ -278,10 +278,10 @@
<string name="education_biometric_summary">Veritabanınızı hızlıca açmak için parolanızı taranan parmak izinize bağlayın.</string>
<string name="education_entry_edit_title">Girdiyi düzenle</string>
<string name="education_entry_edit_summary">Girdinizi özel alanlarla düzenleyin. Havuz verileri farklı giriş alanları arasında referans alınabilir.</string>
<string name="education_generate_password_title">Girdiniz için güçlü bir parola oluşturun.</string>
<string name="education_generate_password_title">Güçlü bir parola oluşturun</string>
<string name="education_generate_password_summary">Girişinizle ilişkilendirmek için güçlü bir şifre oluşturun, formun kriterlerine göre kolayca tanımlayın ve güvenli şifreyi unutmayın.</string>
<string name="education_entry_new_field_title">Özel alanlar ekle</string>
<string name="education_entry_new_field_summary">Ayrıca koruyabileceğiniz yeni bir formu doldurarak temel bir tedarik edilmemiş alanı kaydedin.</string>
<string name="education_entry_new_field_summary">Ek bir alan kaydedin, bir değer ekleyin ve isteğe bağlı olarak koruyun.</string>
<string name="education_unlock_title">Veritabanınızın kilidini açın</string>
<string name="education_unlock_summary">Veritabanınızın kilidini açmak için parola ve/veya anahtar dosya girin.
\n
@@ -301,7 +301,7 @@
<string name="education_sort_summary">Girdilerin ve grupların nasıl sıralandığını seçin.</string>
<string name="education_donation_title">Katıl</string>
<string name="education_donation_summary">Daha fazla özellik ekleyerek istikrarı, güvenliği artırmaya yardımcı olun.</string>
<string name="html_text_ad_free">Birçok parola yönetimi uygulamasının aksine, bu uygulama &lt;strong&gt;reklam içermez&lt;/strong&gt;, &lt;strong&gt;ık kaynaklı&lt;/strong&gt; ve &lt;strong&gt;copyleft lisanslıdır&lt;/strong&gt;. Hangi sürümü (ücretsiz veya profesyonel) kullanırsanız kullanın, herhangi bir biçimde &lt;strong&gt;kişisel veri toplanmamaktadır&lt;/strong&gt;.</string>
<string name="html_text_ad_free">Birçok parola yönetimi uygulamasının aksine, bu uygulama &lt;strong&gt;reklam içermez&lt;/strong&gt;, &lt;strong&gt; copyleft lisanslı özgür yazılımdır&lt;/strong&gt; ve hangi sürümü kullanırsanız kullanın, sunucularında kişisel veri toplamaz.</string>
<string name="html_text_buy_pro">Profesyonel sürümü satın alarak, bu &lt;strong&gt;görsel stile&lt;/strong&gt; erişebilecek ve özellikle &lt;strong&gt;topluluk projelerinin gerçekleştirilmesine&lt;/strong&gt; yardımcı olacaksınız.</string>
<string name="html_text_feature_generosity">Bu &lt;strong&gt;görsel stil&lt;/strong&gt;, cömertliğiniz sayesinde kullanılabilir.</string>
<string name="html_text_donation">Özgürlüğümüzü korumak ve daima aktif olmak için &lt;strong&gt;katkılarınıza&lt;/strong&gt; güveniyoruz</string>
@@ -390,7 +390,7 @@
<string name="menu_security_settings">Güvenlik ayarları</string>
<string name="menu_master_key_settings">Ana anahtar ayarları</string>
<string name="contains_duplicate_uuid">Veritabanı tekrarlanan UUID\'ler içermektedir.</string>
<string name="contains_duplicate_uuid_procedure">Bu iletişim kutusunu doğrulayarak, KeePassDX sorunu çözecek (tekrarlananlar için yeni UUID\'ler oluşturarak) ve devam edecektir.</string>
<string name="contains_duplicate_uuid_procedure">Tekrarlananlar için yeni UUID\'ler oluşturarak sorunu çöz ve devam et\?</string>
<string name="database_opened">Veritabanııldı</string>
<string name="clipboard_explanation_summary">Cihazınızın panosunu kullanarak giriş alanlarını kopyala</string>
<string name="advanced_unlock_explanation_summary">Veritabanını daha kolay açmak için gelişmiş kilit açma özelliğini kullan</string>
@@ -404,29 +404,29 @@
<string name="settings_database_recommend_changing_master_key_summary">Ana anahtarın değiştirilmesini öner (gün)</string>
<string name="settings_database_force_changing_master_key_title">Yenilemeyi zorla</string>
<string name="settings_database_force_changing_master_key_summary">Ana anahtarın değiştirilmesini gerektir (gün)</string>
<string name="settings_database_force_changing_master_key_next_time_title">Bir dahaki sefere yenilemeyi zorla</string>
<string name="settings_database_force_changing_master_key_next_time_title">Bir dahaki sefere yenilemeye zorla</string>
<string name="settings_database_force_changing_master_key_next_time_summary">Bir dahaki sefere ana anahtarı değiştirmeyi gerektirir (bir kez)</string>
<string name="database_default_username_title">Varsayılan kullanıcı adı</string>
<string name="database_custom_color_title">Özel veritabanı rengi</string>
<string name="compression">Sıkıştırma</string>
<string name="compression_none">Yok</string>
<string name="compression_gzip">gzip</string>
<string name="device_keyboard_setting_title">Cihaz klavye Ayarları</string>
<string name="device_keyboard_setting_title">Cihaz klavye ayarları</string>
<string name="error_save_database">Veritabanı kaydedilemedi.</string>
<string name="menu_save_database">Veritabanını kaydet</string>
<string name="menu_empty_recycle_bin">Geri dönüşüm kutusunu boşalt</string>
<string name="command_execution">Komut çalıştırılıyor…</string>
<string name="warning_permanently_delete_nodes">Seçili düğümleri kalıcı olarak silmek istediğinizden emin misiniz\?</string>
<string name="warning_permanently_delete_nodes">Seçilen düğümler kalıcı olarak silinsin mi\?</string>
<string name="keystore_not_accessible">Anahtar deposu düzgün bir şekilde başlatılmadı.</string>
<string name="credential_before_click_biometric_button">Biyometrik butona tıklamadan önce şifreyi yazın.</string>
<string name="recycle_bin_group_title">Geri dönüşüm kutusu grubu</string>
<string name="enable_auto_save_database_title">Veritabanını otomatik kaydet</string>
<string name="enable_auto_save_database_summary">Önemli bir işlemden sonra veritabanını otomatik olarak kaydet (yalnızca \"Değiştirilebilir\" modunda)</string>
<string name="enable_auto_save_database_summary">Her önemli işlemden sonra veri tabanını kaydet (\"Değiştirilebilir\" modda)</string>
<string name="entry_attachments">Ekler</string>
<string name="menu_restore_entry_history">Geçmişi geri yükle</string>
<string name="menu_delete_entry_history">Geçmişi sil</string>
<string name="keyboard_auto_go_action_title">Otomatik tuş eylemi</string>
<string name="keyboard_auto_go_action_summary">Alan tuşuna bastıktan sonra otomatik olarak gerçekleştirilen Git tuşunun eylemi</string>
<string name="keyboard_auto_go_action_summary">\"Alan\" tuşuna bastıktan sonra \"Git\" tuşu eylemi</string>
<string name="download_attachment">İndir %1$s</string>
<string name="download_initialization">Başlatılıyor…</string>
<string name="download_progression">Devam ediyor: %1$d&#37;</string>
@@ -434,4 +434,25 @@
<string name="download_complete">Tamamlandı! Dosyayı açmak için dokunun.</string>
<string name="hide_expired_entries_title">Süresi dolmuş girdileri gizle</string>
<string name="hide_expired_entries_summary">Süresi dolmuş girdiler gizlenecek</string>
<string name="warning_database_read_only">Veritabanı değişikliklerini kaydetmek için dosya yazma erişimi ver</string>
<string name="hide_broken_locations_summary">Son veritabanları listesindeki bozuk bağlantıları gizle</string>
<string name="hide_broken_locations_title">Bozuk veritabanı bağlantılarını gizle</string>
<string name="show_recent_files_summary">Son veritabanlarının konumlarını göster</string>
<string name="show_recent_files_title">Son dosyaları göster</string>
<string name="remember_keyfile_locations_summary">Veri tabanını anahtar dosyalarının konumunu hatırla</string>
<string name="remember_keyfile_locations_title">Anahtar dosyalarının konumlarını kaydet</string>
<string name="remember_database_locations_summary">Veri tabanlarının konumlarını hatırla</string>
<string name="remember_database_locations_title">Veri tabanlarının konumlarını kaydet</string>
<string name="auto_focus_search_summary">Veri tabanını açarken arama iste</string>
<string name="auto_focus_search_title">Hızlı arama</string>
<string name="contribution">Katkı</string>
<string name="contact">İletişim</string>
<string name="education_setup_OTP_summary">İki öğeli kimlik doğrulaması (2FA) için istenen bir belirteç oluşturmak için Bir Kerelik Parola yönetimini (HOTP / TOTP) ayarlayın.</string>
<string name="education_setup_OTP_title">OTP ayarla</string>
<string name="error_create_database">Veritabanı dosyası oluşturulamıyor.</string>
<string name="html_about_contribution">&lt;strong&gt;Özgürlüğümüzü korumak&lt;/strong&gt;, &lt;strong&gt;hataları düzeltmek&lt;/strong&gt;, &lt;strong&gt;özellikler eklemek&lt;/strong&gt; ve &lt;strong&gt;her zaman etkin olmak&lt;/strong&gt; için, &lt;strong&gt;desteğinize&lt;/strong&gt; güveniyoruz.</string>
<string name="entry_add_attachment">Ek ekle</string>
<string name="discard">Vazgeç</string>
<string name="discard_changes">Değişikliklerden vazgeç\?</string>
<string name="validate">Doğrula</string>
</resources>

View File

@@ -104,7 +104,6 @@
<string name="never">Ніколи</string>
<string name="no_results">Нічого не знайдено.</string>
<string name="no_url_handler">Нема програми для опрацювання цього посилання.</string>
<string name="open_recent">Відкрити останню базу даних :</string>
<string name="omit_backup_search_title">Не шукати записів з резервного копіювання та кошиків</string>
<string name="omit_backup_search_summary">Пропустити групу \'Резервна копія\' та Кошик серед результатів пошуку</string>
<string name="progress_create">Створення нової бази даних&#8230;</string>
@@ -124,7 +123,6 @@
<string name="underline">Підкреслення</string>
<string name="unsupported_db_version">Непідтримувана версія бази даних.</string>
<string name="uppercase">Верхній регістр</string>
<string name="warning_unmounted">Ваша карта пам’яті зараз не змонтована на телефоні. Ви не зможете завантажити або створити базу даних.</string>
<string name="version_label">Версія %1$s</string>
<string name="education_unlock_summary">Введіть пароль і/або файл ключа для відкриття бази даних.</string>

View File

@@ -28,6 +28,7 @@
<style name="KeepassDXStyle.Night" parent="KeepassDXStyle.Night.v21" >
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="android:navigationBarColor">@color/background_dark</item>
<item name="android:timePickerDialogTheme">@style/KeepassDXStyle.Night.DateTime.Dialog</item>
<item name="android:datePickerDialogTheme">@style/KeepassDXStyle.Night.DateTime.Dialog</item>
</style>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">反馈</string>
<string name="homepage">主页</string>
<string name="about_description">Android平台上KeePass密码管理器</string>
<string name="about_description">Android 平台上基于 KeePass 实现的密码管理器</string>
<string name="accept">接受</string>
<string name="add_entry">添加条目</string>
<string name="add_group">添加群组</string>
@@ -39,7 +39,7 @@
<string name="decrypting_db">正在解密数据库内容…</string>
<string name="default_checkbox">设为默认数据库</string>
<string name="digits">数字</string>
<string name="html_about_licence">KeePassDX © %1$d 是Kunzisoft的一个&lt;strong&gt;开源&lt;/strong&gt;&lt;strong&gt;广告&lt;/strong&gt;软件
<string name="html_about_licence">KeePassDX © %1$d 是 Kunzisoft 的一个&lt;strong&gt;自由软件&lt;/strong&gt;并且&lt;strong&gt;不含广告&lt;/strong&gt;
\n它是根据&lt;strong&gt;GPLv3&lt;/strong&gt;许可证分发的您可在遵循GPL 3或者更高版本的协议下重新发布。Kunzisoft对软件的质量和性能等问题不提供任何形式的担保。</string>
<string name="select_database_file">打开已有数据库</string>
<string name="entry_accessed">访问时间</string>
@@ -103,7 +103,6 @@
<string name="never">从不</string>
<string name="no_results">没有搜索结果</string>
<string name="no_url_handler">需要安装网络浏览器才能打开这个URL。</string>
<string name="open_recent">最近用过的数据库</string>
<string name="progress_create">正在新建数据库…</string>
<string name="progress_title">正在处理…</string>
<string name="content_description_remove_from_list">移除</string>
@@ -121,10 +120,9 @@
<string name="underline">下划线</string>
<string name="unsupported_db_version">不支持的数据库版本。</string>
<string name="uppercase">大写</string>
<string name="warning_unmounted">请挂载内存卡以新建或加载数据库。</string>
<string name="education_unlock_summary">输入密码和/或密钥文件来解锁你的数据库。
\n
\n记得在每次更改后将数据库文件备份至安全的地方。</string>
\n
\n记得在每次做出更改后将数据库文件备份至安全的地方。</string>
<string-array name="timeout_options">
<item>5秒</item>
<item>10秒</item>
@@ -173,7 +171,7 @@
<string name="menu_paste">粘贴</string>
<string name="menu_cancel">取消</string>
<string name="menu_showpass">显示密码</string>
<string name="menu_biometric_remove_key">删除已保存生物识别密钥</string>
<string name="menu_biometric_remove_key">删除已保存的与生物识别相关的密钥</string>
<string name="menu_file_selection_read_only">只读</string>
<string name="menu_open_file_read_and_write">可修改</string>
<string name="omit_backup_search_title">搜索时忽略备份条目</string>
@@ -222,7 +220,7 @@
<string name="other">其他</string>
<string name="keyboard">键盘</string>
<string name="magic_keyboard_title">魔法键盘</string>
<string name="enable_read_only_title">写保护(只读模式)</string>
<string name="enable_read_only_title">保护(只读模式)</string>
<string name="enable_read_only_summary">默认以只读方式打开数据库</string>
<string name="download">下载</string>
<string name="contribute">贡献</string>
@@ -235,18 +233,18 @@
<string name="warning_password_encoding">避免在数据库中保存编码格式外字符的密码(未识别的字符将转换为同一字符)。</string>
<string name="sort_groups_before">群组在前</string>
<string name="sort_recycle_bin_bottom">回收站在末尾</string>
<string name="warning_empty_password">确定不用密码解锁</string>
<string name="warning_no_encryption_key">确认使用密钥吗?</string>
<string name="warning_empty_password">确定不使用密码保护</string>
<string name="warning_no_encryption_key">确认使用加密密钥吗?</string>
<string name="build_label">版本%1$s</string>
<string name="configure_biometric">支持生物识别设置,但并未启用生物识别。</string>
<string name="open_biometric_prompt_unlock_database">打开生物识别对话框以解锁数据库</string>
<string name="encrypted_value_stored">加密密码已保存</string>
<string name="biometric_invalid_key">不能读取生物识别密钥,请删除所有生物密钥,并重新录入。</string>
<string name="biometric_invalid_key">不能读取生物识别密钥,请删除所有生物识别密钥,并重新录入。</string>
<string name="biometric_not_recognized">无法识别生物识别信息</string>
<string name="biometric_scanning_error">生物识别错误:%1$s</string>
<string name="no_credentials_stored">当前数据库无密码。</string>
<string name="set_autofill_service_title">设为默认的填充服务</string>
<string name="autofill_explanation_summary">启用自动填充功能,以便捷地在其他程序中填写信息</string>
<string name="autofill_explanation_summary">启用自动填充功能,以快速填写其他应用中的表单</string>
<string name="password_size_title">密码生成长度</string>
<string name="password_size_summary">设置生成密码的默认长度</string>
<string name="list_password_generator_options_title">密码字符集</string>
@@ -258,8 +256,8 @@
<string name="biometric_unlock_enable_title">生物识别解锁</string>
<string name="biometric_unlock_enable_summary">通过生物识别解锁数据库</string>
<string name="biometric_delete_all_key_title">删除加密密钥</string>
<string name="biometric_delete_all_key_summary">删除所有与生物相关的加密密钥</string>
<string name="biometric_delete_all_key_warning">要删除所有生物识别密钥吗?</string>
<string name="biometric_delete_all_key_summary">删除所有与生物识别相关的密钥</string>
<string name="biometric_delete_all_key_warning">要删除所有生物识别相关的密钥吗?</string>
<string name="unavailable_feature_text">无法启动此功能。</string>
<string name="unavailable_feature_version">你的Android版本%1$s无法满足程序对系统版本%2$s的要求。</string>
<string name="unavailable_feature_hardware">找不到所需的硬件。</string>
@@ -311,16 +309,16 @@
<string name="education_biometric_summary">将主密钥与生物识别信息关联,以快速解锁数据库。</string>
<string name="education_entry_edit_title">编辑此条目</string>
<string name="education_entry_edit_summary">使用自定义字段编辑条。自定义字段可以在不同的条目间引用。</string>
<string name="education_generate_password_title">为记录新建强密码</string>
<string name="education_generate_password_summary">依据表中的标准生成新密码,并将密码与条目关联起来,永不忘记</string>
<string name="education_generate_password_title">新建一个强密码</string>
<string name="education_generate_password_summary">依据表中的标准进行简单的定义,随机为该条目生成一个强密码,不在担心忘记安全密码</string>
<string name="education_entry_new_field_title">添加自定义字段</string>
<string name="education_entry_new_field_summary">添加一个新的字段并添加为其添加一个值,此时可以选择是否保护该字段及其值。</string>
<string name="education_unlock_title">解锁数据库</string>
<string name="education_read_only_title">数据库开启写保护(只读)</string>
<string name="education_read_only_summary">在会话中改变打开模式。
\n
\n“写保护只读将阻止对数据库的任何修改。
\n“可编辑可写添加、删除或者修改元素。</string>
<string name="education_read_only_title">数据库启用写入保护(只读)</string>
<string name="education_read_only_summary">更改会话的打开模式。
\n
\n“写保护(只读)”可防止对数据库的意外更改。
\n“可编辑可写允许您添加、删除或者修改元素。</string>
<string name="education_field_copy_title">复制字段</string>
<string name="education_field_copy_summary">已复制的字段可以粘贴到任何地方。
\n
@@ -331,21 +329,21 @@
<string name="education_sort_summary">选择条目和群组的排序方式。</string>
<string name="education_donation_title">参与开发</string>
<string name="education_donation_summary">帮助增加稳定性,安全性并添加更多的功能。</string>
<string name="html_text_ad_free">不同于大多数的密码管理程序无论您是使用免费版本还是付费版本的KeePassDX这都是一款&lt;strong&gt;没有广告&lt;/strong&gt;&lt;strong&gt;基于copylefted版权协议的免费软件&lt;/strong&gt;同样的本软件的任何版本不会收集您的个人信息。</string>
<string name="html_text_buy_pro">通过购买高级版本,您将解锁全部&lt;strong&gt;主题样式&lt;/strong&gt;,重要的是,您会为&lt;strong&gt;社区项目的进行&lt;/strong&gt;提供帮助</string>
<string name="html_text_feature_generosity">&lt;strong&gt;主题样式&lt;/strong&gt;现在已经可用,感谢慷慨相助。</string>
<string name="html_text_donation">为继续建设此自由项目,我们需要&lt;strong&gt;&lt;/strong&gt;</string>
<string name="html_text_dev_feature">这个特性目前&lt;strong&gt;仍在开发中&lt;/strong&gt;&lt;strong&gt;捐助&lt;/strong&gt;将使这个特性在未来变得可用。</string>
<string name="html_text_ad_free">不同于大多数的密码管理程序,无论您是使用免费版本还是付费版本的 KeePassDX这都是一款&lt;strong&gt;没有广告&lt;/strong&gt;&lt;strong&gt;基于 copylefted 版权协议的自由软件&lt;/strong&gt;。同时,本软件的任何版本不会收集您的任何个人信息。</string>
<string name="html_text_buy_pro">通过购买高级版本,您将解锁全部&lt;strong&gt;主题样式&lt;/strong&gt;,重要的是,您会为&lt;strong&gt;社区项目的进行&lt;/strong&gt;提供帮助</string>
<string name="html_text_feature_generosity">&lt;strong&gt;主题样式&lt;/strong&gt;可用,感谢您的慷慨相助。</string>
<string name="html_text_donation">为继续建设此自由项目让其保持活跃,我们需要您的&lt;strong&gt;&lt;/strong&gt;</string>
<string name="html_text_dev_feature">此功能目前&lt;strong&gt;仍在开发中&lt;/strong&gt;&lt;strong&gt;捐助&lt;/strong&gt;将使该功能很快变得可用。</string>
<string name="html_text_dev_feature_buy_pro">通过购买&lt;strong&gt;专业&lt;/strong&gt;版,</string>
<string name="html_text_dev_feature_contibute">通过&lt;strong&gt;贡献&lt;/strong&gt;</string>
<string name="html_text_dev_feature_encourage">您的留言,鼓励了开发人员开发&lt;strong&gt;特性&lt;/strong&gt;&lt;strong&gt;修复程序缺陷&lt;/strong&gt;</string>
<string name="html_text_dev_feature_encourage">您的留言,是对开发人员添加&lt;strong&gt;功能&lt;/strong&gt;&lt;strong&gt;修复 bugs&lt;/strong&gt; 的鼓励</string>
<string name="html_text_dev_feature_thanks">非常感谢您的捐助和贡献。</string>
<string name="html_text_dev_feature_work_hard">我们正在努力的研发并尽快发布新特性。</string>
<string name="html_text_dev_feature_upgrade">别忘了更新程序。</string>
<string name="selection_mode">选择模式</string>
<string name="do_not_kill_app">不要终止程序…</string>
<string name="lock_database_back_root_title">按返回键以锁定</string>
<string name="lock_database_back_root_summary">在点按根屏幕上的后退按钮时锁定数据库</string>
<string name="lock_database_back_root_summary">点击屏幕底部的返回键时锁定数据库</string>
<string name="clear_clipboard_notification_title">关闭程序时清空剪贴板</string>
<string name="clear_clipboard_notification_summary">清除通知时锁定数据库</string>
<string name="recycle_bin">回收站</string>
@@ -397,7 +395,7 @@
<string name="otp_digits">数字位数</string>
<string name="otp_algorithm">算法</string>
<string name="entry_otp">一次性密码</string>
<string name="error_invalid_OTP">一次性密码密钥错误</string>
<string name="error_invalid_OTP">错误的一次性密码密钥。</string>
<string name="error_disallow_no_credentials">至少需要设置一个凭据。</string>
<string name="error_copy_group_here">不能将群组复制到这里。</string>
<string name="error_otp_secret_key">密钥必须是BASE32格式。</string>
@@ -409,7 +407,7 @@
<string name="menu_security_settings">安全设置</string>
<string name="menu_master_key_settings">主密钥设置</string>
<string name="contains_duplicate_uuid">数据库包含重复UUID。</string>
<string name="contains_duplicate_uuid_procedure">通过验证此对话框KeePassDX将解决这个问题通过给重复项生成新的UUID)并继续。</string>
<string name="contains_duplicate_uuid_procedure">通过重复项生成新的UUID以继续解决问题?</string>
<string name="database_opened">数据库开启</string>
<string name="clipboard_explanation_summary">使用设备的剪贴板来复制输入字段</string>
<string name="advanced_unlock_explanation_summary">使用高级解锁轻松打开数据库</string>
@@ -423,7 +421,7 @@
<string name="settings_database_recommend_changing_master_key_summary">建议修改主密钥(以天为单位)</string>
<string name="settings_database_force_changing_master_key_title">强制修改</string>
<string name="settings_database_force_changing_master_key_summary">要求修改主密钥(以天为单位)</string>
<string name="settings_database_force_changing_master_key_next_time_title">下次强制修改</string>
<string name="settings_database_force_changing_master_key_next_time_title">下次强制更新修改</string>
<string name="settings_database_force_changing_master_key_next_time_summary">下次强制修改主密钥(一次)</string>
<string name="database_default_username_title">默认用户名</string>
<string name="database_custom_color_title">自定义数据库颜色</string>
@@ -435,27 +433,27 @@
<string name="menu_save_database">保存数据库</string>
<string name="menu_empty_recycle_bin">清空回收站</string>
<string name="command_execution">正在执行命令……</string>
<string name="warning_permanently_delete_nodes">确认要永久删除选中的条目</string>
<string name="warning_permanently_delete_nodes">是否永久删除选中的条目?</string>
<string name="credential_before_click_biometric_button">请先输入密码,再点击生物识别按钮。</string>
<string name="recycle_bin_group_title">回收站(组)</string>
<string name="enable_auto_save_database_title">自动保存数据库</string>
<string name="enable_auto_save_database_summary">行重要操作后自动保存数据库(仅在编辑模式下有效)</string>
<string name="enable_auto_save_database_summary">每次执行重要操作后保存数据库(仅在编辑模式下有效)</string>
<string name="keystore_not_accessible">密钥库未正确地初始化。</string>
<string name="entry_attachments">附件</string>
<string name="menu_restore_entry_history">恢复历史记录</string>
<string name="menu_delete_entry_history">删除历史记录</string>
<string name="keyboard_auto_go_action_title">自动键操作</string>
<string name="keyboard_auto_go_action_summary">入用户名或密码后直接登录</string>
<string name="keyboard_auto_go_action_summary">充条目后直接登录</string>
<string name="download_attachment">下载%1$s</string>
<string name="download_initialization">正在初始化…</string>
<string name="download_progression">进行中:%1$d%</string>
<string name="download_progression">进行中:%1$d&#37;</string>
<string name="download_finalization">正在完成…</string>
<string name="download_complete">完成!点击打开文件。</string>
<string name="hide_expired_entries_title">隐藏过期条目</string>
<string name="hide_expired_entries_summary">过期条目将被隐藏</string>
<string name="contact">联系我们</string>
<string name="contribution">贡献</string>
<string name="html_about_contribution">为了&lt;strong&gt;持我们的自由&lt;/strong&gt;&lt;strong&gt;修复错误&lt;/strong&gt;&lt;strong&gt;添加功能&lt;/strong&gt;&lt;strong&gt;始终保持活跃&lt;/strong&gt;,我们期待您的 &lt;strong&gt;贡献&lt;/strong&gt;</string>
<string name="html_about_contribution">为了&lt;strong&gt;持我们的自由&lt;/strong&gt;&lt;strong&gt;修复 bugs&lt;/strong&gt;&lt;strong&gt;添加更多功能&lt;/strong&gt;以及&lt;strong&gt;始终保持项目活跃&lt;/strong&gt;,我们期待您的&lt;strong&gt;贡献&lt;/strong&gt;</string>
<string name="auto_focus_search_title">快速搜索</string>
<string name="auto_focus_search_summary">打开数据库时询问是否进行搜索</string>
<string name="remember_database_locations_title">数据库保存的路径</string>
@@ -465,4 +463,11 @@
<string name="hide_broken_locations_title">隐藏已损坏的数据库路径</string>
<string name="hide_broken_locations_summary">在最近的数据库列表中隐藏已损坏的数据库的链接</string>
<string name="warning_database_read_only">授予软件文件读写访问权限以保存数据库更改</string>
<string name="education_setup_OTP_summary">设置一次性密码管理HOTP / TOTP以生成请求的用于双重身份验证2FA的令牌。</string>
<string name="education_setup_OTP_title">设置一次性密码</string>
<string name="discard">丢弃</string>
<string name="error_create_database">无法创建数据库文件。</string>
<string name="entry_add_attachment">添加附件</string>
<string name="discard_changes">放弃更改?</string>
<string name="validate">验证</string>
</resources>

View File

@@ -102,7 +102,6 @@
<string name="never">從不</string>
<string name="no_results">沒有搜索結果</string>
<string name="no_url_handler">沒有這個鏈結的處理程式。</string>
<string name="open_recent">最近打開的資料庫:</string>
<string name="progress_create">創建新資料庫中…</string>
<string name="progress_title">工作中…</string>
<string name="content_description_remove_from_list">移除</string>
@@ -120,7 +119,6 @@
<string name="underline">強調</string>
<string name="unsupported_db_version">不支援的資料庫版本。</string>
<string name="uppercase">大寫</string>
<string name="warning_unmounted">你的SD卡目前尚未安裝在您的設備上。你將無法讀或創建您的資料庫。</string>
<string name="education_unlock_summary">輸入密碼和/或一個密鑰檔來解鎖你的資料庫.</string>
<string-array name="timeout_options">
<item>5秒</item>

View File

@@ -41,6 +41,7 @@
<string name="magic_keyboard_explanation_url" translatable="false">https://github.com/Kunzisoft/KeePassDX/wiki/Magikeyboard</string>
<string name="clipboard_explanation_url" translatable="false">https://github.com/Kunzisoft/KeePassDX/wiki/Clipboard</string>
<string name="autofill_explanation_url" translatable="false">https://github.com/Kunzisoft/KeePassDX/wiki/Autofill</string>
<string name="file_manager_explanation_url" translatable="false">https://github.com/Kunzisoft/KeePassDX/wiki/File-Manager-and-Sync</string>
<string name="html_rose">--,--`--,{@</string>
<!-- File Path -->
@@ -77,6 +78,8 @@
<bool name="lock_database_screen_off_default" translatable="false">true</bool>
<string name="lock_database_back_root_key" translatable="false">lock_database_back_root_key</string>
<bool name="lock_database_back_root_default" translatable="false">false</bool>
<string name="lock_database_show_button_key" translatable="false">lock_database_show_button_key</string>
<bool name="lock_database_show_button_default" translatable="false">true</bool>
<string name="password_length_key" translatable="false">password_length_key</string>
<string name="list_password_generator_options_key" translatable="false">list_password_generator_options_key</string>
<string name="hide_password_key" translatable="false">hide_password_key</string>
@@ -116,6 +119,7 @@
<string name="autofill_explanation_key" translatable="false">autofill_explanation_key</string>
<string name="settings_autofill_enable_key" translatable="false">settings_autofill_enable_key</string>
<bool name="settings_autofill_enable_default" translatable="false">false</bool>
<string name="settings_autofill_key" translatable="false">settings_autofill_key</string>
<string name="keyboard_selection_entry_key" translatable="false">keyboard_selection_entry_key</string>
<bool name="keyboard_selection_entry_default" translatable="false">false</bool>
<string name="keyboard_notification_entry_key" translatable="false">keyboard_notification_entry_key</string>
@@ -130,6 +134,8 @@
<bool name="keyboard_key_vibrate_default" translatable="false">true</bool>
<string name="keyboard_key_sound_key" translatable="false">keyboard_key_sound_key</string>
<bool name="keyboard_key_sound_default" translatable="false">false</bool>
<string name="autofill_auto_search_key" translatable="false">autofill_auto_search_key</string>
<bool name="autofill_auto_search_default" translatable="false">true</bool>
<!-- Advanced Unlock Settings -->
<string name="settings_advanced_unlock_key" translatable="false">settings_advanced_unlock_key</string>

View File

@@ -118,6 +118,7 @@
<string name="error_pass_match">The passwords do not match.</string>
<string name="error_rounds_too_large">\"Transformation rounds\" too high. Setting to 2147483648.</string>
<string name="error_string_key">Each string must have a field name.</string>
<string name="error_label_exists">This label already exists.</string>
<string name="error_wrong_length">Enter a positive whole number in the \"Length\" field.</string>
<string name="error_autofill_enable_service">Could not enable autofill service.</string>
<string name="error_move_folder_in_itself">You can not move a group into itself.</string>
@@ -198,7 +199,6 @@
<string name="no_url_handler">Install a web browser to open this URL.</string>
<string name="select_database_file">Open existing database</string>
<string name="create_keepass_file">Create new database</string>
<string name="open_recent">Recent databases</string>
<string name="omit_backup_search_title">Don\'t search through backup entries</string>
<string name="omit_backup_search_summary">Omits \"Backup\" and \"Recycle bin\" groups from search results</string>
<string name="auto_focus_search_title">Quick search</string>
@@ -253,7 +253,7 @@
<string name="warning">Warning</string>
<string name="warning_password_encoding">Avoid password characters outside of text encoding format in database file (unrecognized chars are converted to the same letter).</string>
<string name="warning_database_read_only">Grant file write access to save database changes</string>
<string name="warning_unmounted">Mount the memory card to create or load a database.</string>
<string name="warning_database_link_revoked">Access to the file revoked by the file manager</string>
<string name="warning_empty_password">Continue without password unlocking protection?</string>
<string name="warning_no_encryption_key">Continue without encryption key?</string>
<string name="warning_permanently_delete_nodes">Permanently delete selected nodes?</string>
@@ -283,6 +283,7 @@
<string name="autofill_sign_in_prompt">Sign in with KeePassDX</string>
<string name="autofill_explanation_summary">Enable autofilling to quickly fill out forms in other apps</string>
<string name="set_autofill_service_title">Set default autofill service</string>
<string name="autofill_preference_title">Autofill settings</string>
<string name="password_size_title">Generated password size</string>
<string name="password_size_summary">Sets default size of the generated passwords</string>
<string name="list_password_generator_options_title">Password characters</string>
@@ -298,6 +299,8 @@
<string name="lock_database_screen_off_summary">Lock the database when the screen is off</string>
<string name="lock_database_back_root_title">Press \'Back\' to lock</string>
<string name="lock_database_back_root_summary">Lock the database when the user clicks the back button on the root screen</string>
<string name="lock_database_show_button_title">Show lock button</string>
<string name="lock_database_show_button_summary">Displays the lock button in the user interface</string>
<string name="advanced_unlock">Advanced unlock</string>
<string name="advanced_unlock_explanation_summary">Use advanced unlocking to open a database more easily</string>
<string name="biometric_unlock_enable_title">Biometric unlocking</string>
@@ -377,6 +380,8 @@
<string name="keyboard_auto_go_action_summary">\"Go\" key action after pressing a \"Field\" key</string>
<string name="keyboard_key_vibrate_title">Vibratory keypresses</string>
<string name="keyboard_key_sound_title">Audible keypresses</string>
<string name="autofill_auto_search_title">Auto search</string>
<string name="autofill_auto_search_summary">Automatically suggest search results from the web domain or applicationId</string>
<string name="allow_no_password_title">Allow no master key</string>
<string name="allow_no_password_summary">Enable the \"Open\" button if no credentials are selected</string>
<string name="delete_entered_password_title">Delete password</string>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX.
KeePassDX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePassDX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<!-- Dark Style -->
<style name="KeepassDXStyle.Black" parent="KeepassDXStyle.Night.v21" >
<item name="colorPrimary">@color/dark</item>
<item name="colorPrimaryDark">@color/black</item>
<item name="colorAccent">@color/orange_dark</item>
<item name="colorAccentLight">@color/orange</item>
<item name="colorControlNormal">@color/colorText</item>
<item name="colorControlActivated">@color/green_darker</item>
<item name="android:textColorPrimary">@color/green</item>
<item name="android:textColorHintInverse">@color/green_light</item>
<item name="android:windowBackground">@color/background_dark</item>
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
<item name="android:alertDialogTheme">@style/KeepassDXStyle.Black.Dialog</item>
<item name="alertDialogTheme">@style/KeepassDXStyle.Black.Dialog</item>
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode.Dark</item>
</style>
<!-- Toolbar Style Black Green -->
<style name="KeepassDXStyle.Toolbar.Black" parent="KeepassDXStyle.Black">
<item name="colorControlNormal">@color/colorTextInverse</item>
<item name="android:textColorPrimary">@color/colorTextInverse</item>
<item name="android:textColorSecondary">@color/colorTextSecondary</item>
<item name="android:editTextColor">@color/colorTextInverse</item>
<item name="android:textColorHint">@color/green_lighter</item>
</style>
<!-- Contextual Action Bar Dark -->
<style name="KeepassDXStyle.ActionMode.Black" parent="@style/Widget.AppCompat.ActionMode">
<item name="background">@color/dark</item>
</style>
<!-- Dialog -->
<style name="KeepassDXStyle.Black.Dialog" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorAccent">@color/orange_dark</item>
<item name="android:textColorPrimary">@color/green_dark</item>
<item name="android:background">@color/black</item>
</style>
</resources>

View File

@@ -134,60 +134,6 @@
<item name="expandedTitleTextAppearance">@style/KeepassDXStyle.Expanded.Title</item>
<item name="collapsedTitleTextAppearance">@style/KeepassDXStyle.Collapsed.Title</item>
</style>
<style name="KeepassDXStyle.Black.v21" parent="Theme.AppCompat">
<item name="android:windowAnimationStyle">@style/KeepassDXStyle.ActivityAnimation</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:buttonStyle">@style/KeepassDXStyle.Button</item>
<item name="buttonStyle">@style/KeepassDXStyle.Button</item>
<item name="android:imageButtonStyle">@style/KeepassDXStyle.ImageButton</item>
<item name="imageButtonStyle">@style/KeepassDXStyle.ImageButton</item>
<item name="android:checkboxStyle">@style/KeepassDXStyle.CheckBox</item>
<item name="colorPrimary">@color/dark</item>
<item name="colorPrimaryDark">@color/black</item>
<item name="colorAccent">@color/orange_dark</item>
<item name="colorAccentLight">@color/orange</item>
<item name="colorControlNormal">@color/colorText</item>
<item name="colorControlActivated">@color/green_darker</item>
<item name="android:textAppearance">@style/KeepassDXStyle.TextAppearance</item>
<item name="android:textAppearanceMedium">@style/KeepassDXStyle.TextAppearance</item>
<item name="android:windowBackground">@color/background_dark</item>
<item name="android:textColor">@color/text_color_night</item>
<item name="android:editTextColor">@color/colorTextInverse</item>
<item name="textColorInverse">@color/colorTextInverse</item>
<item name="android:textColorPrimary">@color/green</item>
<item name="android:textColorPrimaryInverse">@color/colorTextPrimaryInverse</item>
<item name="android:textColorSecondary">@color/text_color_secondary_night</item>
<item name="android:textColorSecondaryInverse">@color/colorTextSecondaryInverse</item>
<item name="android:textColorHint">@color/colorTextSecondary</item>
<item name="android:textColorHintInverse">@color/green_light</item>
<item name="iconPreferenceColor">@color/text_color_secondary_night</item>
<!-- Dialog -->
<item name="android:alertDialogTheme">@style/KeepassDXStyle.Black.Dialog</item>
<item name="alertDialogTheme">@style/KeepassDXStyle.Black.Dialog</item>
<!-- Toolbar -->
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
<item name="toolbarPopupAppearance">@style/KeepassDXStyle.Black.Toolbar.Popup</item>
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode</item>
<!-- CollapsingToolbarLayout -->
<item name="expandedTitleTextAppearance">@style/KeepassDXStyle.Expanded.Title</item>
<item name="collapsedTitleTextAppearance">@style/KeepassDXStyle.Collapsed.Title</item>
</style>
<!-- Light Style -->
<style name="KeepassDXStyle.Light" parent="KeepassDXStyle.Light.v21" />
@@ -203,13 +149,6 @@
<item name="android:colorBackground">@color/background_night</item>
</style>
<!-- Black Style -->
<style name="KeepassDXStyle.Black" parent="KeepassDXStyle.Black.v21" />
<style name="KeepassDXStyle.Black.Toolbar.Popup" parent="Theme.AppCompat">
<item name="android:textColor">@color/colorTextPrimaryInverse</item>
<item name="android:colorBackground">@color/dark</item>
</style>
<!-- Activity Animation -->
<style name="KeepassDXStyle.ActivityAnimation" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/slide_in_right</item>
@@ -236,15 +175,6 @@
<item name="android:textColorHint">@color/green_lighter</item>
</style>
<!-- Toolbar Style Black Green -->
<style name="KeepassDXStyle.Toolbar.Black" parent="KeepassDXStyle.Black.v21">
<item name="colorControlNormal">@color/colorTextInverse</item>
<item name="android:textColorPrimary">@color/colorTextInverse</item>
<item name="android:textColorSecondary">@color/colorTextInverse</item>
<item name="android:editTextColor">@color/colorTextInverse</item>
<item name="android:textColorHint">@color/green_lighter</item>
</style>
<!-- Contextual Action Bar -->
<style name="KeepassDXStyle.ActionMode" parent="@style/Widget.AppCompat.ActionMode">
<item name="background">@color/orange</item>
@@ -265,22 +195,17 @@
<item name="android:textColorPrimary">@color/green</item>
<item name="android:background">@color/background_light</item>
</style>
<style name="KeepassDXStyle.Night.Dialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<style name="KeepassDXStyle.Night.Dialog" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorAccent">@color/orange</item>
<item name="android:textColorPrimary">@color/green</item>
<item name="android:background">@color/background_night</item>
</style>
<style name="KeepassDXStyle.Black.Dialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<item name="colorAccent">@color/orange_dark</item>
<item name="android:textColorPrimary">@color/green_dark</item>
<item name="android:background">@color/black</item>
</style>
<style name="KeepassDXStyle.Light.DateTime.Dialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="colorAccent">@color/orange</item>
<item name="android:textColorPrimary">@color/green_dark</item>
<item name="android:windowBackground">@color/background_light</item>
</style>
<style name="KeepassDXStyle.Night.DateTime.Dialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<style name="KeepassDXStyle.Night.DateTime.Dialog" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorAccent">@color/orange_dark</item>
<item name="android:textColorPrimary">@color/green_light</item>
<item name="android:windowBackground">@color/background_night</item>
@@ -377,6 +302,17 @@
<item name="backgroundTint">?android:attr/windowBackground</item>
</style>
<!-- Special button Style -->
<style name="KeepassDXStyle.Special.Button.Background" parent="KeepassDXStyle.v21.Button">
<item name="android:background">@drawable/btn_special_start_bottom_background</item>
<item name="backgroundTint">@color/background_special_button_color</item>
</style>
<style name="KeepassDXStyle.Special.Button.Stroke" parent="KeepassDXStyle.v21.Button">
<item name="android:background">@drawable/btn_special_start_bottom_stroke</item>
<item name="backgroundTint">?android:attr/textColorPrimary</item>
<item name="backgroundTintMode">src_atop</item>
</style>
<!-- FAB -->
<style name="KeepassDXStyle.v21.Fab" parent="KeepassDXStyle.Light.v21" />
<style name="KeepassDXStyle.Fab" parent="KeepassDXStyle.v21.Fab">

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