Add toolbar to Settings (involves reorganization of Settings into Fragmnt which removes duplicate code in both activities)

This commit is contained in:
Philipp Crocoll 2015-08-13 17:37:01 +02:00
parent 15f73257fa
commit fabe0904c0
12 changed files with 710 additions and 603 deletions

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

View 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>

View 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" />

View File

@ -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"

View File

@ -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)
);
}
}
} }
} }

View File

@ -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>

View File

@ -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();
}
} }
} }

View File

@ -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;
}
} }
} }