mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-22 01:02:16 -05:00
Add toolbar to Settings (involves reorganization of Settings into Fragmnt which removes duplicate code in both activities)
This commit is contained in:
parent
15f73257fa
commit
fabe0904c0
Binary file not shown.
After Width: | Height: | Size: 152 B |
Binary file not shown.
After Width: | Height: | Size: 118 B |
Binary file not shown.
After Width: | Height: | Size: 151 B |
Binary file not shown.
After Width: | Height: | Size: 188 B |
Binary file not shown.
After Width: | Height: | Size: 231 B |
15
src/keepass2android/Resources/layout/preference.axml
Normal file
15
src/keepass2android/Resources/layout/preference.axml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<include
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
layout="@layout/toolbar" />
|
||||||
|
<fragment
|
||||||
|
android:name="keepass2android.SettingsFragment"
|
||||||
|
android:id="@+id/settings_fragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/toolbar" />
|
||||||
|
</RelativeLayout>
|
10
src/keepass2android/Resources/layout/toolbar.axml
Normal file
10
src/keepass2android/Resources/layout/toolbar.axml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:local="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||||
|
local:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
@ -18,11 +18,15 @@
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:key="mainprefs">
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
android:key="@string/db_key"
|
android:key="@string/db_key"
|
||||||
android:title="@string/database"
|
android:title="@string/database"
|
||||||
android:summary="@string/menu_db_settings">
|
android:summary="@string/menu_db_settings">
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/db_key"
|
||||||
|
android:title="@string/database" />
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:title="@string/database_name"
|
android:title="@string/database_name"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
@ -72,11 +76,16 @@
|
|||||||
android:key="@string/app_key"
|
android:key="@string/app_key"
|
||||||
android:title="@string/application"
|
android:title="@string/application"
|
||||||
android:summary="@string/application_settings">
|
android:summary="@string/application_settings">
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/app_key"
|
||||||
|
android:title="@string/application" />
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
android:key="@string/security_prefs_key"
|
android:key="@string/security_prefs_key"
|
||||||
android:title="@string/security_prefs"
|
android:title="@string/security_prefs"
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/security_prefs_key"
|
||||||
|
android:title="@string/security_prefs" />
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="@string/clipboard_timeout_key"
|
android:key="@string/clipboard_timeout_key"
|
||||||
@ -142,6 +151,9 @@
|
|||||||
android:key="@string/display_prefs_key"
|
android:key="@string/display_prefs_key"
|
||||||
android:title="@string/display_prefs"
|
android:title="@string/display_prefs"
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/display_prefs_key"
|
||||||
|
android:title="@string/display_prefs" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
@ -187,15 +199,6 @@
|
|||||||
android:title="@string/ViewDatabaseSecure_title"
|
android:title="@string/ViewDatabaseSecure_title"
|
||||||
android:key="@string/ViewDatabaseSecure_key" />
|
android:key="@string/ViewDatabaseSecure_key" />
|
||||||
|
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
android:key="@string/design_key"
|
|
||||||
android:title="@string/design_title"
|
|
||||||
android:entries="@array/design_options"
|
|
||||||
android:entryValues="@array/design_values"
|
|
||||||
android:dialogTitle="@string/design_title"
|
|
||||||
android:defaultValue="@string/design_default"/>
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
@ -209,6 +212,9 @@
|
|||||||
android:key="@string/password_access_prefs_key"
|
android:key="@string/password_access_prefs_key"
|
||||||
android:title="@string/password_access_prefs"
|
android:title="@string/password_access_prefs"
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/password_access_prefs_key"
|
||||||
|
android:title="@string/password_access_prefs" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
@ -236,8 +242,10 @@
|
|||||||
android:key="@string/keyboardswitch_prefs_key"
|
android:key="@string/keyboardswitch_prefs_key"
|
||||||
android:title="@string/keyboardswitch_prefs"
|
android:title="@string/keyboardswitch_prefs"
|
||||||
android:dependency="@string/UseKp2aKeyboard_key"
|
android:dependency="@string/UseKp2aKeyboard_key"
|
||||||
|
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/keyboardswitch_prefs_key"
|
||||||
|
android:title="@string/keyboardswitch_prefs"/>
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="kp2a_switch_rooted"
|
android:key="kp2a_switch_rooted"
|
||||||
android:title="@string/kp2a_switch_rooted"
|
android:title="@string/kp2a_switch_rooted"
|
||||||
@ -289,6 +297,9 @@
|
|||||||
android:key="@string/QuickUnlock_prefs_key"
|
android:key="@string/QuickUnlock_prefs_key"
|
||||||
android:title="@string/QuickUnlock_prefs"
|
android:title="@string/QuickUnlock_prefs"
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/QuickUnlock_prefs_key"
|
||||||
|
android:title="@string/QuickUnlock_prefs"/>
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
@ -323,6 +334,9 @@
|
|||||||
android:key="@string/FileHandling_prefs_key"
|
android:key="@string/FileHandling_prefs_key"
|
||||||
android:title="@string/FileHandling_prefs"
|
android:title="@string/FileHandling_prefs"
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/FileHandling_prefs_key"
|
||||||
|
android:title="@string/FileHandling_prefs"/>
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
@ -395,7 +409,10 @@
|
|||||||
android:key="@string/TrayTotp_prefs_key"
|
android:key="@string/TrayTotp_prefs_key"
|
||||||
android:title="@string/TrayTotp_prefs"
|
android:title="@string/TrayTotp_prefs"
|
||||||
>
|
>
|
||||||
|
<keepass2android.ToolbarPreference
|
||||||
|
android:key="@string/TrayTotp_prefs_key"
|
||||||
|
android:title="@string/TrayTotp_prefs"/>
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
|
@ -432,48 +432,19 @@ namespace keepass2android
|
|||||||
activity.Finish();
|
activity.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrepareNoDonatePreference(Context ctx, Preference preference)
|
public static void PrepareDonateOptionMenu(IMenu menu, Context ctx)
|
||||||
{
|
{
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
var donateItem = menu.FindItem(Resource.Id.menu_donate);
|
||||||
|
if (donateItem != null)
|
||||||
|
{
|
||||||
|
donateItem.SetVisible(
|
||||||
|
!PreferenceManager.GetDefaultSharedPreferences(ctx)
|
||||||
|
.GetBoolean(ctx.GetString(Resource.String.NoDonateOption_key), false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long usageCount = prefs.GetLong(ctx.GetString(Resource.String.UsageCount_key), 0);
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
preference.Enabled = (usageCount > 1);
|
|
||||||
#else
|
|
||||||
preference.Enabled = (usageCount > 50);
|
|
||||||
#endif
|
|
||||||
preference.PreferenceChange += delegate(object sender, Preference.PreferenceChangeEventArgs args)
|
|
||||||
{
|
|
||||||
if ((bool) args.NewValue)
|
|
||||||
{
|
|
||||||
new AlertDialog.Builder(ctx)
|
|
||||||
.SetTitle(ctx.GetString(AppNames.AppNameResource))
|
|
||||||
.SetCancelable(false)
|
|
||||||
.SetPositiveButton(Android.Resource.String.Ok, delegate(object o, DialogClickEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
GotoDonateUrl(ctx);
|
|
||||||
((Dialog) o).Dismiss();
|
|
||||||
})
|
|
||||||
.SetMessage(Resource.String.NoDonateOption_question)
|
|
||||||
.Create().Show();
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void PrepareDonateOptionMenu(IMenu menu, Context ctx)
|
|
||||||
{
|
|
||||||
var donateItem = menu.FindItem(Resource.Id.menu_donate);
|
|
||||||
if (donateItem != null)
|
|
||||||
{
|
|
||||||
donateItem.SetVisible(
|
|
||||||
!PreferenceManager.GetDefaultSharedPreferences(ctx)
|
|
||||||
.GetBoolean(ctx.GetString(Resource.String.NoDonateOption_key), false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +264,12 @@
|
|||||||
<AndroidResource Include="Resources\layout\EntryEditButtonDelete.axml">
|
<AndroidResource Include="Resources\layout\EntryEditButtonDelete.axml">
|
||||||
<SubType>AndroidResource</SubType>
|
<SubType>AndroidResource</SubType>
|
||||||
</AndroidResource>
|
</AndroidResource>
|
||||||
|
<AndroidResource Include="Resources\layout\preference.axml">
|
||||||
|
<SubType>AndroidResource</SubType>
|
||||||
|
</AndroidResource>
|
||||||
|
<AndroidResource Include="Resources\layout\toolbar.axml">
|
||||||
|
<SubType>AndroidResource</SubType>
|
||||||
|
</AndroidResource>
|
||||||
<None Include="settings\RoundsPreference %28Kopie%29.cs">
|
<None Include="settings\RoundsPreference %28Kopie%29.cs">
|
||||||
<Visible>False</Visible>
|
<Visible>False</Visible>
|
||||||
</None>
|
</None>
|
||||||
@ -1310,4 +1316,19 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_nav_about.png" />
|
<AndroidResource Include="Resources\drawable-xhdpi\ic_nav_about.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable-mhdpi\ic_arrow_back_white_24dp.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable-hdpi\ic_arrow_back_white_24dp.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable-xhdpi\ic_arrow_back_white_24dp.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable-xxhdpi\ic_arrow_back_white_24dp.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable-xxxhdpi\ic_arrow_back_white_24dp.png" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -21,20 +21,70 @@ using Android.App;
|
|||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
|
using Android.Runtime;
|
||||||
|
using Android.Util;
|
||||||
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using keepass2android.Io;
|
using keepass2android.Io;
|
||||||
|
using Toolbar = Android.Support.V7.Widget.Toolbar;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
public class ToolbarPreference : Preference
|
||||||
|
{
|
||||||
|
#region constructors
|
||||||
|
protected ToolbarPreference(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToolbarPreference(Context context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToolbarPreference(Context context, IAttributeSet attrs) : base(context, attrs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToolbarPreference(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToolbarPreference(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
protected override View OnCreateView(ViewGroup parent)
|
||||||
|
{
|
||||||
|
parent.SetPadding(0, 0, 0, 0);
|
||||||
|
|
||||||
|
LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService);
|
||||||
|
View layout = inflater.Inflate(Resource.Layout.toolbar, parent, false);
|
||||||
|
|
||||||
|
Toolbar toolbar = (Toolbar) layout.FindViewById<Toolbar>(Resource.Id.toolbar);
|
||||||
|
toolbar.SetNavigationIcon(Resource.Drawable.ic_arrow_back_white_24dp);
|
||||||
|
toolbar.Title = Title;
|
||||||
|
toolbar.NavigationClick += (sender, args) =>
|
||||||
|
{
|
||||||
|
PreferenceScreen prefScreen = (PreferenceScreen) PreferenceManager.FindPreference(Key);
|
||||||
|
if (prefScreen == null)
|
||||||
|
throw new Exception("didn't find preference " + Key);
|
||||||
|
prefScreen.Dialog.Dismiss();
|
||||||
|
};
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activity to configure the application, without database settings. Does not require an unlocked database, or close when the database is locked
|
/// Activity to configure the application, without database settings. Does not require an unlocked database, or close when the database is locked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar")]
|
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme")]
|
||||||
public class AppSettingsActivity : LockingPreferenceActivity
|
public class AppSettingsActivity : LockingActivity
|
||||||
{
|
{
|
||||||
private ActivityDesign _design;
|
private ActivityDesign _design;
|
||||||
private KeyboardSwitchPrefManager _switchPrefManager;
|
|
||||||
|
|
||||||
public AppSettingsActivity()
|
public AppSettingsActivity()
|
||||||
{
|
{
|
||||||
_design = new ActivityDesign(this);
|
_design = new ActivityDesign(this);
|
||||||
@ -47,223 +97,16 @@ namespace keepass2android
|
|||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
_design.ApplyTheme();
|
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
|
SetContentView(Resource.Layout.preference);
|
||||||
|
|
||||||
|
SetSupportActionBar(FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar));
|
||||||
|
|
||||||
|
FragmentManager.FindFragmentById<SettingsFragment>(Resource.Id.settings_fragment).FindPreference(GetString(Resource.String.db_key)).Enabled = false;
|
||||||
|
|
||||||
AddPreferencesFromResource(Resource.Xml.preferences);
|
|
||||||
|
|
||||||
FindPreference(GetString(Resource.String.keyfile_key)).PreferenceChange += OnRememberKeyFileHistoryChanged;
|
|
||||||
Preference designPref = FindPreference(GetString(Resource.String.design_key));
|
|
||||||
if (!_design.HasThemes())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(designPref);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
designPref.PreferenceChange += (sender, args) => Recreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.PrepareNoDonatePreference(this, FindPreference(GetString(Resource.String.NoDonateOption_key)));
|
|
||||||
|
|
||||||
Preference cachingPreference = FindPreference(GetString(Resource.String.UseOfflineCache_key));
|
|
||||||
cachingPreference.PreferenceChange += OnUseOfflineCacheChanged;
|
|
||||||
|
|
||||||
#if NoNet
|
|
||||||
try
|
|
||||||
{
|
|
||||||
((PreferenceScreen) FindPreference(GetString(Resource.String.FileHandling_prefs_key))).RemovePreference(cachingPreference);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//depending on Android version, we offer to use a transparent icon for QuickUnlock or use the notification priority (since API level 16)
|
|
||||||
Preference hideQuickUnlockTranspIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key));
|
|
||||||
Preference hideQuickUnlockIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden16_key));
|
|
||||||
var quickUnlockScreen = ((PreferenceScreen) FindPreference(GetString(Resource.String.QuickUnlock_prefs_key)));
|
|
||||||
if ((int) Android.OS.Build.VERSION.SdkInt >= 16)
|
|
||||||
{
|
|
||||||
quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
|
|
||||||
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)).PreferenceChange += (sender, args) => App.Kp2a.UpdateOngoingNotification();
|
|
||||||
hideQuickUnlockIconPref.PreferenceChange += OnQuickUnlockHiddenChanged;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//old version: only show transparent quickUnlock and no option to hide unlocked icon:
|
|
||||||
quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
|
|
||||||
FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key)).PreferenceChange +=
|
|
||||||
delegate { App.Kp2a.UpdateOngoingNotification(); };
|
|
||||||
((PreferenceScreen) FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(
|
|
||||||
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
FindPreference(GetString(Resource.String.db_key)).Enabled = false;
|
|
||||||
_switchPrefManager = new KeyboardSwitchPrefManager(this);
|
|
||||||
|
|
||||||
PrepareSeparateNotificationsPreference(this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrepareSeparateNotificationsPreference(PreferenceActivity preferenceActivity)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//depending on Android version, we offer to show a combined notification (with action buttons) (since API level 16)
|
|
||||||
Preference separateNotificationsPref = preferenceActivity.FindPreference(preferenceActivity.GetString(Resource.String.ShowSeparateNotifications_key));
|
|
||||||
var passwordAccessScreen = ((PreferenceScreen)preferenceActivity.FindPreference(preferenceActivity.GetString(Resource.String.password_access_prefs_key)));
|
|
||||||
if ((int)Build.VERSION.SdkInt < 16)
|
|
||||||
{
|
|
||||||
passwordAccessScreen.RemovePreference(separateNotificationsPref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class KeyboardSwitchPrefManager
|
|
||||||
{
|
|
||||||
private readonly PreferenceActivity _act;
|
|
||||||
private CheckBoxPreference _switchPref;
|
|
||||||
private CheckBoxPreference _openKp2aAutoPref;
|
|
||||||
private CheckBoxPreference _openOnlyOnSearchPref;
|
|
||||||
private CheckBoxPreference _switchBackPref;
|
|
||||||
private PreferenceScreen _screen;
|
|
||||||
|
|
||||||
public KeyboardSwitchPrefManager(PreferenceActivity act)
|
|
||||||
{
|
|
||||||
this._act = act;
|
|
||||||
|
|
||||||
_switchPref = (CheckBoxPreference)_act.FindPreference("kp2a_switch_rooted");
|
|
||||||
_openKp2aAutoPref =
|
|
||||||
(CheckBoxPreference)act.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key));
|
|
||||||
_openOnlyOnSearchPref =
|
|
||||||
(CheckBoxPreference)
|
|
||||||
act.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key));
|
|
||||||
_switchBackPref =
|
|
||||||
(CheckBoxPreference)act.FindPreference(act.GetString(Resource.String.AutoSwitchBackKeyboard_key));
|
|
||||||
_screen = (PreferenceScreen)act.FindPreference(act.GetString(Resource.String.keyboardswitch_prefs_key));
|
|
||||||
EnableSwitchPreferences(_switchPref.Checked);
|
|
||||||
|
|
||||||
_switchPref.PreferenceChange += (sender, args) =>
|
|
||||||
{
|
|
||||||
bool switchOnRooted = (bool)args.NewValue;
|
|
||||||
EnableSwitchPreferences(switchOnRooted);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void EnableSwitchPreferences(bool switchOnRooted)
|
|
||||||
{
|
|
||||||
if (!switchOnRooted)
|
|
||||||
{
|
|
||||||
if (_act.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key)) == null)
|
|
||||||
{
|
|
||||||
_screen.AddPreference(_openKp2aAutoPref);
|
|
||||||
}
|
|
||||||
if (_act.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) != null)
|
|
||||||
{
|
|
||||||
_screen.RemovePreference(_openOnlyOnSearchPref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_act.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key)) != null)
|
|
||||||
{
|
|
||||||
_screen.RemovePreference(_openKp2aAutoPref);
|
|
||||||
}
|
|
||||||
if (_act.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) == null)
|
|
||||||
{
|
|
||||||
_screen.AddPreference(_openOnlyOnSearchPref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*_openKp2aAutoPref.Enabled = !switchOnRooted;
|
|
||||||
|
|
||||||
_openOnlyOnSearchPref.Enabled = switchOnRooted;
|
|
||||||
|
|
||||||
_switchBackPref.Enabled = switchOnRooted;*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDesignChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
|
|
||||||
{
|
|
||||||
Recreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnQuickUnlockHiddenChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
|
||||||
{
|
|
||||||
App.Kp2a.UpdateOngoingNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUseOfflineCacheChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
|
||||||
{
|
|
||||||
//ensure the user gets a matching database
|
|
||||||
if (App.Kp2a.GetDb().Loaded && !App.Kp2a.GetDb().Ioc.IsLocalFile())
|
|
||||||
App.Kp2a.LockDatabase(false);
|
|
||||||
|
|
||||||
if (!(bool)e.NewValue)
|
|
||||||
{
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.SetTitle(GetString(Resource.String.ClearOfflineCache_title));
|
|
||||||
|
|
||||||
builder.SetMessage(GetString(Resource.String.ClearOfflineCache_question));
|
|
||||||
|
|
||||||
builder.SetPositiveButton(App.Kp2a.GetResourceString(UiStringKey.yes), (o, args) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
App.Kp2a.ClearOfflineCache();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
Toast.MakeText(Application.Context, ex.Message, ToastLength.Long).Show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.SetNegativeButton(App.Kp2a.GetResourceString(UiStringKey.no), (o, args) =>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
);
|
|
||||||
builder.SetCancelable(false);
|
|
||||||
Dialog dialog = builder.Create();
|
|
||||||
dialog.Show();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void OnRememberKeyFileHistoryChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (!(bool)eventArgs.NewValue)
|
|
||||||
{
|
|
||||||
App.Kp2a.FileDbHelper.DeleteAllKeys();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void OnShowUnlockedNotificationChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
App.Kp2a.UpdateOngoingNotification();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ using Android.Content;
|
|||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
|
using Android.Views;
|
||||||
using Java.IO;
|
using Java.IO;
|
||||||
using KeePassLib.Cryptography.Cipher;
|
using KeePassLib.Cryptography.Cipher;
|
||||||
using KeePassLib.Keys;
|
using KeePassLib.Keys;
|
||||||
@ -32,18 +33,570 @@ using keepass2android.Utils;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
//http://stackoverflow.com/a/27422401/292233
|
||||||
|
public class SettingsFragment : PreferenceFragment
|
||||||
|
{
|
||||||
|
|
||||||
|
public class KeyboardSwitchPrefManager
|
||||||
|
{
|
||||||
|
private readonly Activity _act;
|
||||||
|
private CheckBoxPreference _switchPref;
|
||||||
|
private CheckBoxPreference _openKp2aAutoPref;
|
||||||
|
private CheckBoxPreference _openOnlyOnSearchPref;
|
||||||
|
private CheckBoxPreference _switchBackPref;
|
||||||
|
private PreferenceScreen _screen;
|
||||||
|
private PreferenceFragment _fragment;
|
||||||
|
|
||||||
|
public KeyboardSwitchPrefManager(PreferenceFragment fragment)
|
||||||
|
{
|
||||||
|
var act = fragment.Activity;
|
||||||
|
this._act = act;
|
||||||
|
this._fragment = fragment;
|
||||||
|
|
||||||
|
_switchPref = (CheckBoxPreference)_fragment.FindPreference("kp2a_switch_rooted");
|
||||||
|
_openKp2aAutoPref =
|
||||||
|
(CheckBoxPreference)_fragment.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key));
|
||||||
|
_openOnlyOnSearchPref =
|
||||||
|
(CheckBoxPreference)
|
||||||
|
_fragment.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key));
|
||||||
|
_switchBackPref =
|
||||||
|
(CheckBoxPreference)_fragment.FindPreference(act.GetString(Resource.String.AutoSwitchBackKeyboard_key));
|
||||||
|
_screen = (PreferenceScreen)_fragment.FindPreference(act.GetString(Resource.String.keyboardswitch_prefs_key));
|
||||||
|
EnableSwitchPreferences(_switchPref.Checked);
|
||||||
|
|
||||||
|
_switchPref.PreferenceChange += (sender, args) =>
|
||||||
|
{
|
||||||
|
bool switchOnRooted = (bool)args.NewValue;
|
||||||
|
EnableSwitchPreferences(switchOnRooted);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void EnableSwitchPreferences(bool switchOnRooted)
|
||||||
|
{
|
||||||
|
if (!switchOnRooted)
|
||||||
|
{
|
||||||
|
if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key)) == null)
|
||||||
|
{
|
||||||
|
_screen.AddPreference(_openKp2aAutoPref);
|
||||||
|
}
|
||||||
|
if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) != null)
|
||||||
|
{
|
||||||
|
_screen.RemovePreference(_openOnlyOnSearchPref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
{
|
||||||
|
_screen.RemovePreference(_openKp2aAutoPref);
|
||||||
|
}
|
||||||
|
if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) == null)
|
||||||
|
{
|
||||||
|
_screen.AddPreference(_openOnlyOnSearchPref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*_openKp2aAutoPref.Enabled = !switchOnRooted;
|
||||||
|
|
||||||
|
_openOnlyOnSearchPref.Enabled = switchOnRooted;
|
||||||
|
|
||||||
|
_switchBackPref.Enabled = switchOnRooted;*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyboardSwitchPrefManager _switchPrefManager;
|
||||||
|
|
||||||
|
void OnRememberKeyFileHistoryChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (!(bool)eventArgs.NewValue)
|
||||||
|
{
|
||||||
|
App.Kp2a.FileDbHelper.DeleteAllKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnShowUnlockedNotificationChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
App.Kp2a.UpdateOngoingNotification();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void OnCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
base.OnCreate(savedInstanceState);
|
||||||
|
AddPreferencesFromResource(Resource.Xml.preferences);
|
||||||
|
|
||||||
|
// Re-use the change handlers for the application settings
|
||||||
|
FindPreference(GetString(Resource.String.keyfile_key)).PreferenceChange += OnRememberKeyFileHistoryChanged;
|
||||||
|
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)).PreferenceChange += OnShowUnlockedNotificationChanged;
|
||||||
|
PrepareNoDonatePreference(Activity, FindPreference(GetString(Resource.String.NoDonateOption_key)));
|
||||||
|
|
||||||
|
Database db = App.Kp2a.GetDb();
|
||||||
|
if (db.Loaded)
|
||||||
|
{
|
||||||
|
Preference rounds = FindPreference(GetString(Resource.String.rounds_key));
|
||||||
|
rounds.PreferenceChange += (sender, e) => SetRounds(db, e.Preference);
|
||||||
|
rounds.Enabled = db.CanWrite;
|
||||||
|
SetRounds(db, rounds);
|
||||||
|
|
||||||
|
PrepareDefaultUsername(db);
|
||||||
|
PrepareDatabaseName(db);
|
||||||
|
PrepareMasterPassword();
|
||||||
|
|
||||||
|
Preference algorithm = FindPreference(GetString(Resource.String.algorithm_key));
|
||||||
|
SetAlgorithm(db, algorithm);
|
||||||
|
|
||||||
|
UpdateImportDbPref();
|
||||||
|
UpdateImportKeyfilePref();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//depending on Android version, we offer to use a transparent icon for QuickUnlock or use the notification priority (since API level 16)
|
||||||
|
Preference hideQuickUnlockTranspIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key));
|
||||||
|
Preference hideQuickUnlockIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden16_key));
|
||||||
|
var quickUnlockScreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.QuickUnlock_prefs_key)));
|
||||||
|
if ((int)Android.OS.Build.VERSION.SdkInt >= 16)
|
||||||
|
{
|
||||||
|
quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
|
||||||
|
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)).PreferenceChange += (sender, args) => App.Kp2a.UpdateOngoingNotification();
|
||||||
|
hideQuickUnlockIconPref.PreferenceChange += delegate { App.Kp2a.UpdateOngoingNotification(); };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//old version: only show transparent quickUnlock and no option to hide unlocked icon:
|
||||||
|
quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
|
||||||
|
FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key)).PreferenceChange +=
|
||||||
|
delegate { App.Kp2a.UpdateOngoingNotification(); };
|
||||||
|
|
||||||
|
((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(
|
||||||
|
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//AppSettingsActivity.PrepareKeyboardSwitchingPreferences(this);
|
||||||
|
_switchPrefManager = new KeyboardSwitchPrefManager(this);
|
||||||
|
PrepareSeparateNotificationsPreference();
|
||||||
|
|
||||||
|
Preference cachingPreference = FindPreference(GetString(Resource.String.UseOfflineCache_key));
|
||||||
|
cachingPreference.PreferenceChange += OnUseOfflineCacheChanged;
|
||||||
|
|
||||||
|
#if NoNet
|
||||||
|
try
|
||||||
|
{
|
||||||
|
((PreferenceScreen) FindPreference(GetString(Resource.String.FileHandling_prefs_key))).RemovePreference(cachingPreference);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(ex.ToString());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//depending on Android version, we offer to use a transparent icon for QuickUnlock or use the notification priority (since API level 16)
|
||||||
|
Preference hideQuickUnlockTranspIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key));
|
||||||
|
Preference hideQuickUnlockIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden16_key));
|
||||||
|
var quickUnlockScreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.QuickUnlock_prefs_key)));
|
||||||
|
if ((int)Android.OS.Build.VERSION.SdkInt >= 16)
|
||||||
|
{
|
||||||
|
quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
|
||||||
|
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)).PreferenceChange += (sender, args) => App.Kp2a.UpdateOngoingNotification();
|
||||||
|
hideQuickUnlockIconPref.PreferenceChange += OnQuickUnlockHiddenChanged;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//old version: only show transparent quickUnlock and no option to hide unlocked icon:
|
||||||
|
quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
|
||||||
|
FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key)).PreferenceChange +=
|
||||||
|
delegate { App.Kp2a.UpdateOngoingNotification(); };
|
||||||
|
((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(
|
||||||
|
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareMasterPassword()
|
||||||
|
{
|
||||||
|
Preference changeMaster = FindPreference(GetString(Resource.String.master_pwd_key));
|
||||||
|
if (App.Kp2a.GetDb().CanWrite)
|
||||||
|
{
|
||||||
|
changeMaster.Enabled = true;
|
||||||
|
changeMaster.PreferenceClick += delegate { new SetPasswordDialog(Activity).Show(); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareDatabaseName(Database db)
|
||||||
|
{
|
||||||
|
Preference databaseName = FindPreference(GetString(Resource.String.database_name_key));
|
||||||
|
if (!db.DatabaseFormat.HasDatabaseName)
|
||||||
|
{
|
||||||
|
((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(databaseName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
databaseName.Enabled = db.CanWrite;
|
||||||
|
((EditTextPreference) databaseName).EditText.Text = db.KpDatabase.Name;
|
||||||
|
((EditTextPreference) databaseName).Text = db.KpDatabase.Name;
|
||||||
|
databaseName.PreferenceChange += (sender, e) =>
|
||||||
|
{
|
||||||
|
DateTime previousNameChanged = db.KpDatabase.NameChanged;
|
||||||
|
String previousName = db.KpDatabase.Name;
|
||||||
|
db.KpDatabase.Name = e.NewValue.ToString();
|
||||||
|
|
||||||
|
SaveDb save = new SaveDb(Activity, App.Kp2a, new ActionOnFinish((success, message) =>
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
db.KpDatabase.Name = previousName;
|
||||||
|
db.KpDatabase.NameChanged = previousNameChanged;
|
||||||
|
Toast.MakeText(Activity, message, ToastLength.Long).Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Name is reflected in notification, so update it
|
||||||
|
App.Kp2a.UpdateOngoingNotification();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
|
||||||
|
pt.Run();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareDefaultUsername(Database db)
|
||||||
|
{
|
||||||
|
Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
|
||||||
|
if (!db.DatabaseFormat.HasDefaultUsername)
|
||||||
|
{
|
||||||
|
((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(defaultUser);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
defaultUser.Enabled = db.CanWrite;
|
||||||
|
((EditTextPreference) defaultUser).EditText.Text = db.KpDatabase.DefaultUserName;
|
||||||
|
((EditTextPreference) defaultUser).Text = db.KpDatabase.DefaultUserName;
|
||||||
|
defaultUser.PreferenceChange += (sender, e) =>
|
||||||
|
{
|
||||||
|
DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged;
|
||||||
|
String previousUsername = db.KpDatabase.DefaultUserName;
|
||||||
|
db.KpDatabase.DefaultUserName = e.NewValue.ToString();
|
||||||
|
|
||||||
|
SaveDb save = new SaveDb(Activity, App.Kp2a, new ActionOnFinish((success, message) =>
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
db.KpDatabase.DefaultUserName = previousUsername;
|
||||||
|
db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged;
|
||||||
|
Toast.MakeText(Activity, message, ToastLength.Long).Show();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
|
||||||
|
pt.Run();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareSeparateNotificationsPreference()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//depending on Android version, we offer to show a combined notification (with action buttons) (since API level 16)
|
||||||
|
Preference separateNotificationsPref = FindPreference(Activity.GetString(Resource.String.ShowSeparateNotifications_key));
|
||||||
|
var passwordAccessScreen = ((PreferenceScreen)FindPreference(Activity.GetString(Resource.String.password_access_prefs_key)));
|
||||||
|
if ((int)Build.VERSION.SdkInt < 16)
|
||||||
|
{
|
||||||
|
passwordAccessScreen.RemovePreference(separateNotificationsPref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void OnQuickUnlockHiddenChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
||||||
|
{
|
||||||
|
App.Kp2a.UpdateOngoingNotification();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUseOfflineCacheChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
||||||
|
{
|
||||||
|
//ensure the user gets a matching database
|
||||||
|
if (App.Kp2a.GetDb().Loaded && !App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||||
|
App.Kp2a.LockDatabase(false);
|
||||||
|
|
||||||
|
if (!(bool)e.NewValue)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
|
||||||
|
builder.SetTitle(GetString(Resource.String.ClearOfflineCache_title));
|
||||||
|
|
||||||
|
builder.SetMessage(GetString(Resource.String.ClearOfflineCache_question));
|
||||||
|
|
||||||
|
builder.SetPositiveButton(App.Kp2a.GetResourceString(UiStringKey.yes), (o, args) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
App.Kp2a.ClearOfflineCache();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(ex.ToString());
|
||||||
|
Toast.MakeText(Application.Context, ex.Message, ToastLength.Long).Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.SetNegativeButton(App.Kp2a.GetResourceString(UiStringKey.no), (o, args) =>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
);
|
||||||
|
builder.SetCancelable(false);
|
||||||
|
Dialog dialog = builder.Create();
|
||||||
|
dialog.Show();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateImportKeyfilePref()
|
||||||
|
{
|
||||||
|
var prefs = PreferenceManager.GetDefaultSharedPreferences(Activity);
|
||||||
|
var rememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
||||||
|
|
||||||
|
Preference importDb = FindPreference("import_keyfile_prefs");
|
||||||
|
importDb.Summary = "";
|
||||||
|
|
||||||
|
if (!rememberKeyfile)
|
||||||
|
{
|
||||||
|
importDb.Summary = GetString(Resource.String.KeyfileMoveRequiresRememberKeyfile);
|
||||||
|
importDb.Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CompositeKey masterKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
||||||
|
if (masterKey.ContainsType(typeof(KcpKeyFile)))
|
||||||
|
{
|
||||||
|
IOConnectionInfo iocKeyfile = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
|
||||||
|
if (iocKeyfile.IsLocalFile() && IoUtil.IsInInternalDirectory(iocKeyfile.Path, Activity))
|
||||||
|
{
|
||||||
|
importDb.Enabled = false;
|
||||||
|
importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importDb.Enabled = true;
|
||||||
|
importDb.PreferenceClick += (sender, args) => { MoveKeyfileToInternalFolder(); };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importDb.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveKeyfileToInternalFolder()
|
||||||
|
{
|
||||||
|
Func<Action> copyAndReturnPostExecute = () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CompositeKey masterKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
||||||
|
var sourceIoc = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
|
||||||
|
var newIoc = ImportFileToInternalDirectory(sourceIoc);
|
||||||
|
((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
|
||||||
|
var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
|
||||||
|
App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.GetDb().Ioc, keyfileString);
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
UpdateImportKeyfilePref();
|
||||||
|
var builder = new AlertDialog.Builder(Activity);
|
||||||
|
builder
|
||||||
|
.SetMessage(Resource.String.KeyfileMoved);
|
||||||
|
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => { });
|
||||||
|
builder.Show();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
new SimpleLoadingDialog(Activity, GetString(Resource.String.CopyingFile), false,
|
||||||
|
copyAndReturnPostExecute
|
||||||
|
).Execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
private void UpdateImportDbPref()
|
||||||
|
{
|
||||||
|
//Import db/key file preferences:
|
||||||
|
Preference importDb = FindPreference("import_db_prefs");
|
||||||
|
if (!App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||||
|
{
|
||||||
|
importDb.Summary = GetString(Resource.String.OnlyAvailableForLocalFiles);
|
||||||
|
importDb.Enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IoUtil.IsInInternalDirectory(App.Kp2a.GetDb().Ioc.Path, Activity))
|
||||||
|
{
|
||||||
|
importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
|
||||||
|
importDb.Enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importDb.Enabled = true;
|
||||||
|
importDb.PreferenceClick += delegate { MoveDbToInternalFolder(); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveDbToInternalFolder()
|
||||||
|
{
|
||||||
|
Func<Action> copyAndReturnPostExecute = () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sourceIoc = App.Kp2a.GetDb().Ioc;
|
||||||
|
var newIoc = ImportFileToInternalDirectory(sourceIoc);
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var builder = new AlertDialog.Builder(Activity);
|
||||||
|
builder
|
||||||
|
.SetMessage(Resource.String.DatabaseFileMoved);
|
||||||
|
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
|
||||||
|
PasswordActivity.Launch(Activity, newIoc, new NullTask()));
|
||||||
|
builder.Show();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
new SimpleLoadingDialog(Activity, GetString(Resource.String.CopyingFile), false,
|
||||||
|
copyAndReturnPostExecute
|
||||||
|
).Execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc)
|
||||||
|
{
|
||||||
|
string targetPath = UrlUtil.GetFileName(sourceIoc.Path);
|
||||||
|
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
|
||||||
|
if (targetPath == "")
|
||||||
|
targetPath = "imported";
|
||||||
|
if (new File(Activity.FilesDir, targetPath).Exists())
|
||||||
|
{
|
||||||
|
int c = 1;
|
||||||
|
var ext = UrlUtil.GetExtension(targetPath);
|
||||||
|
var filenameWithoutExt = UrlUtil.StripExtension(targetPath);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
targetPath = filenameWithoutExt + c;
|
||||||
|
if (!String.IsNullOrEmpty(ext))
|
||||||
|
targetPath += "." + ext;
|
||||||
|
} while (new File(Activity.FilesDir, targetPath).Exists());
|
||||||
|
}
|
||||||
|
var targetIoc = IOConnectionInfo.FromPath(new File(Activity.FilesDir, targetPath).CanonicalPath);
|
||||||
|
|
||||||
|
IoUtil.Copy(targetIoc, sourceIoc, App.Kp2a);
|
||||||
|
return targetIoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SetRounds(Database db, Preference rounds)
|
||||||
|
{
|
||||||
|
rounds.Summary = db.KpDatabase.KeyEncryptionRounds.ToString(CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetAlgorithm(Database db, Preference algorithm)
|
||||||
|
{
|
||||||
|
algorithm.Summary = CipherPool.GlobalPool.GetCipher(db.KpDatabase.DataCipherUuid).DisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareNoDonatePreference(Context ctx, Preference preference)
|
||||||
|
{
|
||||||
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
||||||
|
|
||||||
|
long usageCount = prefs.GetLong(ctx.GetString(Resource.String.UsageCount_key), 0);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
preference.Enabled = (usageCount > 1);
|
||||||
|
#else
|
||||||
|
preference.Enabled = (usageCount > 50);
|
||||||
|
#endif
|
||||||
|
preference.PreferenceChange += delegate(object sender, Preference.PreferenceChangeEventArgs args)
|
||||||
|
{
|
||||||
|
if ((bool)args.NewValue)
|
||||||
|
{
|
||||||
|
new AlertDialog.Builder(ctx)
|
||||||
|
.SetTitle(ctx.GetString(AppNames.AppNameResource))
|
||||||
|
.SetCancelable(false)
|
||||||
|
.SetPositiveButton(Android.Resource.String.Ok, delegate(object o, DialogClickEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
Util.GotoDonateUrl(ctx);
|
||||||
|
((Dialog)o).Dismiss();
|
||||||
|
})
|
||||||
|
.SetMessage(Resource.String.NoDonateOption_question)
|
||||||
|
.Create().Show();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activity to configure the application and database settings. The database must be unlocked, and this activity will close if it becomes locked.
|
/// Activity to configure the application and database settings. The database must be unlocked, and this activity will close if it becomes locked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar")]
|
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme")]
|
||||||
public class DatabaseSettingsActivity : LockingClosePreferenceActivity
|
public class DatabaseSettingsActivity : LockCloseActivity
|
||||||
{
|
{
|
||||||
private ActivityDesign _design;
|
|
||||||
private AppSettingsActivity.KeyboardSwitchPrefManager _switchPrefManager;
|
|
||||||
|
|
||||||
public DatabaseSettingsActivity()
|
public DatabaseSettingsActivity()
|
||||||
{
|
{
|
||||||
_design = new ActivityDesign(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Launch(Activity ctx)
|
public static void Launch(Activity ctx)
|
||||||
@ -51,338 +604,15 @@ namespace keepass2android
|
|||||||
ctx.StartActivity(new Intent(ctx, typeof(DatabaseSettingsActivity)));
|
ctx.StartActivity(new Intent(ctx, typeof(DatabaseSettingsActivity)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
_design.ApplyTheme();
|
base.OnCreate(savedInstanceState);
|
||||||
|
SetContentView(Resource.Layout.preference);
|
||||||
|
|
||||||
base.OnCreate(savedInstanceState);
|
SetSupportActionBar(FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar));
|
||||||
|
|
||||||
AddPreferencesFromResource(Resource.Xml.preferences);
|
|
||||||
|
|
||||||
// Re-use the change handlers for the application settings
|
}
|
||||||
FindPreference(GetString(Resource.String.keyfile_key)).PreferenceChange += AppSettingsActivity.OnRememberKeyFileHistoryChanged;
|
|
||||||
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)).PreferenceChange += AppSettingsActivity.OnShowUnlockedNotificationChanged;
|
|
||||||
Util.PrepareNoDonatePreference(this, FindPreference(GetString(Resource.String.NoDonateOption_key)));
|
|
||||||
Preference designPref = FindPreference(GetString(Resource.String.design_key));
|
|
||||||
if (!_design.HasThemes())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(designPref);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
designPref.PreferenceChange += (sender, args) => Recreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Database db = App.Kp2a.GetDb();
|
|
||||||
|
|
||||||
Preference rounds = FindPreference(GetString(Resource.String.rounds_key));
|
|
||||||
rounds.PreferenceChange += (sender, e) => SetRounds(db, e.Preference);
|
|
||||||
rounds.Enabled = db.CanWrite;
|
|
||||||
|
|
||||||
Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
|
|
||||||
if (!db.DatabaseFormat.HasDefaultUsername)
|
|
||||||
{
|
|
||||||
((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(defaultUser);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
defaultUser.Enabled = db.CanWrite;
|
|
||||||
((EditTextPreference)defaultUser).EditText.Text = db.KpDatabase.DefaultUserName;
|
|
||||||
((EditTextPreference)defaultUser).Text = db.KpDatabase.DefaultUserName;
|
|
||||||
defaultUser.PreferenceChange += (sender, e) =>
|
|
||||||
{
|
|
||||||
DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged;
|
|
||||||
String previousUsername = db.KpDatabase.DefaultUserName;
|
|
||||||
db.KpDatabase.DefaultUserName = e.NewValue.ToString();
|
|
||||||
|
|
||||||
SaveDb save = new SaveDb(this, App.Kp2a, new ActionOnFinish((success, message) =>
|
|
||||||
{
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
db.KpDatabase.DefaultUserName = previousUsername;
|
|
||||||
db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged;
|
|
||||||
Toast.MakeText(this, message, ToastLength.Long).Show();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
ProgressTask pt = new ProgressTask(App.Kp2a, this, save);
|
|
||||||
pt.Run();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Preference databaseName = FindPreference(GetString(Resource.String.database_name_key));
|
|
||||||
if (!db.DatabaseFormat.HasDatabaseName)
|
|
||||||
{
|
|
||||||
((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(databaseName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
databaseName.Enabled = db.CanWrite;
|
|
||||||
((EditTextPreference) databaseName).EditText.Text = db.KpDatabase.Name;
|
|
||||||
((EditTextPreference) databaseName).Text = db.KpDatabase.Name;
|
|
||||||
databaseName.PreferenceChange += (sender, e) =>
|
|
||||||
{
|
|
||||||
DateTime previousNameChanged = db.KpDatabase.NameChanged;
|
|
||||||
String previousName = db.KpDatabase.Name;
|
|
||||||
db.KpDatabase.Name = e.NewValue.ToString();
|
|
||||||
|
|
||||||
SaveDb save = new SaveDb(this, App.Kp2a, new ActionOnFinish((success, message) =>
|
|
||||||
{
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
db.KpDatabase.Name = previousName;
|
|
||||||
db.KpDatabase.NameChanged = previousNameChanged;
|
|
||||||
Toast.MakeText(this, message, ToastLength.Long).Show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Name is reflected in notification, so update it
|
|
||||||
App.Kp2a.UpdateOngoingNotification();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
ProgressTask pt = new ProgressTask(App.Kp2a, this, save);
|
|
||||||
pt.Run();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Preference changeMaster = FindPreference(GetString(Resource.String.master_pwd_key));
|
|
||||||
if (App.Kp2a.GetDb().CanWrite)
|
|
||||||
{
|
|
||||||
changeMaster.Enabled = true;
|
|
||||||
changeMaster.PreferenceClick += delegate {
|
|
||||||
new SetPasswordDialog(this).Show();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//depending on Android version, we offer to use a transparent icon for QuickUnlock or use the notification priority (since API level 16)
|
|
||||||
Preference hideQuickUnlockTranspIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key));
|
|
||||||
Preference hideQuickUnlockIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden16_key));
|
|
||||||
var quickUnlockScreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.QuickUnlock_prefs_key)));
|
|
||||||
if ((int)Android.OS.Build.VERSION.SdkInt >= 16)
|
|
||||||
{
|
|
||||||
quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
|
|
||||||
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)).PreferenceChange += (sender, args) => App.Kp2a.UpdateOngoingNotification();
|
|
||||||
hideQuickUnlockIconPref.PreferenceChange += delegate { App.Kp2a.UpdateOngoingNotification(); };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//old version: only show transparent quickUnlock and no option to hide unlocked icon:
|
|
||||||
quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
|
|
||||||
FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key)).PreferenceChange +=
|
|
||||||
delegate { App.Kp2a.UpdateOngoingNotification(); };
|
|
||||||
|
|
||||||
((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(
|
|
||||||
FindPreference(GetString(Resource.String.ShowUnlockedNotification_key)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Kp2aLog.Log(ex.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
SetRounds(db, rounds);
|
|
||||||
|
|
||||||
Preference algorithm = FindPreference(GetString(Resource.String.algorithm_key));
|
|
||||||
SetAlgorithm(db, algorithm);
|
|
||||||
|
|
||||||
UpdateImportDbPref();
|
|
||||||
UpdateImportKeyfilePref();
|
|
||||||
//AppSettingsActivity.PrepareKeyboardSwitchingPreferences(this);
|
|
||||||
_switchPrefManager = new AppSettingsActivity.KeyboardSwitchPrefManager(this);
|
|
||||||
AppSettingsActivity.PrepareSeparateNotificationsPreference(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateImportKeyfilePref()
|
|
||||||
{
|
|
||||||
var prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
|
||||||
var rememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
|
||||||
|
|
||||||
Preference importDb = FindPreference("import_keyfile_prefs");
|
|
||||||
importDb.Summary = "";
|
|
||||||
|
|
||||||
if (!rememberKeyfile)
|
|
||||||
{
|
|
||||||
importDb.Summary = GetString(Resource.String.KeyfileMoveRequiresRememberKeyfile);
|
|
||||||
importDb.Enabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CompositeKey masterKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
|
||||||
if (masterKey.ContainsType(typeof (KcpKeyFile)))
|
|
||||||
{
|
|
||||||
IOConnectionInfo iocKeyfile = ((KcpKeyFile)masterKey.GetUserKey(typeof (KcpKeyFile))).Ioc;
|
|
||||||
if (iocKeyfile.IsLocalFile() && IoUtil.IsInInternalDirectory(iocKeyfile.Path, this))
|
|
||||||
{
|
|
||||||
importDb.Enabled = false;
|
|
||||||
importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
importDb.Enabled = true;
|
|
||||||
importDb.PreferenceClick += (sender, args) => { MoveKeyfileToInternalFolder();};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
importDb.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MoveKeyfileToInternalFolder()
|
|
||||||
{
|
|
||||||
Func<Action> copyAndReturnPostExecute = () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CompositeKey masterKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
|
||||||
var sourceIoc = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
|
|
||||||
var newIoc = ImportFileToInternalDirectory(sourceIoc);
|
|
||||||
((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
|
|
||||||
var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
|
|
||||||
App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.GetDb().Ioc, keyfileString);
|
|
||||||
return () =>
|
|
||||||
{
|
|
||||||
UpdateImportKeyfilePref();
|
|
||||||
var builder = new AlertDialog.Builder(this);
|
|
||||||
builder
|
|
||||||
.SetMessage(Resource.String.KeyfileMoved);
|
|
||||||
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => { });
|
|
||||||
builder.Show();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
return () =>
|
|
||||||
{
|
|
||||||
Toast.MakeText(this, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
new SimpleLoadingDialog(this, GetString(Resource.String.CopyingFile), false,
|
|
||||||
copyAndReturnPostExecute
|
|
||||||
).Execute();
|
|
||||||
|
|
||||||
}
|
|
||||||
private void UpdateImportDbPref()
|
|
||||||
{
|
|
||||||
//Import db/key file preferences:
|
|
||||||
Preference importDb = FindPreference("import_db_prefs");
|
|
||||||
if (!App.Kp2a.GetDb().Ioc.IsLocalFile())
|
|
||||||
{
|
|
||||||
importDb.Summary = GetString(Resource.String.OnlyAvailableForLocalFiles);
|
|
||||||
importDb.Enabled = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (IoUtil.IsInInternalDirectory(App.Kp2a.GetDb().Ioc.Path, this))
|
|
||||||
{
|
|
||||||
importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
|
|
||||||
importDb.Enabled = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
importDb.Enabled = true;
|
|
||||||
importDb.PreferenceClick += delegate { MoveDbToInternalFolder(); };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MoveDbToInternalFolder()
|
|
||||||
{
|
|
||||||
Func<Action> copyAndReturnPostExecute = () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var sourceIoc = App.Kp2a.GetDb().Ioc;
|
|
||||||
var newIoc = ImportFileToInternalDirectory(sourceIoc);
|
|
||||||
return () =>
|
|
||||||
{
|
|
||||||
var builder = new AlertDialog.Builder(this);
|
|
||||||
builder
|
|
||||||
.SetMessage(Resource.String.DatabaseFileMoved);
|
|
||||||
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
|
|
||||||
PasswordActivity.Launch(this, newIoc, new NullTask()));
|
|
||||||
builder.Show();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
return () =>
|
|
||||||
{
|
|
||||||
Toast.MakeText(this, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
new SimpleLoadingDialog(this, GetString(Resource.String.CopyingFile), false,
|
|
||||||
copyAndReturnPostExecute
|
|
||||||
).Execute();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc)
|
|
||||||
{
|
|
||||||
string targetPath = UrlUtil.GetFileName(sourceIoc.Path);
|
|
||||||
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
|
|
||||||
if (targetPath == "")
|
|
||||||
targetPath = "imported";
|
|
||||||
if (new File(FilesDir, targetPath).Exists())
|
|
||||||
{
|
|
||||||
int c = 1;
|
|
||||||
var ext = UrlUtil.GetExtension(targetPath);
|
|
||||||
var filenameWithoutExt = UrlUtil.StripExtension(targetPath);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c++;
|
|
||||||
targetPath = filenameWithoutExt + c;
|
|
||||||
if (!String.IsNullOrEmpty(ext))
|
|
||||||
targetPath += "." + ext;
|
|
||||||
} while (new File(FilesDir, targetPath).Exists());
|
|
||||||
}
|
|
||||||
var targetIoc = IOConnectionInfo.FromPath(new File(FilesDir, targetPath).CanonicalPath);
|
|
||||||
|
|
||||||
IoUtil.Copy(targetIoc, sourceIoc, App.Kp2a);
|
|
||||||
return targetIoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetRounds(Database db, Preference rounds)
|
|
||||||
{
|
|
||||||
rounds.Summary = db.KpDatabase.KeyEncryptionRounds.ToString(CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetAlgorithm(Database db, Preference algorithm)
|
|
||||||
{
|
|
||||||
algorithm.Summary = CipherPool.GlobalPool.GetCipher(db.KpDatabase.DataCipherUuid).DisplayName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user