diff --git a/src/keepass2android/EntryActivity.cs b/src/keepass2android/EntryActivity.cs index c325f9d3..7a5277e4 100644 --- a/src/keepass2android/EntryActivity.cs +++ b/src/keepass2android/EntryActivity.cs @@ -50,7 +50,7 @@ namespace keepass2android public const String KEY_CLOSE_AFTER_CREATE = "close_after_create"; - public static void Launch(Activity act, PwEntry pw, int pos, IAppTask appTask) { + public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask) { Intent i; i = new Intent(act, typeof(EntryActivity)); @@ -69,7 +69,7 @@ namespace keepass2android private bool mShowPassword; private int mPos; - IAppTask mAppTask; + AppTask mAppTask; protected void setEntryView() { diff --git a/src/keepass2android/EntryEditActivity.cs b/src/keepass2android/EntryEditActivity.cs index 33ec9f3d..ec1cfd02 100644 --- a/src/keepass2android/EntryEditActivity.cs +++ b/src/keepass2android/EntryEditActivity.cs @@ -73,6 +73,8 @@ namespace keepass2android private ScrollView scroll; bool mCloseForReload; + + AppTask mAppTask; protected override void OnCreate(Bundle savedInstanceState) { @@ -86,6 +88,8 @@ namespace keepass2android return; } + mAppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent); + SetContentView(Resource.Layout.entry_edit); mCloseForReload = false; @@ -234,9 +238,7 @@ namespace keepass2android } save.Click += (object sender, EventArgs e) => { - OnFinish onFinish = new AfterSave(new Handler(), this); - - SaveEntry(onFinish); + SaveEntry(); }; @@ -284,7 +286,7 @@ namespace keepass2android } - void SaveEntry(OnFinish onFinish) + void SaveEntry() { Database db = App.getDB(); EntryEditActivity act = this; @@ -358,9 +360,7 @@ namespace keepass2android if(bUndoBackup) newEntry.History.RemoveAt(newEntry.History.UCount - 1); newEntry.MaintainBackups(db.pm); - - - + //if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(State.mEntry.Strings.ReadSafe (PwDefs.TitleField)) ) { // SetResult(KeePass.EXIT_REFRESH); //} else { @@ -368,15 +368,30 @@ namespace keepass2android SetResult(KeePass.EXIT_REFRESH_TITLE); //} - RunnableOnFinish task; - - + RunnableOnFinish runnable; + + ActionOnFinish closeOrShowError = new ActionOnFinish((success, message) => { + if (success) + { + Finish(); + } else + { + OnFinish.displayMessage(this, message); + } + }); + + ActionOnFinish afterAddEntry = new ActionOnFinish((success, message) => + { + if (success) + mAppTask.AfterAddNewEntry(this); + },closeOrShowError); + if ( State.mIsNew ) { - task = AddEntry.getInstance(this, App.getDB(), newEntry, State.parentGroup, onFinish); + runnable = AddEntry.getInstance(this, App.getDB(), newEntry, State.parentGroup, afterAddEntry); } else { - task = new UpdateEntry(this, App.getDB(), initialEntry, newEntry, onFinish); + runnable = new UpdateEntry(this, App.getDB(), initialEntry, newEntry, closeOrShowError); } - ProgressTask pt = new ProgressTask(act, task, Resource.String.saving_database); + ProgressTask pt = new ProgressTask(act, runnable, Resource.String.saving_database); pt.run(); @@ -535,6 +550,12 @@ namespace keepass2android populateBinaries(); } + protected override void OnSaveInstanceState(Bundle outState) + { + base.OnSaveInstanceState(outState); + mAppTask.ToBundle(outState); + } + public override void OnBackPressed() { if (State.mEntryModified == false) @@ -901,22 +922,6 @@ namespace keepass2android } - private class AfterSave : OnFinish { - Activity act; - public AfterSave(Handler handler, Activity act): base(handler) { - this.act = act; - } - - - public override void run() { - if ( mSuccess ) { - act.Finish(); - } else { - displayMessage(act); - } - } - - } } diff --git a/src/keepass2android/GroupActivity.cs b/src/keepass2android/GroupActivity.cs index 3b3b3eca..3c7f2a51 100644 --- a/src/keepass2android/GroupActivity.cs +++ b/src/keepass2android/GroupActivity.cs @@ -45,11 +45,11 @@ namespace keepass2android private const String TAG = "Group Activity:"; - public static void Launch(Activity act, IAppTask appTask) { + public static void Launch(Activity act, AppTask appTask) { Launch(act, null, appTask); } - public static void Launch (Activity act, PwGroup g, IAppTask appTask) + public static void Launch (Activity act, PwGroup g, AppTask appTask) { Intent i; diff --git a/src/keepass2android/GroupBaseActivity.cs b/src/keepass2android/GroupBaseActivity.cs index 84bbfb85..5376010e 100644 --- a/src/keepass2android/GroupBaseActivity.cs +++ b/src/keepass2android/GroupBaseActivity.cs @@ -63,7 +63,7 @@ namespace keepass2android protected PwGroup mGroup; - internal IAppTask mAppTask; + internal AppTask mAppTask; protected override void OnResume() { base.OnResume(); diff --git a/src/keepass2android/PasswordActivity.cs b/src/keepass2android/PasswordActivity.cs index 2ade556a..e2f55290 100644 --- a/src/keepass2android/PasswordActivity.cs +++ b/src/keepass2android/PasswordActivity.cs @@ -87,7 +87,7 @@ namespace keepass2android ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(KEY_SERVERCREDMODE, (int) IOCredSaveMode.NoSave); } - public static void Launch(Activity act, String fileName, IAppTask appTask) { + public static void Launch(Activity act, String fileName, AppTask appTask) { Java.IO.File dbFile = new Java.IO.File(fileName); if ( ! dbFile.Exists() ) { throw new Java.IO.FileNotFoundException(); @@ -108,7 +108,7 @@ namespace keepass2android } - public static void Launch(Activity act, IOConnectionInfo ioc, IAppTask appTask) + public static void Launch(Activity act, IOConnectionInfo ioc, AppTask appTask) { if (ioc.IsLocalFile()) { @@ -279,7 +279,7 @@ namespace keepass2android } - internal IAppTask mAppTask; + internal AppTask mAppTask; protected override void OnCreate(Bundle savedInstanceState) { diff --git a/src/keepass2android/app/AppTask.cs b/src/keepass2android/app/AppTask.cs index 28f650bd..8d2f8a90 100644 --- a/src/keepass2android/app/AppTask.cs +++ b/src/keepass2android/app/AppTask.cs @@ -62,131 +62,48 @@ namespace keepass2android } /// - /// interface for "tasks": this are things the user wants to do and which require several activities + /// base class for "tasks": this are things the user wants to do and which require several activities /// - public interface IAppTask + public abstract class AppTask { /// /// Loads the parameters of the task from the given bundle /// - void Setup(Bundle b); + public virtual void Setup(Bundle b) + {} /// /// Returns the parameters of the task for storage in a bundle or intent /// /// The extras. - IEnumerable Extras { get;} - - void AfterUnlockDatabase(PasswordActivity act); - - bool CloseEntryActivityAfterCreate - { - get; - } - } - - /// - /// Implementation of IAppTask for "no task currently active" (Null pattern) - /// - public class NullTask: IAppTask - { - - public void Setup(Bundle b) - { - } - - public IEnumerable Extras - { + public virtual IEnumerable Extras { get { yield break; } } - - public void AfterUnlockDatabase(PasswordActivity act) + public virtual void AfterUnlockDatabase(PasswordActivity act) { GroupActivity.Launch(act, this); } - public bool CloseEntryActivityAfterCreate + + public virtual void AfterAddNewEntry(EntryEditActivity entryEditActivity) + { + } + + public virtual bool CloseEntryActivityAfterCreate { get { return false;} } - } - /// - /// User is about to search an entry for a given URL - /// - public class SearchUrlTask: IAppTask - { - public const String UrlToSearch_key = "UrlToSearch"; - - public string UrlToSearchFor - { - get; - set; - } - - public void Setup(Bundle b) - { - UrlToSearchFor = b.GetString(UrlToSearch_key); - } - public IEnumerable Extras - { - get - { - yield return new StringExtra() { Key=UrlToSearch_key, Value = UrlToSearchFor }; - } - } - public void AfterUnlockDatabase(PasswordActivity act) - { - ShareUrlResults.Launch(act, this); - } - public bool CloseEntryActivityAfterCreate - { - get { return true;} - } - } - - - /// - /// User is about to select an entry for use in another app - /// - public class SelectEntryTask: IAppTask - { - public void Setup(Bundle b) - { - } - public IEnumerable Extras - { - get - { - yield break; - } - } - public void AfterUnlockDatabase(PasswordActivity act) - { - GroupActivity.Launch(act, this); - } - public bool CloseEntryActivityAfterCreate - { - //keypoint here: close the app after selecting the entry - get { return true;} - } - } - - /// - /// - /// - public static class AppTask - { public const String AppTask_key = "KP2A_APPTASK"; /// /// Should be used in OnCreate to (re)create a task /// if savedInstanceState is not null, the task is recreated from there. Otherwise it's taken from the intent. /// - public static IAppTask GetTaskInOnCreate(Bundle savedInstanceState, Intent intent) + public static AppTask GetTaskInOnCreate(Bundle savedInstanceState, Intent intent) { if (savedInstanceState != null) { @@ -198,12 +115,12 @@ namespace keepass2android } } - public static IAppTask CreateFromIntent(Intent i) + public static AppTask CreateFromIntent(Intent i) { return CreateFromBundle(i.Extras); } - public static IAppTask CreateFromBundle(Bundle b) + public static AppTask CreateFromBundle(Bundle b) { if (b == null) return new NullTask(); @@ -219,7 +136,7 @@ namespace keepass2android { if (taskType == type.Name) { - IAppTask task = (IAppTask)Activator.CreateInstance(type); + AppTask task = (AppTask)Activator.CreateInstance(type); task.Setup(b); return task; } @@ -231,11 +148,11 @@ namespace keepass2android /// /// Adds the extras of the task to the intent /// - public static void ToIntent(this IAppTask task, Intent intent) + public void ToIntent(Intent intent) { - AppTask.GetTypeExtra(task.GetType()).ToIntent(intent); + AppTask.GetTypeExtra(GetType()).ToIntent(intent); - foreach (IExtra extra in task.Extras) + foreach (IExtra extra in Extras) { extra.ToIntent(intent); } @@ -244,11 +161,11 @@ namespace keepass2android /// /// Adds the extras of the task to the bundle /// - public static void ToBundle(this IAppTask task, Bundle bundle) + public void ToBundle(Bundle bundle) { - AppTask.GetTypeExtra(task.GetType()).ToBundle(bundle); + AppTask.GetTypeExtra(GetType()).ToBundle(bundle); - foreach (IExtra extra in task.Extras) + foreach (IExtra extra in Extras) { extra.ToBundle(bundle); } @@ -264,5 +181,94 @@ namespace keepass2android } } + + /// + /// Implementation of AppTask for "no task currently active" (Null pattern) + /// + public class NullTask: AppTask + { + + } + + /// + /// User is about to search an entry for a given URL + /// + public class SearchUrlTask: AppTask + { + public const String UrlToSearch_key = "UrlToSearch"; + + public string UrlToSearchFor + { + get; + set; + } + + public override void Setup(Bundle b) + { + UrlToSearchFor = b.GetString(UrlToSearch_key); + } + public override IEnumerable Extras + { + get + { + yield return new StringExtra() { Key=UrlToSearch_key, Value = UrlToSearchFor }; + } + } + public override void AfterUnlockDatabase(PasswordActivity act) + { + ShareUrlResults.Launch(act, this); + } + public override bool CloseEntryActivityAfterCreate + { + get { return true;} + } + } + + + /// + /// User is about to select an entry for use in another app + /// + public class SelectEntryTask: AppTask + { + + public override bool CloseEntryActivityAfterCreate + { + //keypoint here: close the app after selecting the entry + get { return true;} + } + } + + + /// + /// User is about to create a new entry. The task might already "know" some information about the contents. + /// + public class CreateEntryThenCloseTask: AppTask + { + public const String Url_key = "CreateEntry_Url"; + + public string Url + { + get; + set; + } + + public override void Setup(Bundle b) + { + Url = b.GetString(Url_key); + } + public override IEnumerable Extras + { + get + { + yield return new StringExtra() { Key = Url_key, Value = Url }; + yield break; + } + } + public override bool CloseEntryActivityAfterCreate + { + //if the user selects an entry before creating the new one, we're not closing the app + get { return false;} + } + } } diff --git a/src/keepass2android/database/edit/OnFinish.cs b/src/keepass2android/database/edit/OnFinish.cs index ee105fe9..67e3094f 100644 --- a/src/keepass2android/database/edit/OnFinish.cs +++ b/src/keepass2android/database/edit/OnFinish.cs @@ -78,11 +78,15 @@ namespace keepass2android } protected void displayMessage(Context ctx) { - if ( mMessage != null && mMessage.Length > 0 ) { - Toast.MakeText(ctx, mMessage, ToastLength.Long).Show(); - } + displayMessage(ctx, mMessage); } + public static void displayMessage(Context ctx, string message) + { + if ( !String.IsNullOrEmpty(message) ) { + Toast.MakeText(ctx, message, ToastLength.Long).Show(); + } + } } } diff --git a/src/keepass2android/fileselect/FileSelectActivity.cs b/src/keepass2android/fileselect/FileSelectActivity.cs index 39ba3d67..286ba053 100644 --- a/src/keepass2android/fileselect/FileSelectActivity.cs +++ b/src/keepass2android/fileselect/FileSelectActivity.cs @@ -64,7 +64,7 @@ namespace keepass2android view.FileSelectButtons fileSelectButtons; bool createdWithActivityResult = false; - internal IAppTask mAppTask; + internal AppTask mAppTask; IOConnectionInfo loadIoc(string defaultFileName) {