Kotlinized preference

This commit is contained in:
J-Jamet
2019-07-17 22:20:07 +02:00
parent 06fcbf8995
commit dcc7c4d39e
19 changed files with 1066 additions and 1127 deletions

View File

@@ -186,6 +186,7 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
when (item?.itemId) {
R.id.menu_sort -> {
context?.let { context ->
val sortDialogFragment: SortDialogFragment
/*
@@ -206,6 +207,7 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
//}
sortDialogFragment.show(childFragmentManager, "sortDialog")
}
return true
}

View File

@@ -92,7 +92,10 @@ class GeneratePasswordDialogFragment : DialogFragment() {
override fun onStopTrackingTouch(seekBar: SeekBar) {}
})
context?.let { context ->
seekBar?.progress = PreferencesUtil.getDefaultPasswordLength(context)
}
root?.findViewById<Button>(R.id.generate_password_button)
?.setOnClickListener { fillPassword() }
@@ -131,8 +134,9 @@ class GeneratePasswordDialogFragment : DialogFragment() {
bracketsBox?.isChecked = false
extendedBox?.isChecked = false
val defaultPasswordChars = PreferencesUtil.getDefaultPasswordCharacters(context)
for (passwordChar in defaultPasswordChars) {
context?.let { context ->
PreferencesUtil.getDefaultPasswordCharacters(context)?.let { charSet ->
for (passwordChar in charSet) {
when (passwordChar) {
getString(R.string.value_password_uppercase) -> uppercaseBox?.isChecked = true
getString(R.string.value_password_lowercase) -> lowercaseBox?.isChecked = true
@@ -146,6 +150,8 @@ class GeneratePasswordDialogFragment : DialogFragment() {
}
}
}
}
}
private fun fillPassword() {
root?.findViewById<EditText>(R.id.password)?.setText(generatePassword())

View File

@@ -124,7 +124,7 @@ public class IconPackChooser {
public static IconPack getSelectedIconPack(Context context) {
build(context);
if (iconPackSelected == null)
setSelectedIconPack(PreferencesUtil.getIconPackSelectedId(context));
setSelectedIconPack(PreferencesUtil.INSTANCE.getIconPackSelectedId(context));
return iconPackSelected;
}

View File

@@ -139,8 +139,8 @@ public class MagikIME extends InputMethodService
}
// Define preferences
keyboardView.setHapticFeedbackEnabled(PreferencesUtil.enableKeyboardVibration(this));
playSoundDuringCLick = PreferencesUtil.enableKeyboardSound(this);
keyboardView.setHapticFeedbackEnabled(PreferencesUtil.INSTANCE.enableKeyboardVibration(this));
playSoundDuringCLick = PreferencesUtil.INSTANCE.enableKeyboardSound(this);
}
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright 2018 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.activities.stylish.StylishActivity;
public class MagikIMESettings extends StylishActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toolbar);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(R.string.keyboard_setting_label);
setSupportActionBar(toolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new MagikIMESettingsFragment())
.commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch ( item.getItemId() ) {
case android.R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
}

View File

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

View File

@@ -1,15 +0,0 @@
package com.kunzisoft.keepass.settings;
import android.os.Bundle;
import android.support.v7.preference.PreferenceFragmentCompat;
import com.kunzisoft.keepass.R;
public class MagikIMESettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
// Load the preferences from an XML resource
setPreferencesFromResource(R.xml.keyboard_preferences, rootKey);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018 Jeremy Jamet / Kunzisoft.
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
@@ -17,21 +17,17 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment.adapter;
package com.kunzisoft.keepass.settings
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.RadioButton;
import android.os.Bundle
import android.support.v7.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.R
public class ListRadioViewHolder extends RecyclerView.ViewHolder {
class MagikIMESettingsFragment : PreferenceFragmentCompat() {
public RadioButton radioButton;
public ListRadioViewHolder(View itemView) {
super(itemView);
radioButton = itemView.findViewById(R.id.pref_dialog_list_radio);
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
// Load the preferences from an XML resource
setPreferencesFromResource(R.xml.keyboard_preferences, rootKey)
}
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright 2018 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.database.element.Database;
public class MainPreferenceFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener {
private Callback mCallback;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Callback) {
mCallback = (Callback) context;
} else {
throw new IllegalStateException("Owner must implement " + Callback.class.getName());
}
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
// add listeners for non-default actions
Preference preference = findPreference(getString(R.string.app_key));
preference.setOnPreferenceClickListener(this);
preference = findPreference(getString(R.string.settings_form_filling_key));
preference.setOnPreferenceClickListener(this);
preference = findPreference(getString(R.string.settings_appearance_key));
preference.setOnPreferenceClickListener(this);
preference = findPreference(getString(R.string.db_key));
preference.setOnPreferenceClickListener(this);
Database db = App.Companion.getCurrentDatabase();
if (!(db.getLoaded())) {
preference.setEnabled(false);
}
}
@Override
public boolean onPreferenceClick(Preference preference) {
// here you should use the same keys as you used in the xml-file
if (preference.getKey().equals(getString(R.string.app_key))) {
mCallback.onNestedPreferenceSelected(NestedSettingsFragment.Screen.APPLICATION);
}
if (preference.getKey().equals(getString(R.string.settings_form_filling_key))) {
mCallback.onNestedPreferenceSelected(NestedSettingsFragment.Screen.FORM_FILLING);
}
if (preference.getKey().equals(getString(R.string.db_key))) {
mCallback.onNestedPreferenceSelected(NestedSettingsFragment.Screen.DATABASE);
}
if (preference.getKey().equals(getString(R.string.settings_appearance_key))) {
mCallback.onNestedPreferenceSelected(NestedSettingsFragment.Screen.APPEARANCE);
}
return false;
}
public interface Callback {
void onNestedPreferenceSelected(NestedSettingsFragment.Screen key);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings
import android.content.Context
import android.os.Bundle
import android.support.v7.preference.Preference
import android.support.v7.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.app.App
class MainPreferenceFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClickListener {
private var mCallback: Callback? = null
override fun onAttach(context: Context?) {
super.onAttach(context)
if (context is Callback) {
mCallback = context
} else {
throw IllegalStateException("Owner must implement " + Callback::class.java.name)
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
// add listeners for non-default actions
var preference = findPreference(getString(R.string.app_key))
preference.onPreferenceClickListener = this
preference = findPreference(getString(R.string.settings_form_filling_key))
preference.onPreferenceClickListener = this
preference = findPreference(getString(R.string.settings_appearance_key))
preference.onPreferenceClickListener = this
preference = findPreference(getString(R.string.db_key))
preference.onPreferenceClickListener = this
if (!App.currentDatabase.loaded) {
preference.isEnabled = false
}
}
override fun onPreferenceClick(preference: Preference): Boolean {
// here you should use the same keys as you used in the xml-file
if (preference.key == getString(R.string.app_key)) {
mCallback?.onNestedPreferenceSelected(NestedSettingsFragment.Screen.APPLICATION)
}
if (preference.key == getString(R.string.settings_form_filling_key)) {
mCallback?.onNestedPreferenceSelected(NestedSettingsFragment.Screen.FORM_FILLING)
}
if (preference.key == getString(R.string.db_key)) {
mCallback?.onNestedPreferenceSelected(NestedSettingsFragment.Screen.DATABASE)
}
if (preference.key == getString(R.string.settings_appearance_key)) {
mCallback?.onNestedPreferenceSelected(NestedSettingsFragment.Screen.APPEARANCE)
}
return false
}
interface Callback {
fun onNestedPreferenceSelected(key: NestedSettingsFragment.Screen)
}
}

View File

@@ -1,568 +0,0 @@
/*
* Copyright 2017 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.hardware.fingerprint.FingerprintManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v14.preference.SwitchPreference;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.util.Log;
import android.view.autofill.AutofillManager;
import android.widget.Toast;
import com.kunzisoft.keepass.BuildConfig;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper;
import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.database.element.Database;
import com.kunzisoft.keepass.activities.dialogs.ProFeatureDialogFragment;
import com.kunzisoft.keepass.activities.dialogs.UnavailableFeatureDialogFragment;
import com.kunzisoft.keepass.activities.dialogs.UnderDevelopmentFeatureDialogFragment;
import com.kunzisoft.keepass.education.Education;
import com.kunzisoft.keepass.fileselect.database.FileDatabaseHistory;
import com.kunzisoft.keepass.fingerprint.FingerPrintHelper;
import com.kunzisoft.keepass.icons.IconPackChooser;
import com.kunzisoft.keepass.activities.dialogs.KeyboardExplanationDialogFragment;
import com.kunzisoft.keepass.settings.preferencedialogfragment.DatabaseDescriptionPreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.settings.preferencedialogfragment.DatabaseEncryptionAlgorithmPreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.settings.preferencedialogfragment.DatabaseKeyDerivationPreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.settings.preferencedialogfragment.DatabaseNamePreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.settings.preferencedialogfragment.MemoryUsagePreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.settings.preferencedialogfragment.ParallelismPreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.settings.preferencedialogfragment.RoundsPreferenceDialogFragmentCompat;
import com.kunzisoft.keepass.activities.stylish.Stylish;
import java.lang.ref.WeakReference;
public class NestedSettingsFragment extends PreferenceFragmentCompat
implements Preference.OnPreferenceClickListener {
public enum Screen {
APPLICATION, FORM_FILLING, DATABASE, APPEARANCE
}
private static final String TAG_KEY = "NESTED_KEY";
private static final int REQUEST_CODE_AUTOFILL = 5201;
private Database database;
private boolean databaseReadOnly;
private int count = 0;
private Preference roundPref;
private Preference memoryPref;
private Preference parallelismPref;
public static NestedSettingsFragment newInstance(Screen key) {
return newInstance(key, ReadOnlyHelper.READ_ONLY_DEFAULT);
}
public static NestedSettingsFragment newInstance(Screen key, boolean databaseReadOnly) {
NestedSettingsFragment fragment = new NestedSettingsFragment();
// supply arguments to bundle.
Bundle args = new Bundle();
args.putInt(TAG_KEY, key.ordinal());
ReadOnlyHelper.INSTANCE.putReadOnlyInBundle(args, databaseReadOnly);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
SwitchPreference autoFillEnablePreference =
(SwitchPreference) findPreference(getString(R.string.settings_autofill_enable_key));
if (autoFillEnablePreference != null) {
AutofillManager autofillManager = getActivity().getSystemService(AutofillManager.class);
if (autofillManager != null && autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference.setChecked(true);
else
autoFillEnablePreference.setChecked(false);
}
}
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
int key = 0;
if (getArguments() != null)
key = getArguments().getInt(TAG_KEY);
database = App.Companion.getCurrentDatabase();
databaseReadOnly = ReadOnlyHelper.INSTANCE.retrieveReadOnlyFromInstanceStateOrArguments(savedInstanceState, getArguments());
databaseReadOnly = database.isReadOnly() || databaseReadOnly;
// Load the preferences from an XML resource
switch (Screen.values()[key]) {
case APPLICATION:
setPreferencesFromResource(R.xml.application_preferences, rootKey);
allowCopyPassword();
Preference keyFile = findPreference(getString(R.string.keyfile_key));
keyFile.setOnPreferenceChangeListener((preference, newValue) -> {
Boolean value = (Boolean) newValue;
if (!value) {
FileDatabaseHistory.Companion.getInstance(new WeakReference<>(getContext().getApplicationContext())).deleteAllKeys();
}
return true;
});
Preference recentHistory = findPreference(getString(R.string.recentfile_key));
recentHistory.setOnPreferenceChangeListener((preference, newValue) -> {
Boolean value = (Boolean) newValue;
if (value == null) {
value = true;
}
if (!value) {
FileDatabaseHistory.Companion.getInstance(new WeakReference<>(getContext().getApplicationContext())).deleteAll();
}
return true;
});
SwitchPreference storageAccessFramework = (SwitchPreference) findPreference(getString(R.string.saf_key));
storageAccessFramework.setOnPreferenceChangeListener((preference, newValue) -> {
Boolean value = (Boolean) newValue;
if (!value && getContext() != null) {
AlertDialog alertDialog = new AlertDialog.Builder(getContext())
.setMessage(getString(R.string.warning_disabling_storage_access_framework)).create();
alertDialog.setButton(AlertDialog.BUTTON1, getText(android.R.string.ok),
(dialog, which) -> {
dialog.dismiss();
});
alertDialog.setButton(AlertDialog.BUTTON2, getText(android.R.string.cancel),
(dialog, which) -> {
storageAccessFramework.setChecked(true);
dialog.dismiss();
});
alertDialog.show();
}
return true;
});
SwitchPreference fingerprintEnablePreference =
(SwitchPreference) findPreference(getString(R.string.fingerprint_enable_key));
// < M solve verifyError exception
boolean fingerprintSupported = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& getActivity() != null)
fingerprintSupported = FingerPrintHelper.isFingerprintSupported(
getActivity().getSystemService(FingerprintManager.class));
if (!fingerprintSupported) {
// False if under Marshmallow
fingerprintEnablePreference.setChecked(false);
fingerprintEnablePreference.setOnPreferenceClickListener(preference -> {
FragmentManager fragmentManager = getFragmentManager();
assert fragmentManager != null;
((SwitchPreference) preference).setChecked(false);
UnavailableFeatureDialogFragment.Companion.getInstance(Build.VERSION_CODES.M)
.show(getFragmentManager(), "unavailableFeatureDialog");
return false;
});
}
Preference deleteKeysFingerprints = findPreference(getString(R.string.fingerprint_delete_all_key));
if (!fingerprintSupported) {
deleteKeysFingerprints.setEnabled(false);
} else {
deleteKeysFingerprints.setOnPreferenceClickListener(preference -> {
new AlertDialog.Builder(getContext())
.setMessage(getResources().getString(R.string.fingerprint_delete_all_warning))
.setIcon(getResources().getDrawable(
android.R.drawable.ic_dialog_alert))
.setPositiveButton(
getResources().getString(android.R.string.yes),
new DialogInterface.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onClick(DialogInterface dialog,
int which) {
FingerPrintHelper.deleteEntryKeyInKeystoreForFingerprints(
getContext(),
new FingerPrintHelper.FingerPrintErrorCallback() {
@Override
public void onInvalidKeyException(Exception e) {}
@Override
public void onFingerPrintException(Exception e) {
Toast.makeText(getContext(),
getString(R.string.fingerprint_error, e.getLocalizedMessage()),
Toast.LENGTH_SHORT).show();
}
});
PreferencesUtil.deleteAllValuesFromNoBackupPreferences(getContext());
}
})
.setNegativeButton(
getResources().getString(android.R.string.no),
(dialog, which) -> {
}).show();
return false;
});
}
break;
case FORM_FILLING:
setPreferencesFromResource(R.xml.form_filling_preferences, rootKey);
SwitchPreference autoFillEnablePreference =
(SwitchPreference) findPreference(getString(R.string.settings_autofill_enable_key));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
assert getActivity() != null;
AutofillManager autofillManager = getActivity().getSystemService(AutofillManager.class);
if (autofillManager != null && autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference.setChecked(autofillManager.hasEnabledAutofillServices());
autoFillEnablePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public boolean onPreferenceClick(Preference preference) {
if (((SwitchPreference) preference).isChecked()) {
try {
startEnableService();
} catch (ActivityNotFoundException e) {
String error = getString(R.string.error_autofill_enable_service);
((SwitchPreference) preference).setChecked(false);
Log.d(getClass().getName(), error, e);
Toast.makeText(getContext(), error, Toast.LENGTH_SHORT).show();
}
} else {
disableService();
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void disableService() {
if (autofillManager != null && autofillManager.hasEnabledAutofillServices()) {
autofillManager.disableAutofillServices();
} else {
Log.d(getClass().getName(), "Sample service already disabled.");
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void startEnableService() throws ActivityNotFoundException{
if (autofillManager != null && !autofillManager.hasEnabledAutofillServices()) {
Intent intent = new Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE);
intent.setData(Uri.parse("package:com.example.android.autofill.service"));
Log.d(getClass().getName(), "enableService(): intent=" + intent);
startActivityForResult(intent, REQUEST_CODE_AUTOFILL);
} else {
Log.d(getClass().getName(), "Sample service already enabled.");
}
}
});
} else {
autoFillEnablePreference.setOnPreferenceClickListener(preference -> {
((SwitchPreference) preference).setChecked(false);
FragmentManager fragmentManager = getFragmentManager();
assert fragmentManager != null;
UnavailableFeatureDialogFragment.Companion.getInstance(Build.VERSION_CODES.O)
.show(fragmentManager, "unavailableFeatureDialog");
return false;
});
}
Preference keyboardPreference = findPreference(getString(R.string.magic_keyboard_key));
keyboardPreference.setOnPreferenceClickListener(preference -> {
if (getFragmentManager() != null) {
KeyboardExplanationDialogFragment keyboardDialog = new KeyboardExplanationDialogFragment();
keyboardDialog.show(getFragmentManager(), "keyboardExplanationDialog");
}
return false;
});
Preference keyboardSubPreference = findPreference(getString(R.string.magic_keyboard_preference_key));
keyboardSubPreference.setOnPreferenceClickListener(preference -> {
startActivity(new Intent(getContext(), MagikIMESettings.class));
return false;
});
// Present in two places
allowCopyPassword();
break;
case DATABASE:
setPreferencesFromResource(R.xml.database_preferences, rootKey);
if (database.getLoaded()) {
PreferenceCategory dbGeneralPrefCategory = (PreferenceCategory) findPreference(getString(R.string.database_general_key));
// Db name
Preference dbNamePref = findPreference(getString(R.string.database_name_key));
if ( database.containsName() ) {
dbNamePref.setSummary(database.getName());
} else {
dbGeneralPrefCategory.removePreference(dbNamePref);
}
// Db description
Preference dbDescriptionPref = findPreference(getString(R.string.database_description_key));
if ( database.containsDescription() ) {
dbDescriptionPref.setSummary(database.getDescription());
} else {
dbGeneralPrefCategory.removePreference(dbDescriptionPref);
}
// Recycle bin
SwitchPreference recycleBinPref = (SwitchPreference) findPreference(getString(R.string.recycle_bin_key));
// TODO Recycle
dbGeneralPrefCategory.removePreference(recycleBinPref); // To delete
if (database.isRecycleBinAvailable()) {
recycleBinPref.setChecked(database.isRecycleBinEnabled());
recycleBinPref.setEnabled(false);
} else {
dbGeneralPrefCategory.removePreference(recycleBinPref);
}
// Version
Preference dbVersionPref = findPreference(getString(R.string.database_version_key));
dbVersionPref.setSummary(database.getVersion());
// Encryption Algorithm
Preference algorithmPref = findPreference(getString(R.string.encryption_algorithm_key));
algorithmPref.setSummary(database.getEncryptionAlgorithmName(getResources()));
// Key derivation function
Preference kdfPref = findPreference(getString(R.string.key_derivation_function_key));
kdfPref.setSummary(database.getKeyDerivationName(getResources()));
// Round encryption
roundPref = findPreference(getString(R.string.transform_rounds_key));
roundPref.setSummary(database.getNumberKeyEncryptionRoundsAsString());
// Memory Usage
memoryPref = findPreference(getString(R.string.memory_usage_key));
memoryPref.setSummary(database.getMemoryUsageAsString());
// Parallelism
parallelismPref = findPreference(getString(R.string.parallelism_key));
parallelismPref.setSummary(database.getParallelismAsString());
} else {
Log.e(getClass().getName(), "Database isn't ready");
}
break;
case APPEARANCE:
setPreferencesFromResource(R.xml.appearance_preferences, rootKey);
Preference stylePreference = findPreference(getString(R.string.setting_style_key));
stylePreference.setOnPreferenceChangeListener((preference, newValue) -> {
String styleIdString = (String) newValue;
if (!(!BuildConfig.CLOSED_STORE && Education.Companion.isEducationScreenReclickedPerformed(getContext())))
for (String themeIdDisabled : BuildConfig.STYLES_DISABLED) {
if (themeIdDisabled.equals(styleIdString)) {
ProFeatureDialogFragment dialogFragment = new ProFeatureDialogFragment();
if (getFragmentManager() != null)
dialogFragment.show(getFragmentManager(), "pro_feature_dialog");
return false;
}
}
Stylish.assignStyle(styleIdString);
if (getActivity() != null)
getActivity().recreate();
return true;
});
Preference iconPackPreference = findPreference(getString(R.string.setting_icon_pack_choose_key));
iconPackPreference.setOnPreferenceChangeListener((preference, newValue) -> {
String iconPackId = (String) newValue;
if (!(!BuildConfig.CLOSED_STORE && Education.Companion.isEducationScreenReclickedPerformed(getContext())))
for (String iconPackIdDisabled : BuildConfig.ICON_PACKS_DISABLED) {
if (iconPackIdDisabled.equals(iconPackId)) {
ProFeatureDialogFragment dialogFragment = new ProFeatureDialogFragment();
if (getFragmentManager() != null)
dialogFragment.show(getFragmentManager(), "pro_feature_dialog");
return false;
}
}
IconPackChooser.setSelectedIconPack(iconPackId);
return true;
});
Preference resetEducationScreens = findPreference(getString(R.string.reset_education_screens_key));
resetEducationScreens.setOnPreferenceClickListener(preference -> {
// To allow only one toast
if (count == 0) {
SharedPreferences sharedPreferences = Education.Companion.getEducationSharedPreferences(getContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
for (int resourceId : Education.Companion.getEducationResourcesKeys()) {
editor.putBoolean(getString(resourceId), false);
}
editor.apply();
Toast.makeText(getContext(), R.string.reset_education_screens_text, Toast.LENGTH_SHORT).show();
}
count++;
return false;
});
break;
default:
break;
}
}
private void allowCopyPassword() {
SwitchPreference copyPasswordPreference = (SwitchPreference) findPreference(getString(R.string.allow_copy_password_key));
copyPasswordPreference.setOnPreferenceChangeListener((preference, newValue) -> {
if ((Boolean) newValue && getContext() != null) {
String message = getString(R.string.allow_copy_password_warning) +
"\n\n" +
getString(R.string.clipboard_warning);
AlertDialog warningDialog = new AlertDialog.Builder(getContext())
.setMessage(message).create();
warningDialog.setButton(AlertDialog.BUTTON1, getText(android.R.string.ok),
(dialog, which) -> dialog.dismiss());
warningDialog.setButton(AlertDialog.BUTTON2, getText(android.R.string.cancel),
(dialog, which) -> {
copyPasswordPreference.setChecked(false);
dialog.dismiss();
});
warningDialog.show();
}
return true;
});
}
private void preferenceInDevelopment(Preference preferenceInDev) {
preferenceInDev.setOnPreferenceClickListener(preference -> {
FragmentManager fragmentManager = getFragmentManager();
assert fragmentManager != null;
try { // don't check if we can
((SwitchPreference) preference).setChecked(false);
} catch (Exception ignored) {}
new UnderDevelopmentFeatureDialogFragment().show(getFragmentManager(), "underDevFeatureDialog");
return false;
});
}
@Override
public void onStop() {
super.onStop();
if(count==10) {
if (getActivity()!=null)
Education.Companion.getEducationSharedPreferences(getActivity()).edit()
.putBoolean(getString(R.string.education_screen_reclicked_key), true).apply();
}
}
@Override
public void onDisplayPreferenceDialog(Preference preference) {
assert getFragmentManager() != null;
boolean otherDialogFragment = false;
DialogFragment dialogFragment = null;
if (preference.getKey().equals(getString(R.string.database_name_key))) {
dialogFragment = DatabaseNamePreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
} else if (preference.getKey().equals(getString(R.string.database_description_key))) {
dialogFragment = DatabaseDescriptionPreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
} else if (preference.getKey().equals(getString(R.string.encryption_algorithm_key))) {
dialogFragment = DatabaseEncryptionAlgorithmPreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
} else if (preference.getKey().equals(getString(R.string.key_derivation_function_key))) {
DatabaseKeyDerivationPreferenceDialogFragmentCompat keyDerivationDialogFragment = DatabaseKeyDerivationPreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
// Add other prefs to manage
if (roundPref != null)
keyDerivationDialogFragment.setRoundPreference(roundPref);
if (memoryPref != null)
keyDerivationDialogFragment.setMemoryPreference(memoryPref);
if (parallelismPref != null)
keyDerivationDialogFragment.setParallelismPreference(parallelismPref);
dialogFragment = keyDerivationDialogFragment;
} else if (preference.getKey().equals(getString(R.string.transform_rounds_key))) {
dialogFragment = RoundsPreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
} else if (preference.getKey().equals(getString(R.string.memory_usage_key))) {
dialogFragment = MemoryUsagePreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
} else if (preference.getKey().equals(getString(R.string.parallelism_key))) {
dialogFragment = ParallelismPreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());
} else {
otherDialogFragment = true;
}
if (dialogFragment != null && !databaseReadOnly) {
dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(getFragmentManager(), null);
}
// Could not be handled here. Try with the super method.
else if (otherDialogFragment) {
super.onDisplayPreferenceDialog(preference);
}
}
public static String retrieveTitle(Resources resources, Screen key) {
switch (key) {
case APPLICATION:
return resources.getString(R.string.menu_app_settings);
case FORM_FILLING:
return resources.getString(R.string.menu_form_filling_settings);
case DATABASE:
return resources.getString(R.string.menu_db_settings);
case APPEARANCE:
return resources.getString(R.string.appearance);
default:
return resources.getString(R.string.settings);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
ReadOnlyHelper.INSTANCE.onSaveInstanceState(outState, databaseReadOnly);
super.onSaveInstanceState(outState);
}
@Override
public boolean onPreferenceClick(Preference preference) {
// TODO encapsulate
return false;
}
}

View File

@@ -0,0 +1,542 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.res.Resources
import android.hardware.fingerprint.FingerprintManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.support.annotation.RequiresApi
import android.support.v14.preference.SwitchPreference
import android.support.v4.app.DialogFragment
import android.support.v7.app.AlertDialog
import android.support.v7.preference.Preference
import android.support.v7.preference.PreferenceCategory
import android.support.v7.preference.PreferenceFragmentCompat
import android.util.Log
import android.view.autofill.AutofillManager
import android.widget.Toast
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.KeyboardExplanationDialogFragment
import com.kunzisoft.keepass.activities.dialogs.ProFeatureDialogFragment
import com.kunzisoft.keepass.activities.dialogs.UnavailableFeatureDialogFragment
import com.kunzisoft.keepass.activities.dialogs.UnderDevelopmentFeatureDialogFragment
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.stylish.Stylish
import com.kunzisoft.keepass.app.App
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.education.Education
import com.kunzisoft.keepass.fileselect.database.FileDatabaseHistory
import com.kunzisoft.keepass.fingerprint.FingerPrintHelper
import com.kunzisoft.keepass.icons.IconPackChooser
import com.kunzisoft.keepass.settings.preferencedialogfragment.*
import java.lang.ref.WeakReference
class NestedSettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClickListener {
private var database: Database = App.currentDatabase
private var databaseReadOnly: Boolean = false
private var count = 0
private var roundPref: Preference? = null
private var memoryPref: Preference? = null
private var parallelismPref: Preference? = null
enum class Screen {
APPLICATION, FORM_FILLING, DATABASE, APPEARANCE
}
override fun onResume() {
super.onResume()
activity?.let { activity ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val autoFillEnablePreference = findPreference(getString(R.string.settings_autofill_enable_key)) as SwitchPreference?
if (autoFillEnablePreference != null) {
val autofillManager = activity.getSystemService(AutofillManager::class.java)
autoFillEnablePreference.isChecked = autofillManager != null
&& autofillManager.hasEnabledAutofillServices()
}
}
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
var key = 0
if (arguments != null)
key = arguments!!.getInt(TAG_KEY)
databaseReadOnly = database.isReadOnly
|| ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrArguments(savedInstanceState, arguments)
// Load the preferences from an XML resource
when (Screen.values()[key]) {
Screen.APPLICATION -> {
onCreateApplicationPreferences(rootKey)
}
Screen.FORM_FILLING -> {
onCreateFormFillingPreference(rootKey)
}
Screen.APPEARANCE -> {
onCreateAppearancePreferences(rootKey)
}
Screen.DATABASE -> {
onCreateDatabasePreference(rootKey)
}
}
}
private fun onCreateApplicationPreferences(rootKey: String?) {
setPreferencesFromResource(R.xml.application_preferences, rootKey)
activity?.let { activity ->
allowCopyPassword()
val keyFile = findPreference(getString(R.string.keyfile_key))
keyFile.setOnPreferenceChangeListener { _, newValue ->
if (!(newValue as Boolean)) {
FileDatabaseHistory.getInstance(WeakReference(activity.applicationContext)).deleteAllKeys()
}
true
}
val recentHistory = findPreference(getString(R.string.recentfile_key))
recentHistory.setOnPreferenceChangeListener { _, newValue ->
if (!(newValue as Boolean)) {
FileDatabaseHistory.getInstance(WeakReference(activity.applicationContext)).deleteAll()
}
true
}
val storageAccessFramework = findPreference(getString(R.string.saf_key)) as SwitchPreference
storageAccessFramework.setOnPreferenceChangeListener { _, newValue ->
if (!(newValue as Boolean) && context != null) {
val alertDialog = AlertDialog.Builder(context!!)
.setMessage(getString(R.string.warning_disabling_storage_access_framework)).create()
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, getText(android.R.string.ok)
) { dialog, _ -> dialog.dismiss() }
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, getText(android.R.string.cancel)
) { dialog, _ ->
storageAccessFramework.isChecked = true
dialog.dismiss()
}
alertDialog.show()
}
true
}
val fingerprintEnablePreference = findPreference(getString(R.string.fingerprint_enable_key)) as SwitchPreference
// < M solve verifyError exception
var fingerprintSupported = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
fingerprintSupported = FingerPrintHelper.isFingerprintSupported(
activity.getSystemService(FingerprintManager::class.java))
if (!fingerprintSupported) {
// False if under Marshmallow
fingerprintEnablePreference.isChecked = false
fingerprintEnablePreference.setOnPreferenceClickListener { preference ->
fragmentManager?.let { fragmentManager ->
(preference as SwitchPreference).isChecked = false
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M)
.show(fragmentManager, "unavailableFeatureDialog")
}
false
}
}
val deleteKeysFingerprints = findPreference(getString(R.string.fingerprint_delete_all_key))
if (!fingerprintSupported) {
deleteKeysFingerprints.isEnabled = false
} else {
deleteKeysFingerprints.setOnPreferenceClickListener {
if (context != null) {
AlertDialog.Builder(context!!)
.setMessage(resources.getString(R.string.fingerprint_delete_all_warning))
.setIcon(resources.getDrawable(
android.R.drawable.ic_dialog_alert))
.setPositiveButton(resources.getString(android.R.string.yes)
) { _, _ ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
FingerPrintHelper.deleteEntryKeyInKeystoreForFingerprints(
context,
object : FingerPrintHelper.FingerPrintErrorCallback {
override fun onInvalidKeyException(e: Exception) {}
override fun onFingerPrintException(e: Exception) {
Toast.makeText(context,
getString(R.string.fingerprint_error, e.localizedMessage),
Toast.LENGTH_SHORT).show()
}
})
}
PreferencesUtil.deleteAllValuesFromNoBackupPreferences(context!!)
}
.setNegativeButton(resources.getString(android.R.string.no))
{ _, _ -> }.show()
}
false
}
}
}
}
private fun onCreateFormFillingPreference(rootKey: String?) {
setPreferencesFromResource(R.xml.form_filling_preferences, rootKey)
activity?.let { activity ->
val autoFillEnablePreference = findPreference(getString(R.string.settings_autofill_enable_key)) as SwitchPreference
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val autofillManager = activity.getSystemService(AutofillManager::class.java)
if (autofillManager != null && autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference.isChecked = autofillManager.hasEnabledAutofillServices()
autoFillEnablePreference.onPreferenceClickListener = object : Preference.OnPreferenceClickListener {
@RequiresApi(api = Build.VERSION_CODES.O)
override fun onPreferenceClick(preference: Preference): Boolean {
if ((preference as SwitchPreference).isChecked) {
try {
startEnableService()
} catch (e: ActivityNotFoundException) {
val error = getString(R.string.error_autofill_enable_service)
preference.isChecked = false
Log.d(javaClass.name, error, e)
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
}
} else {
disableService()
}
return false
}
@RequiresApi(api = Build.VERSION_CODES.O)
private fun disableService() {
if (autofillManager != null && autofillManager.hasEnabledAutofillServices()) {
autofillManager.disableAutofillServices()
} else {
Log.d(javaClass.name, "Sample service already disabled.")
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Throws(ActivityNotFoundException::class)
private fun startEnableService() {
if (autofillManager != null && !autofillManager.hasEnabledAutofillServices()) {
val intent = Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
intent.data = Uri.parse("package:com.example.android.autofill.service")
Log.d(javaClass.name, "enableService(): intent=$intent")
startActivityForResult(intent, REQUEST_CODE_AUTOFILL)
} else {
Log.d(javaClass.name, "Sample service already enabled.")
}
}
}
} else {
autoFillEnablePreference.setOnPreferenceClickListener { preference ->
(preference as SwitchPreference).isChecked = false
val fragmentManager = fragmentManager!!
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.O)
.show(fragmentManager, "unavailableFeatureDialog")
false
}
}
}
val keyboardPreference = findPreference(getString(R.string.magic_keyboard_key))
keyboardPreference.setOnPreferenceClickListener {
if (fragmentManager != null) {
KeyboardExplanationDialogFragment().show(fragmentManager!!, "keyboardExplanationDialog")
}
false
}
val keyboardSubPreference = findPreference(getString(R.string.magic_keyboard_preference_key))
keyboardSubPreference.setOnPreferenceClickListener {
startActivity(Intent(context, MagikIMESettings::class.java))
false
}
// Present in two places
allowCopyPassword()
}
private fun onCreateAppearancePreferences(rootKey: String?) {
setPreferencesFromResource(R.xml.appearance_preferences, rootKey)
activity?.let { activity ->
val stylePreference = findPreference(getString(R.string.setting_style_key))
stylePreference.setOnPreferenceChangeListener { _, newValue ->
val styleIdString = newValue as String
if (!(!BuildConfig.CLOSED_STORE && Education.isEducationScreenReclickedPerformed(context!!)))
for (themeIdDisabled in BuildConfig.STYLES_DISABLED) {
if (themeIdDisabled == styleIdString) {
if (fragmentManager != null)
ProFeatureDialogFragment().show(fragmentManager!!, "pro_feature_dialog")
}
}
Stylish.assignStyle(styleIdString)
activity.recreate()
true
}
val iconPackPreference = findPreference(getString(R.string.setting_icon_pack_choose_key))
iconPackPreference.setOnPreferenceChangeListener { _, newValue ->
val iconPackId = newValue as String
if (!(!BuildConfig.CLOSED_STORE && Education.isEducationScreenReclickedPerformed(context!!)))
for (iconPackIdDisabled in BuildConfig.ICON_PACKS_DISABLED) {
if (iconPackIdDisabled == iconPackId) {
if (fragmentManager != null)
ProFeatureDialogFragment().show(fragmentManager!!, "pro_feature_dialog")
}
}
IconPackChooser.setSelectedIconPack(iconPackId)
true
}
val resetEducationScreens = findPreference(getString(R.string.reset_education_screens_key))
resetEducationScreens.setOnPreferenceClickListener {
// To allow only one toast
if (count == 0) {
val sharedPreferences = Education.getEducationSharedPreferences(context!!)
val editor = sharedPreferences.edit()
for (resourceId in Education.educationResourcesKeys) {
editor.putBoolean(getString(resourceId), false)
}
editor.apply()
Toast.makeText(context, R.string.reset_education_screens_text, Toast.LENGTH_SHORT).show()
}
count++
false
}
}
}
private fun onCreateDatabasePreference(rootKey: String?) {
setPreferencesFromResource(R.xml.database_preferences, rootKey)
if (database.loaded) {
val dbGeneralPrefCategory = findPreference(getString(R.string.database_general_key)) as PreferenceCategory
// Db name
val dbNamePref = findPreference(getString(R.string.database_name_key))
if (database.containsName()) {
dbNamePref.summary = database.name
} else {
dbGeneralPrefCategory.removePreference(dbNamePref)
}
// Db description
val dbDescriptionPref = findPreference(getString(R.string.database_description_key))
if (database.containsDescription()) {
dbDescriptionPref.summary = database.description
} else {
dbGeneralPrefCategory.removePreference(dbDescriptionPref)
}
// Recycle bin
val recycleBinPref = findPreference(getString(R.string.recycle_bin_key)) as SwitchPreference
// TODO Recycle
dbGeneralPrefCategory.removePreference(recycleBinPref) // To delete
if (database.isRecycleBinAvailable) {
recycleBinPref.isChecked = database.isRecycleBinEnabled
recycleBinPref.isEnabled = false
} else {
dbGeneralPrefCategory.removePreference(recycleBinPref)
}
// Version
val dbVersionPref = findPreference(getString(R.string.database_version_key))
dbVersionPref.summary = database.getVersion()
// Encryption Algorithm
val algorithmPref = findPreference(getString(R.string.encryption_algorithm_key))
algorithmPref.summary = database.getEncryptionAlgorithmName(resources)
// Key derivation function
val kdfPref = findPreference(getString(R.string.key_derivation_function_key))
kdfPref.summary = database.getKeyDerivationName(resources)
// Round encryption
roundPref = findPreference(getString(R.string.transform_rounds_key))
roundPref?.summary = database.numberKeyEncryptionRoundsAsString
// Memory Usage
memoryPref = findPreference(getString(R.string.memory_usage_key))
memoryPref?.summary = database.memoryUsageAsString
// Parallelism
parallelismPref = findPreference(getString(R.string.parallelism_key))
parallelismPref?.summary = database.parallelismAsString
} else {
Log.e(javaClass.name, "Database isn't ready")
}
}
private fun allowCopyPassword() {
val copyPasswordPreference = findPreference(getString(R.string.allow_copy_password_key)) as SwitchPreference
copyPasswordPreference.setOnPreferenceChangeListener { _, newValue ->
if (newValue as Boolean && context != null) {
val message = getString(R.string.allow_copy_password_warning) +
"\n\n" +
getString(R.string.clipboard_warning)
AlertDialog
.Builder(context!!)
.setMessage(message)
.create()
.apply {
setButton(AlertDialog.BUTTON_POSITIVE, getText(android.R.string.ok))
{ dialog, _ ->
dialog.dismiss()
}
setButton(AlertDialog.BUTTON_NEGATIVE, getText(android.R.string.cancel))
{ dialog, _ ->
copyPasswordPreference.isChecked = false
dialog.dismiss()
}
show()
}
}
true
}
}
private fun preferenceInDevelopment(preferenceInDev: Preference) {
preferenceInDev.setOnPreferenceClickListener { preference ->
fragmentManager?.let { fragmentManager ->
try { // don't check if we can
(preference as SwitchPreference).isChecked = false
} catch (ignored: Exception) {
}
UnderDevelopmentFeatureDialogFragment().show(fragmentManager, "underDevFeatureDialog")
}
false
}
}
override fun onStop() {
super.onStop()
activity?.let { activity ->
if (count == 10) {
Education.getEducationSharedPreferences(activity).edit()
.putBoolean(getString(R.string.education_screen_reclicked_key), true).apply()
}
}
}
override fun onDisplayPreferenceDialog(preference: Preference?) {
var otherDialogFragment = false
fragmentManager?.let { fragmentManager ->
preference?.let { preference ->
var dialogFragment: DialogFragment? = null
when {
preference.key == getString(R.string.database_name_key) -> {
dialogFragment = DatabaseNamePreferenceDialogFragmentCompat.newInstance(preference.key)
}
preference.key == getString(R.string.database_description_key) -> {
dialogFragment = DatabaseDescriptionPreferenceDialogFragmentCompat.newInstance(preference.key)
}
preference.key == getString(R.string.encryption_algorithm_key) -> {
dialogFragment = DatabaseEncryptionAlgorithmPreferenceDialogFragmentCompat.newInstance(preference.key)
}
preference.key == getString(R.string.key_derivation_function_key) -> {
val keyDerivationDialogFragment = DatabaseKeyDerivationPreferenceDialogFragmentCompat.newInstance(preference.key)
// Add other prefs to manage
if (roundPref != null)
keyDerivationDialogFragment.setRoundPreference(roundPref!!)
if (memoryPref != null)
keyDerivationDialogFragment.setMemoryPreference(memoryPref!!)
if (parallelismPref != null)
keyDerivationDialogFragment.setParallelismPreference(parallelismPref!!)
dialogFragment = keyDerivationDialogFragment
}
preference.key == getString(R.string.transform_rounds_key) -> {
dialogFragment = RoundsPreferenceDialogFragmentCompat.newInstance(preference.key)
}
preference.key == getString(R.string.memory_usage_key) -> {
dialogFragment = MemoryUsagePreferenceDialogFragmentCompat.newInstance(preference.key)
}
preference.key == getString(R.string.parallelism_key) -> {
dialogFragment = ParallelismPreferenceDialogFragmentCompat.newInstance(preference.key)
}
else -> otherDialogFragment = true
}
if (dialogFragment != null && !databaseReadOnly) {
dialogFragment.setTargetFragment(this, 0)
dialogFragment.show(fragmentManager, null)
}
// Could not be handled here. Try with the super method.
else if (otherDialogFragment) {
super.onDisplayPreferenceDialog(preference)
}
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
ReadOnlyHelper.onSaveInstanceState(outState, databaseReadOnly)
super.onSaveInstanceState(outState)
}
override fun onPreferenceClick(preference: Preference?): Boolean {
// TODO encapsulate
return false
}
companion object {
private const val TAG_KEY = "NESTED_KEY"
private const val REQUEST_CODE_AUTOFILL = 5201
@JvmOverloads
fun newInstance(key: Screen, databaseReadOnly: Boolean = ReadOnlyHelper.READ_ONLY_DEFAULT)
: NestedSettingsFragment {
val fragment = NestedSettingsFragment()
// supply arguments to bundle.
val args = Bundle()
args.putInt(TAG_KEY, key.ordinal)
ReadOnlyHelper.putReadOnlyInBundle(args, databaseReadOnly)
fragment.arguments = args
return fragment
}
fun retrieveTitle(resources: Resources, key: Screen): String {
return when (key) {
Screen.APPLICATION -> resources.getString(R.string.menu_app_settings)
Screen.FORM_FILLING -> resources.getString(R.string.menu_form_filling_settings)
Screen.DATABASE -> resources.getString(R.string.menu_db_settings)
Screen.APPEARANCE -> resources.getString(R.string.appearance)
}
}
}
}

View File

@@ -1,216 +0,0 @@
/*
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.database.SortNodeEnum;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class PreferencesUtil {
private static final String NO_BACKUP_PREFERENCE_FILE_NAME = "nobackup";
public static SharedPreferences getNoBackupSharedPreferences(Context ctx) {
return ctx.getSharedPreferences(
PreferencesUtil.NO_BACKUP_PREFERENCE_FILE_NAME,
Context.MODE_PRIVATE);
}
public static void deleteAllValuesFromNoBackupPreferences(Context ctx) {
SharedPreferences prefsNoBackup = getNoBackupSharedPreferences(ctx);
SharedPreferences.Editor sharedPreferencesEditor = prefsNoBackup.edit();
sharedPreferencesEditor.clear();
sharedPreferencesEditor.apply();
}
public static boolean omitBackup(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.omitbackup_key),
context.getResources().getBoolean(R.bool.omitbackup_default));
}
public static boolean showUsernamesListEntries(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.list_entries_show_username_key),
context.getResources().getBoolean(R.bool.list_entries_show_username_default));
}
/**
* Retrieve the text size in SP, verify the integrity of the size stored in preference
*/
public static float getListTextSize(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
String defaultSizeString = ctx.getString(R.string.list_size_default);
String listSize = prefs.getString(ctx.getString(R.string.list_size_key), defaultSizeString);
if (!Arrays.asList(ctx.getResources().getStringArray(R.array.list_size_values)).contains(listSize))
listSize = defaultSizeString;
return Float.parseFloat(listSize);
}
public static int getDefaultPasswordLength(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getInt(ctx.getString(R.string.password_length_key),
Integer.parseInt(ctx.getString(R.string.default_password_length)));
}
public static Set<String> getDefaultPasswordCharacters(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getStringSet(ctx.getString(R.string.list_password_generator_options_key),
new HashSet<>(Arrays.asList(
ctx.getResources()
.getStringArray(R.array.list_password_generator_options_default_values))));
}
public static boolean isClipboardNotificationsEnable(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.clipboard_notifications_key),
ctx.getResources().getBoolean(R.bool.clipboard_notifications_default));
}
public static boolean isLockDatabaseWhenScreenShutOffEnable(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.lock_database_screen_off_key),
ctx.getResources().getBoolean(R.bool.lock_database_screen_off_default));
}
public static boolean isLockDatabaseWhenBackButtonOnRootClicked(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.lock_database_back_root_key),
ctx.getResources().getBoolean(R.bool.lock_database_back_root_default));
}
public static boolean isFingerprintEnable(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.fingerprint_enable_key),
ctx.getResources().getBoolean(R.bool.fingerprint_enable_default));
}
public static boolean isFullFilePathEnable(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.full_file_path_enable_key),
ctx.getResources().getBoolean(R.bool.full_file_path_enable_default));
}
public static SortNodeEnum getListSort(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return SortNodeEnum.valueOf(prefs.getString(ctx.getString(R.string.sort_node_key),
SortNodeEnum.TITLE.name()));
}
public static boolean getGroupsBeforeSort(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.sort_group_before_key),
ctx.getResources().getBoolean(R.bool.sort_group_before_default));
}
public static boolean getAscendingSort(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.sort_ascending_key),
ctx.getResources().getBoolean(R.bool.sort_ascending_default));
}
public static boolean getRecycleBinBottomSort(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.sort_recycle_bin_bottom_key),
ctx.getResources().getBoolean(R.bool.sort_recycle_bin_bottom_default));
}
public static boolean isPasswordMask(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.maskpass_key),
ctx.getResources().getBoolean(R.bool.maskpass_default));
}
public static boolean fieldFontIsInVisibility(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.monospace_font_fields_enable_key),
ctx.getResources().getBoolean(R.bool.monospace_font_fields_enable_default));
}
public static boolean autoOpenSelectedFile(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.auto_open_file_uri_key),
ctx.getResources().getBoolean(R.bool.auto_open_file_uri_default));
}
public static boolean isFirstTimeAskAllowCopyPasswordAndProtectedFields(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.allow_copy_password_first_time_key),
ctx.getResources().getBoolean(R.bool.allow_copy_password_first_time_default));
}
public static boolean allowCopyPasswordAndProtectedFields(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.allow_copy_password_key),
ctx.getResources().getBoolean(R.bool.allow_copy_password_default));
}
public static void setAllowCopyPasswordAndProtectedFields(Context ctx, boolean allowCopy) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
prefs.edit()
.putBoolean(ctx.getString(R.string.allow_copy_password_first_time_key), false)
.putBoolean(ctx.getString(R.string.allow_copy_password_key), allowCopy)
.apply();
}
public static String getIconPackSelectedId(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getString(
context.getString(R.string.setting_icon_pack_choose_key),
context.getString(R.string.setting_icon_pack_choose_default));
}
public static boolean emptyPasswordAllowed(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.allow_no_password_key),
context.getResources().getBoolean(R.bool.allow_no_password_default));
}
public static boolean enableReadOnlyDatabase(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.enable_read_only_key),
context.getResources().getBoolean(R.bool.enable_read_only_default));
}
public static boolean enableKeyboardNotificationEntry(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.keyboard_notification_entry_key),
context.getResources().getBoolean(R.bool.keyboard_notification_entry_default));
}
public static boolean enableKeyboardVibration(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.keyboard_key_vibrate_key),
context.getResources().getBoolean(R.bool.keyboard_key_vibrate_default));
}
public static boolean enableKeyboardSound(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.keyboard_key_sound_key),
context.getResources().getBoolean(R.bool.keyboard_key_sound_default));
}
}

View File

@@ -0,0 +1,214 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings
import android.content.Context
import android.content.SharedPreferences
import android.preference.PreferenceManager
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.SortNodeEnum
import java.util.*
object PreferencesUtil {
private const val NO_BACKUP_PREFERENCE_FILE_NAME = "nobackup"
fun getNoBackupSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences(
NO_BACKUP_PREFERENCE_FILE_NAME,
Context.MODE_PRIVATE)
}
fun deleteAllValuesFromNoBackupPreferences(context: Context) {
val prefsNoBackup = getNoBackupSharedPreferences(context)
val sharedPreferencesEditor = prefsNoBackup.edit()
sharedPreferencesEditor.clear()
sharedPreferencesEditor.apply()
}
fun omitBackup(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.omitbackup_key),
context.resources.getBoolean(R.bool.omitbackup_default))
}
fun showUsernamesListEntries(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.list_entries_show_username_key),
context.resources.getBoolean(R.bool.list_entries_show_username_default))
}
/**
* Retrieve the text size in SP, verify the integrity of the size stored in preference
*/
fun getListTextSize(context: Context): Float {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val defaultSizeString = context.getString(R.string.list_size_default)
var listSize = prefs.getString(context.getString(R.string.list_size_key), defaultSizeString)
if (!listOf(*context.resources.getStringArray(R.array.list_size_values)).contains(listSize))
listSize = defaultSizeString
return java.lang.Float.parseFloat(listSize)
}
fun getDefaultPasswordLength(context: Context): Int {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getInt(context.getString(R.string.password_length_key),
Integer.parseInt(context.getString(R.string.default_password_length)))
}
fun getDefaultPasswordCharacters(context: Context): Set<String>? {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getStringSet(context.getString(R.string.list_password_generator_options_key),
HashSet(listOf(*context.resources
.getStringArray(R.array.list_password_generator_options_default_values))))
}
fun isClipboardNotificationsEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.clipboard_notifications_key),
context.resources.getBoolean(R.bool.clipboard_notifications_default))
}
fun isLockDatabaseWhenScreenShutOffEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.lock_database_screen_off_key),
context.resources.getBoolean(R.bool.lock_database_screen_off_default))
}
fun isLockDatabaseWhenBackButtonOnRootClicked(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.lock_database_back_root_key),
context.resources.getBoolean(R.bool.lock_database_back_root_default))
}
fun isFingerprintEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.fingerprint_enable_key),
context.resources.getBoolean(R.bool.fingerprint_enable_default))
}
fun isFullFilePathEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.full_file_path_enable_key),
context.resources.getBoolean(R.bool.full_file_path_enable_default))
}
fun getListSort(context: Context): SortNodeEnum {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs.getString(context.getString(R.string.sort_node_key),
SortNodeEnum.TITLE.name)?.let {
return SortNodeEnum.valueOf(it)
}
return SortNodeEnum.DB
}
fun getGroupsBeforeSort(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.sort_group_before_key),
context.resources.getBoolean(R.bool.sort_group_before_default))
}
fun getAscendingSort(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.sort_ascending_key),
context.resources.getBoolean(R.bool.sort_ascending_default))
}
fun getRecycleBinBottomSort(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.sort_recycle_bin_bottom_key),
context.resources.getBoolean(R.bool.sort_recycle_bin_bottom_default))
}
fun isPasswordMask(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.maskpass_key),
context.resources.getBoolean(R.bool.maskpass_default))
}
fun fieldFontIsInVisibility(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.monospace_font_fields_enable_key),
context.resources.getBoolean(R.bool.monospace_font_fields_enable_default))
}
fun autoOpenSelectedFile(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.auto_open_file_uri_key),
context.resources.getBoolean(R.bool.auto_open_file_uri_default))
}
fun isFirstTimeAskAllowCopyPasswordAndProtectedFields(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.allow_copy_password_first_time_key),
context.resources.getBoolean(R.bool.allow_copy_password_first_time_default))
}
fun allowCopyPasswordAndProtectedFields(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.allow_copy_password_key),
context.resources.getBoolean(R.bool.allow_copy_password_default))
}
fun setAllowCopyPasswordAndProtectedFields(context: Context, allowCopy: Boolean) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs.edit()
.putBoolean(context.getString(R.string.allow_copy_password_first_time_key), false)
.putBoolean(context.getString(R.string.allow_copy_password_key), allowCopy)
.apply()
}
fun getIconPackSelectedId(context: Context): String? {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getString(
context.getString(R.string.setting_icon_pack_choose_key),
context.getString(R.string.setting_icon_pack_choose_default))
}
fun emptyPasswordAllowed(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.allow_no_password_key),
context.resources.getBoolean(R.bool.allow_no_password_default))
}
fun enableReadOnlyDatabase(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.enable_read_only_key),
context.resources.getBoolean(R.bool.enable_read_only_default))
}
fun enableKeyboardNotificationEntry(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_notification_entry_key),
context.resources.getBoolean(R.bool.keyboard_notification_entry_default))
}
fun enableKeyboardVibration(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_key_vibrate_key),
context.resources.getBoolean(R.bool.keyboard_key_vibrate_default))
}
fun enableKeyboardSound(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_key_sound_key),
context.resources.getBoolean(R.bool.keyboard_key_sound_default))
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018 Jeremy Jamet / Kunzisoft.
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
@@ -17,14 +17,13 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings;
package com.kunzisoft.keepass.settings
import android.support.v4.app.Fragment;
import android.support.v4.app.Fragment
public class SettingsAutofillActivity extends SettingsActivity {
class SettingsAutofillActivity : SettingsActivity() {
@Override
protected Fragment retrieveMainFragment() {
return NestedSettingsFragment.newInstance(NestedSettingsFragment.Screen.FORM_FILLING);
override fun retrieveMainFragment(): Fragment {
return NestedSettingsFragment.newInstance(NestedSettingsFragment.Screen.FORM_FILLING)
}
}

View File

@@ -39,13 +39,17 @@ class DatabaseEncryptionAlgorithmPreferenceDialogFragmentCompat : DatabaseSavePr
val recyclerView = view.findViewById<RecyclerView>(R.id.pref_dialog_list)
recyclerView.layoutManager = LinearLayoutManager(context)
activity?.let { activity ->
val encryptionAlgorithmAdapter = ListRadioItemAdapter<PwEncryptionAlgorithm>(activity)
encryptionAlgorithmAdapter.setRadioItemSelectedCallback(this)
recyclerView.adapter = encryptionAlgorithmAdapter
database?.let { database ->
algorithmSelected = database.encryptionAlgorithm
encryptionAlgorithmAdapter.setItems(database.availableEncryptionAlgorithms, algorithmSelected)
if (algorithmSelected != null)
encryptionAlgorithmAdapter.setItems(database.availableEncryptionAlgorithms, algorithmSelected!!)
}
}
}

View File

@@ -43,13 +43,17 @@ class DatabaseKeyDerivationPreferenceDialogFragmentCompat : DatabaseSavePreferen
val recyclerView = view.findViewById<RecyclerView>(R.id.pref_dialog_list)
recyclerView.layoutManager = LinearLayoutManager(context)
activity?.let { activity ->
val kdfAdapter = ListRadioItemAdapter<KdfEngine>(activity)
kdfAdapter.setRadioItemSelectedCallback(this)
recyclerView.adapter = kdfAdapter
database?.let { database ->
kdfEngineSelected = database.kdfEngine
kdfAdapter.setItems(database.availableKdfEngines, kdfEngineSelected)
if (kdfEngineSelected != null)
kdfAdapter.setItems(database.availableKdfEngines, kdfEngineSelected!!)
}
}
}

View File

@@ -1,109 +0,0 @@
/*
* Copyright 2018 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.database.ObjectNameResource;
import java.util.ArrayList;
import java.util.List;
public class ListRadioItemAdapter<T extends ObjectNameResource> extends RecyclerView.Adapter<ListRadioViewHolder> {
private Context context;
private LayoutInflater inflater;
private List<T> radioItemList;
private T radioItemUsed;
private RadioItemSelectedCallback<T> radioItemSelectedCallback;
public ListRadioItemAdapter(Context context) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.radioItemList = new ArrayList<>();
this.radioItemUsed = null;
}
@NonNull
@Override
public ListRadioViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.pref_dialog_list_radio_item, parent, false);
return new ListRadioViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ListRadioViewHolder holder, int position) {
T item = this.radioItemList.get(position);
holder.radioButton.setText(item.getName(context.getResources()));
if (radioItemUsed != null && radioItemUsed.equals(item))
holder.radioButton.setChecked(true);
else
holder.radioButton.setChecked(false);
holder.radioButton.setOnClickListener(new OnItemClickListener(item));
}
@Override
public int getItemCount() {
return radioItemList.size();
}
public void setItems(List<T> algorithms, T algorithmUsed) {
this.radioItemList.clear();
this.radioItemList.addAll(algorithms);
this.radioItemUsed = algorithmUsed;
}
private void setRadioItemUsed(T radioItemUsed) {
this.radioItemUsed = radioItemUsed;
}
private class OnItemClickListener implements View.OnClickListener {
private T itemClicked;
OnItemClickListener(T item) {
this.itemClicked = item;
}
@Override
public void onClick(View view) {
if (radioItemSelectedCallback != null)
radioItemSelectedCallback.onItemSelected(itemClicked);
setRadioItemUsed(itemClicked);
notifyDataSetChanged();
}
}
public void setRadioItemSelectedCallback(RadioItemSelectedCallback<T> radioItemSelectedCallback) {
this.radioItemSelectedCallback = radioItemSelectedCallback;
}
public interface RadioItemSelectedCallback<T> {
void onItemSelected(T item);
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment.adapter
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RadioButton
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.ObjectNameResource
import java.util.ArrayList
class ListRadioItemAdapter<T : ObjectNameResource>(private val context: Context)
: RecyclerView.Adapter<ListRadioItemAdapter.ListRadioViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
private val radioItemList: MutableList<T> = ArrayList()
private var radioItemUsed: T? = null
private var radioItemSelectedCallback: RadioItemSelectedCallback<T>? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListRadioViewHolder {
val view = inflater.inflate(R.layout.pref_dialog_list_radio_item, parent, false)
return ListRadioViewHolder(view)
}
override fun onBindViewHolder(holder: ListRadioViewHolder, position: Int) {
val item = this.radioItemList[position]
holder.radioButton.text = item.getName(context.resources)
holder.radioButton.isChecked = radioItemUsed != null && radioItemUsed == item
holder.radioButton.setOnClickListener(OnItemClickListener(item))
}
override fun getItemCount(): Int {
return radioItemList.size
}
fun setItems(algorithms: List<T>, algorithmUsed: T) {
this.radioItemList.clear()
this.radioItemList.addAll(algorithms)
this.radioItemUsed = algorithmUsed
}
private fun setRadioItemUsed(radioItemUsed: T) {
this.radioItemUsed = radioItemUsed
}
private inner class OnItemClickListener(private val itemClicked: T) : View.OnClickListener {
override fun onClick(view: View) {
radioItemSelectedCallback?.onItemSelected(itemClicked)
setRadioItemUsed(itemClicked)
notifyDataSetChanged()
}
}
fun setRadioItemSelectedCallback(radioItemSelectedCallback: RadioItemSelectedCallback<T>) {
this.radioItemSelectedCallback = radioItemSelectedCallback
}
interface RadioItemSelectedCallback<T> {
fun onItemSelected(item: T)
}
class ListRadioViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var radioButton: RadioButton = itemView.findViewById(R.id.pref_dialog_list_radio)
}
}