diff --git a/.gitignore b/.gitignore index c8a63025..ef284c85 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ /src/java/KP2ASoftKeyboard/projectzip /src/java/KP2ASoftKeyboard/createProjectZip.bat Thumbs.db + +/src/monodroid-unittesting/*.suo diff --git a/src/KeePass.sln b/src/KeePass.sln index 0b73d48e..e2c3baef 100644 --- a/src/KeePass.sln +++ b/src/KeePass.sln @@ -1,6 +1,6 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android", "keepass2android\keepass2android.csproj", "{A6CF8A86-37C1-4197-80FE-519DE2C842F5}" @@ -9,6 +9,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kp2akeytransform", "kp2akey EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aKeyboardBinding", "Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj", "{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBusinessLogic\Kp2aBusinessLogic.csproj", "{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDroidUnitTesting", "monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj", "{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aUnitTests", "Kp2aUnitTests\Kp2aUnitTests.csproj", "{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,6 +26,9 @@ Global Release|Win32 = Release|Win32 Release|x64 = Release|x64 ReleaseNoNet|Any CPU = ReleaseNoNet|Any CPU + ReleaseNoNet|Mixed Platforms = ReleaseNoNet|Mixed Platforms + ReleaseNoNet|Win32 = ReleaseNoNet|Win32 + ReleaseNoNet|x64 = ReleaseNoNet|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -40,6 +49,34 @@ Global {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.Build.0 = Release|Any CPU {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.ActiveCfg = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.ActiveCfg = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.Build.0 = Release|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Mixed Platforms.Deploy.0 = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU + {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU {A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Any CPU.Build.0 = Debug|Any CPU {A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -58,24 +95,10 @@ Global {A57B3ACE-5634-469A-88C4-858BB409F356}.Release|x64.Build.0 = Release|Any CPU {A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU {A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.ActiveCfg = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.Build.0 = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.ActiveCfg = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.ActiveCfg = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.Build.0 = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.ActiveCfg = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.Build.0 = Release|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU - {A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU + {A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU + {A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU + {A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU + {A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -94,7 +117,73 @@ Global {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU - + {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU + {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU + {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU + {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Win32.ActiveCfg = Debug|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|x64.ActiveCfg = Debug|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Any CPU.Build.0 = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Win32.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|x64.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|x64.ActiveCfg = Debug|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Any CPU.Build.0 = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Win32.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|x64.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Win32.ActiveCfg = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|x64.ActiveCfg = Debug|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.Build.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.Deploy.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Win32.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|x64.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = keepass2android\keepass2android.csproj @@ -102,7 +191,7 @@ Global $0.DotNetNamingPolicy = $1 $1.DirectoryNamespaceAssociation = None $1.ResourceNamePolicy = FileFormatDefault - $0.TextStylePolicy = $2 + $0.TextStylePolicy = $5 $2.FileWidth = 120 $2.TabsToSpaces = False $2.inheritsSet = VisualStudio @@ -127,13 +216,11 @@ Global $3.inheritsSet = Mono $3.inheritsScope = text/x-csharp $3.scope = text/x-csharp - $0.TextStylePolicy = $4 $4.FileWidth = 120 $4.TabsToSpaces = False $4.inheritsSet = VisualStudio $4.inheritsScope = text/plain $4.scope = text/plain - $0.TextStylePolicy = $5 $5.inheritsSet = null $5.scope = application/xml $0.XmlFormattingPolicy = $6 @@ -144,7 +231,4 @@ Global $7.Text = @/*\nThis file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.\n\n Keepass2Android is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 2 of the License, or\n (at your option) any later version.\n\n Keepass2Android is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with Keepass2Android. If not, see .\n */\n $7.IncludeInNewFiles = True EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection EndGlobal diff --git a/src/Kp2aBusinessLogic/IDrawableFactory.cs b/src/Kp2aBusinessLogic/IDrawableFactory.cs new file mode 100644 index 00000000..a832ff31 --- /dev/null +++ b/src/Kp2aBusinessLogic/IDrawableFactory.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.Content.Res; +using KeePassLib; +using Android.Graphics.Drawables; + +namespace keepass2android +{ + public interface IDrawableFactory + { + void assignDrawableTo (ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId); + + Drawable getIconDrawable(Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId); + + + void Clear(); + } +} \ No newline at end of file diff --git a/src/Kp2aBusinessLogic/IKp2aApp.cs b/src/Kp2aBusinessLogic/IKp2aApp.cs new file mode 100644 index 00000000..3b7fbc81 --- /dev/null +++ b/src/Kp2aBusinessLogic/IKp2aApp.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib.Serialization; + +namespace keepass2android +{ + public interface IKp2aApp + { + void SetShutdown(); + Database GetDb(); + + void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile); + + Database CreateNewDatabase(); + + string GetResourceString(UiStringKey stringKey); + + bool GetBooleanPreference(PreferenceKey key); + + void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey, + EventHandler yesHandler, + EventHandler noHandler, + EventHandler cancelHandler, + Context ctx); + } +} \ No newline at end of file diff --git a/src/keepass2android/KeyFileException.cs b/src/Kp2aBusinessLogic/KeyFileException.cs similarity index 100% rename from src/keepass2android/KeyFileException.cs rename to src/Kp2aBusinessLogic/KeyFileException.cs diff --git a/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj b/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj new file mode 100644 index 00000000..d7082ff4 --- /dev/null +++ b/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj @@ -0,0 +1,86 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA} + {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Properties + keepass2android + Kp2aBusinessLogic + 512 + Resources\Resource.Designer.cs + Off + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {545b4a6b-8bba-4fbe-92fc-4ac060122a54} + KeePassLib2Android + + + + + \ No newline at end of file diff --git a/src/Kp2aBusinessLogic/PreferenceKey.cs b/src/Kp2aBusinessLogic/PreferenceKey.cs new file mode 100644 index 00000000..cedc9ba3 --- /dev/null +++ b/src/Kp2aBusinessLogic/PreferenceKey.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + public enum PreferenceKey + { + remember_keyfile, + UseFileTransactions + } +} \ No newline at end of file diff --git a/src/keepass2android/ProgressTask.cs b/src/Kp2aBusinessLogic/ProgressTask.cs similarity index 83% rename from src/keepass2android/ProgressTask.cs rename to src/Kp2aBusinessLogic/ProgressTask.cs index e6f20b1e..094a1402 100644 --- a/src/keepass2android/ProgressTask.cs +++ b/src/Kp2aBusinessLogic/ProgressTask.cs @@ -35,19 +35,20 @@ namespace keepass2android private Handler mHandler; private RunnableOnFinish mTask; private ProgressDialog mPd; + private IKp2aApp mApp; - public ProgressTask(Context ctx, RunnableOnFinish task, int messageId) { - mCtx = ctx; + public ProgressTask(IKp2aApp app, Context ctx, RunnableOnFinish task, UiStringKey messageKey) { mTask = task; mHandler = new Handler(); + mApp = app; // Show process dialog - mPd = new ProgressDialog(mCtx); - mPd.SetTitle(ctx.GetText(Resource.String.progress_title)); - mPd.SetMessage(ctx.GetText(messageId)); + mPd = new ProgressDialog(ctx); + mPd.SetTitle(mApp.GetResourceString(UiStringKey.progress_title)); + mPd.SetMessage(mApp.GetResourceString(messageKey)); // Set code to run when this is finished - mTask.setStatus(new UpdateStatus(ctx, mHandler, mPd)); + mTask.setStatus(new UpdateStatus(mApp, mHandler, mPd)); mTask.mFinish = new AfterTask(task.mFinish, mHandler, mPd); } diff --git a/src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs b/src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b65267bb --- /dev/null +++ b/src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Android.App; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Kp2aBusinessLogic")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Kp2aBusinessLogic")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +// Add some common permissions, these can be removed if not needed +[assembly: UsesPermission(Android.Manifest.Permission.Internet)] +[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] diff --git a/src/keepass2android/PwGroupEqualityFromIdComparer.cs b/src/Kp2aBusinessLogic/PwGroupEqualityFromIdComparer.cs similarity index 100% rename from src/keepass2android/PwGroupEqualityFromIdComparer.cs rename to src/Kp2aBusinessLogic/PwGroupEqualityFromIdComparer.cs diff --git a/src/keepass2android/PwUuidEqualityComparer.cs b/src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs similarity index 95% rename from src/keepass2android/PwUuidEqualityComparer.cs rename to src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs index f769ff03..b0307ed6 100644 --- a/src/keepass2android/PwUuidEqualityComparer.cs +++ b/src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs @@ -31,7 +31,7 @@ using KeePassLib; namespace keepass2android { - class PwUuidEqualityComparer: IEqualityComparer + public class PwUuidEqualityComparer: IEqualityComparer { #region IEqualityComparer implementation public bool Equals (PwUuid x, PwUuid y) diff --git a/src/Kp2aBusinessLogic/Resources/Resource.Designer.cs b/src/Kp2aBusinessLogic/Resources/Resource.Designer.cs new file mode 100644 index 00000000..e69de29b diff --git a/src/keepass2android/search/SearchDbHelper.cs b/src/Kp2aBusinessLogic/SearchDbHelper.cs similarity index 89% rename from src/keepass2android/search/SearchDbHelper.cs rename to src/Kp2aBusinessLogic/SearchDbHelper.cs index 41bea8db..45fc60c1 100644 --- a/src/keepass2android/search/SearchDbHelper.cs +++ b/src/Kp2aBusinessLogic/SearchDbHelper.cs @@ -37,11 +37,11 @@ namespace keepass2android { public class SearchDbHelper { + private IKp2aApp mApp; - private readonly Context mCtx; - public SearchDbHelper(Context ctx) { - mCtx = ctx; + public SearchDbHelper(IKp2aApp app) { + mApp = app; } @@ -60,7 +60,7 @@ namespace keepass2android new Regex(sp.SearchString); } - string strGroupName = mCtx.GetString(Resource.String.search_results) + " (\"" + sp.SearchString + "\")"; + string strGroupName = mApp.GetResourceString(UiStringKey.search_results) + " (\"" + sp.SearchString + "\")"; PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch); pgResults.IsVirtual = true; @@ -87,7 +87,7 @@ namespace keepass2android new Regex(sp.SearchString); } - string strGroupName = mCtx.GetString(Resource.String.search_results) + " (\"" + sp.SearchString + "\")"; + string strGroupName = mApp.GetResourceString(UiStringKey.search_results) + " (\"" + sp.SearchString + "\")"; PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch); pgResults.IsVirtual = true; @@ -109,7 +109,7 @@ namespace keepass2android public PwGroup searchForHost(Database database, String url, bool allowSubdomains) { String host = extractHost(url); - string strGroupName = mCtx.GetString(Resource.String.search_results) + " (\"" + host + "\")"; + string strGroupName = mApp.GetResourceString(UiStringKey.search_results) + " (\"" + host + "\")"; PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch); pgResults.IsVirtual = true; if (String.IsNullOrWhiteSpace(host)) diff --git a/src/Kp2aBusinessLogic/UiStringKey.cs b/src/Kp2aBusinessLogic/UiStringKey.cs new file mode 100644 index 00000000..7314b524 --- /dev/null +++ b/src/Kp2aBusinessLogic/UiStringKey.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace keepass2android +{ + public enum UiStringKey + { + AskDeletePermanentlyGroup, + progress_title, + AskDeletePermanentlyEntry, + search_results, + AskDeletePermanently_title, + saving_database, + keyfile_does_not_exist, + RecycleBin, + progress_create, + loading_database + } +} \ No newline at end of file diff --git a/src/keepass2android/UpdateStatus.cs b/src/Kp2aBusinessLogic/UpdateStatus.cs similarity index 83% rename from src/keepass2android/UpdateStatus.cs rename to src/Kp2aBusinessLogic/UpdateStatus.cs index 2fe27848..12c1ab0c 100644 --- a/src/keepass2android/UpdateStatus.cs +++ b/src/Kp2aBusinessLogic/UpdateStatus.cs @@ -32,28 +32,28 @@ namespace keepass2android { public class UpdateStatus: IStatusLogger { private ProgressDialog mPD; - private Context mCtx; + IKp2aApp mApp; private Handler mHandler; public UpdateStatus() { } - public UpdateStatus(Context ctx, Handler handler, ProgressDialog pd) { - mCtx = ctx; + public UpdateStatus(IKp2aApp app, Handler handler, ProgressDialog pd) { + mApp = app; mPD = pd; mHandler = handler; } - public void updateMessage(int resId) { - if ( mCtx != null && mPD != null && mHandler != null ) { - mHandler.Post( () => {mPD.SetMessage(mCtx.GetString(resId));}); + public void updateMessage(UiStringKey stringKey) { + if ( mApp != null && mPD != null && mHandler != null ) { + mHandler.Post( () => {mPD.SetMessage(mApp.GetResourceString(stringKey));}); } } public void updateMessage (String message) { - if ( mCtx != null && mPD != null && mHandler != null ) { + if ( mApp!= null && mPD != null && mHandler != null ) { mHandler.Post(() => {mPD.SetMessage(message); } ); } } diff --git a/src/keepass2android/Database.cs b/src/Kp2aBusinessLogic/database/Database.cs similarity index 75% rename from src/keepass2android/Database.cs rename to src/Kp2aBusinessLogic/database/Database.cs index 08aecdf7..6b53b939 100644 --- a/src/keepass2android/Database.cs +++ b/src/Kp2aBusinessLogic/database/Database.cs @@ -46,11 +46,25 @@ namespace keepass2android public DateTime mLastChangeDate; public SearchDbHelper searchHelper; - public DrawableFactory drawFactory = new DrawableFactory(); + public IDrawableFactory drawableFactory; + + IKp2aApp app; + + public Database(IDrawableFactory drawableFactory, IKp2aApp app) + { + this.drawableFactory = drawableFactory; + this.app = app; + } private bool loaded = false; - private bool mReloadRequested = false; + private bool mReloadRequested = false; + + public bool ReloadRequested + { + get { return mReloadRequested; } + set { mReloadRequested = value; } + } public bool Loaded { get { return loaded;} @@ -84,41 +98,8 @@ namespace keepass2android return System.IO.File.GetLastWriteTimeUtc(mIoc.Path) > mLastChangeDate; } - public void CheckForOpenFileChanged(Activity activity) - { - if (DidOpenFileChange()) - { - if (mReloadRequested) - { - - activity.SetResult(KeePass.EXIT_RELOAD_DB); - activity.Finish(); - } - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title)); - - builder.SetMessage(activity.GetString(Resource.String.AskReloadFile)); - - builder.SetPositiveButton(activity.GetString(Android.Resource.String.Yes), new EventHandler((dlgSender, dlgEvt) => - { - mReloadRequested = true; - activity.SetResult(KeePass.EXIT_RELOAD_DB); - activity.Finish(); - - })); - - builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), new EventHandler((dlgSender, dlgEvt) => - { - - })); - - - Dialog dialog = builder.Create(); - dialog.Show(); - } - } - public void LoadData(Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status) + public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status) { mIoc = iocInfo; @@ -154,7 +135,7 @@ namespace keepass2android Loaded = true; pm = pwDatabase; - searchHelper = new SearchDbHelper(ctx); + searchHelper = new SearchDbHelper(app); } bool quickUnlockEnabled = false; @@ -207,8 +188,8 @@ namespace keepass2android public void SaveData(Context ctx) { - ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(ctx); - pm.UseFileTransactions = prefs.GetBoolean(ctx.GetString(Resource.String.UseFileTransactions_key), true); + + pm.UseFileTransactions = app.GetBooleanPreference(PreferenceKey.UseFileTransactions); pm.Save(null); } @@ -257,7 +238,7 @@ namespace keepass2android groups.Clear(); entries.Clear(); dirty.Clear(); - drawFactory.Clear(); + drawableFactory.Clear(); root = null; pm = null; diff --git a/src/keepass2android/database/edit/ActionOnFinish.cs b/src/Kp2aBusinessLogic/database/edit/ActionOnFinish.cs similarity index 100% rename from src/keepass2android/database/edit/ActionOnFinish.cs rename to src/Kp2aBusinessLogic/database/edit/ActionOnFinish.cs diff --git a/src/keepass2android/database/edit/AddEntry.cs b/src/Kp2aBusinessLogic/database/edit/AddEntry.cs similarity index 100% rename from src/keepass2android/database/edit/AddEntry.cs rename to src/Kp2aBusinessLogic/database/edit/AddEntry.cs diff --git a/src/keepass2android/database/edit/AddGroup.cs b/src/Kp2aBusinessLogic/database/edit/AddGroup.cs similarity index 100% rename from src/keepass2android/database/edit/AddGroup.cs rename to src/Kp2aBusinessLogic/database/edit/AddGroup.cs diff --git a/src/keepass2android/database/edit/CreateDB.cs b/src/Kp2aBusinessLogic/database/edit/CreateDB.cs similarity index 89% rename from src/keepass2android/database/edit/CreateDB.cs rename to src/Kp2aBusinessLogic/database/edit/CreateDB.cs index da8059b1..024b432e 100644 --- a/src/keepass2android/database/edit/CreateDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/CreateDB.cs @@ -39,18 +39,18 @@ namespace keepass2android private IOConnectionInfo mIoc; private bool mDontSave; private Context mCtx; + private IKp2aApp mApp; - public CreateDB(Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) { + public CreateDB(IKp2aApp app, Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) { mCtx = ctx; mIoc = ioc; mDontSave = dontSave; + mApp = app; } public override void run() { - // Create new database record - Database db = new Database(); - App.setDB(db); + Database db = mApp.CreateNewDatabase(); db.pm = new KeePassLib.PwDatabase(); //Key will be changed/created immediately after creation: @@ -66,7 +66,7 @@ namespace keepass2android db.root = db.pm.RootGroup; db.mIoc = mIoc; db.Loaded = true; - db.searchHelper = new SearchDbHelper(mCtx); + db.searchHelper = new SearchDbHelper(mApp); // Add a couple default groups AddGroup internet = AddGroup.getInstance(mCtx, db, "Internet", 1, db.pm.RootGroup, null, true); diff --git a/src/keepass2android/database/edit/DeleteEntry.cs b/src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs similarity index 90% rename from src/keepass2android/database/edit/DeleteEntry.cs rename to src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs index e6fc2e11..9518800f 100644 --- a/src/keepass2android/database/edit/DeleteEntry.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs @@ -31,12 +31,12 @@ using KeePassLib; namespace keepass2android { public class DeleteEntry : DeleteRunnable { - - private PwEntry mEntry; - public DeleteEntry(Context ctx, Database db, PwEntry entry, OnFinish finish):base(finish) { + private PwEntry mEntry; + + public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) { mCtx = ctx; - mDb = db; + mDb = app.GetDb(); mEntry = entry; } @@ -49,11 +49,11 @@ namespace keepass2android } } - protected override int QuestionsResourceId + protected override UiStringKey QuestionsResourceId { get { - return Resource.String.AskDeletePermanentlyEntry; + return UiStringKey.AskDeletePermanentlyEntry; } } @@ -86,7 +86,7 @@ namespace keepass2android } } else { // Let's not bother recovering from a failure to save a deleted entry. It is too much work. - App.setShutdown(); + mApp.SetShutdown(); } }, this.mFinish); @@ -109,7 +109,7 @@ namespace keepass2android mDb.dirty.Add(pgRecycleBin); } else { // Let's not bother recovering from a failure to save a deleted entry. It is too much work. - App.setShutdown(); + mApp.SetShutdown(); } }, this.mFinish); diff --git a/src/keepass2android/database/edit/DeleteGroup.cs b/src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs similarity index 75% rename from src/keepass2android/database/edit/DeleteGroup.cs rename to src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs index b8135319..1fd33124 100644 --- a/src/keepass2android/database/edit/DeleteGroup.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs @@ -34,28 +34,33 @@ namespace keepass2android public class DeleteGroup : DeleteRunnable { private PwGroup mGroup; - private GroupBaseActivity mAct; + private Activity mAct; protected bool mDontSave; - public DeleteGroup(Context ctx, Database db, PwGroup group, GroupBaseActivity act, OnFinish finish):base(finish) { - setMembers(ctx, db, group, act, false); + public DeleteGroup(Context ctx, IKp2aApp app, PwGroup group, Activity act, OnFinish finish) + : base(finish, app) + { + setMembers(ctx, app, group, act, false); } - - public DeleteGroup(Context ctx, Database db, PwGroup group, GroupBaseActivity act, OnFinish finish, bool dontSave):base(finish) { + /* + public DeleteGroup(Context ctx, Database db, PwGroup group, Activity act, OnFinish finish, bool dontSave) + : base(finish) + { setMembers(ctx, db, group, act, dontSave); } - + public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, bool dontSave):base(finish) { setMembers(ctx, db, group, null, dontSave); } - - private void setMembers(Context ctx, Database db, PwGroup group, GroupBaseActivity act, bool dontSave) { - base.setMembers(ctx, db); + */ + private void setMembers(Context ctx, IKp2aApp app, PwGroup group, Activity act, bool dontSave) + { + base.setMembers(ctx, app.GetDb()); mGroup = group; mAct = act; mDontSave = dontSave; - + } public override bool CanRecycle @@ -66,11 +71,11 @@ namespace keepass2android } } - protected override int QuestionsResourceId + protected override UiStringKey QuestionsResourceId { get { - return Resource.String.AskDeletePermanentlyGroup; + return UiStringKey.AskDeletePermanentlyGroup; } } @@ -92,7 +97,7 @@ namespace keepass2android PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now); pd.DeletedObjects.Add(pdo); - mFinish = new AfterDeletePermanently(mFinish, mDb, mGroup); + mFinish = new AfterDeletePermanently(mFinish, mApp, mGroup); } else // Recycle { @@ -113,7 +118,7 @@ namespace keepass2android mDb.dirty.Add(pgParent); } else { // Let's not bother recovering from a failure to save a deleted group. It is too much work. - App.setShutdown(); + mApp.SetShutdown(); } }, this.mFinish); } @@ -126,31 +131,31 @@ namespace keepass2android private class AfterDeletePermanently : OnFinish { - Database mDb; + IKp2aApp mApp; PwGroup mGroup; - public AfterDeletePermanently(OnFinish finish, Database db, PwGroup group):base(finish) { - this.mDb = db; + public AfterDeletePermanently(OnFinish finish, IKp2aApp app, PwGroup group):base(finish) { + this.mApp = app; this.mGroup = group; } public override void run() { if ( mSuccess ) { // Remove from group global - mDb.groups.Remove(mGroup.Uuid); + mApp.GetDb().groups.Remove(mGroup.Uuid); // Remove group from the dirty global (if it is present), not a big deal if this fails (doesn't throw) - mDb.dirty.Remove(mGroup); + mApp.GetDb().dirty.Remove(mGroup); // Mark parent dirty PwGroup parent = mGroup.ParentGroup; if ( parent != null ) { - mDb.dirty.Add(parent); + mApp.GetDb().dirty.Add(parent); } } else { // Let's not bother recovering from a failure to save a deleted group. It is too much work. - App.setShutdown(); + mApp.SetShutdown(); } base.run(); diff --git a/src/keepass2android/database/edit/DeleteRunnable.cs b/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs similarity index 64% rename from src/keepass2android/database/edit/DeleteRunnable.cs rename to src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs index 79f5d3b0..738ff1a9 100644 --- a/src/keepass2android/database/edit/DeleteRunnable.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs @@ -1,146 +1,142 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Android.App; -using Android.Content; -using Android.OS; -using Android.Runtime; -using Android.Views; -using Android.Widget; -using KeePassLib; - -namespace keepass2android -{ - public abstract class DeleteRunnable : RunnableOnFinish - { - public DeleteRunnable(OnFinish finish):base(finish) - { - } - - protected Database mDb; - - protected Context mCtx; - - protected void setMembers(Context ctx, Database db) - { - mCtx = ctx; - mDb = db; - } - - - private bool mDeletePermanently = true; - - public bool DeletePermanently - { - get - { - return mDeletePermanently; - } - set - { - mDeletePermanently = value; - } - } - - public abstract bool CanRecycle - { - get; - } - - protected bool CanRecycleGroup(PwGroup pgParent) - { - bool bShiftPressed = false; - PwDatabase pd = mDb.pm; - PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true); - bool bPermanent = false; - if (pgParent != null) - { - if (pd.RecycleBinEnabled == false) - bPermanent = true; - else if (bShiftPressed) - bPermanent = true; - else if (pgRecycleBin == null) - { - } // Recycle - else if (pgParent == pgRecycleBin) - bPermanent = true; - else if (pgParent.IsContainedIn(pgRecycleBin)) - bPermanent = true; - } - return !bPermanent; - } - - - protected void EnsureRecycleBin(ref PwGroup pgRecycleBin, - ref bool bGroupListUpdateRequired) - { - if ((mDb == null) || (mDb.pm == null)) { return; } - - if(pgRecycleBin == mDb.pm.RootGroup) - { - pgRecycleBin = null; - } - - if(pgRecycleBin == null) - { - pgRecycleBin = new PwGroup(true, true, mCtx.GetString(Resource.String.RecycleBin), - PwIcon.TrashBin); - pgRecycleBin.EnableAutoType = false; - pgRecycleBin.EnableSearching = false; - pgRecycleBin.IsExpanded = false; - mDb.pm.RootGroup.AddGroup(pgRecycleBin, true); - - mDb.pm.RecycleBinUuid = pgRecycleBin.Uuid; - - bGroupListUpdateRequired = true; - } - else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.EqualsValue(mDb.pm.RecycleBinUuid)); } - } - - protected abstract int QuestionsResourceId - { - get; - } - - public void start() - { - if (CanRecycle) - { - AlertDialog.Builder builder = new AlertDialog.Builder(mCtx); - builder.SetTitle(mCtx.GetString(Resource.String.AskDeletePermanently_title)); - - builder.SetMessage(mCtx.GetString(QuestionsResourceId)); - - builder.SetPositiveButton(Resource.String.yes, new EventHandler((dlgSender, dlgEvt) => - { - DeletePermanently = true; - ProgressTask pt = new ProgressTask(mCtx, this, Resource.String.saving_database); - pt.run(); - })); - - builder.SetNegativeButton(Resource.String.no, new EventHandler((dlgSender, dlgEvt) => { - DeletePermanently = false; - ProgressTask pt = new ProgressTask(mCtx, this, Resource.String.saving_database); - pt.run(); - })); - - builder.SetNeutralButton(mCtx.GetString(Android.Resource.String.Cancel), - new EventHandler((dlgSender, dlgEvt) => {})); - - Dialog dialog = builder.Create(); - dialog.Show(); - - - } else - { - ProgressTask pt = new ProgressTask(mCtx, this, Resource.String.saving_database); - pt.run(); - } - } - - } -} - + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using KeePassLib; + +namespace keepass2android +{ + public abstract class DeleteRunnable : RunnableOnFinish + { + public DeleteRunnable(OnFinish finish, IKp2aApp app):base(finish) + { + mApp = app; + } + + protected IKp2aApp mApp; + + protected Database mDb; + + protected Context mCtx; + + protected void setMembers(Context ctx, Database db) + { + mCtx = ctx; + mDb = db; + } + + + private bool mDeletePermanently = true; + + public bool DeletePermanently + { + get + { + return mDeletePermanently; + } + set + { + mDeletePermanently = value; + } + } + + public abstract bool CanRecycle + { + get; + } + + protected bool CanRecycleGroup(PwGroup pgParent) + { + bool bShiftPressed = false; + PwDatabase pd = mDb.pm; + PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true); + bool bPermanent = false; + if (pgParent != null) + { + if (pd.RecycleBinEnabled == false) + bPermanent = true; + else if (bShiftPressed) + bPermanent = true; + else if (pgRecycleBin == null) + { + } // Recycle + else if (pgParent == pgRecycleBin) + bPermanent = true; + else if (pgParent.IsContainedIn(pgRecycleBin)) + bPermanent = true; + } + return !bPermanent; + } + + + protected void EnsureRecycleBin(ref PwGroup pgRecycleBin, + ref bool bGroupListUpdateRequired) + { + if ((mDb == null) || (mDb.pm == null)) { return; } + + if(pgRecycleBin == mDb.pm.RootGroup) + { + pgRecycleBin = null; + } + + if(pgRecycleBin == null) + { + pgRecycleBin = new PwGroup(true, true, mApp.GetResourceString(UiStringKey.RecycleBin), + PwIcon.TrashBin); + pgRecycleBin.EnableAutoType = false; + pgRecycleBin.EnableSearching = false; + pgRecycleBin.IsExpanded = false; + mDb.pm.RootGroup.AddGroup(pgRecycleBin, true); + + mDb.pm.RecycleBinUuid = pgRecycleBin.Uuid; + + bGroupListUpdateRequired = true; + } + else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.EqualsValue(mDb.pm.RecycleBinUuid)); } + } + + protected abstract UiStringKey QuestionsResourceId + { + get; + } + + public void start() + { + if (CanRecycle) + { + mApp.AskYesNoCancel(UiStringKey.AskDeletePermanently_title, + QuestionsResourceId, + new EventHandler((dlgSender, dlgEvt) => + { + DeletePermanently = true; + ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database); + pt.run(); + }), + new EventHandler((dlgSender, dlgEvt) => { + DeletePermanently = false; + ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database); + pt.run(); + }), + new EventHandler((dlgSender, dlgEvt) => {}), + mCtx); + + + + } else + { + ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database); + pt.run(); + } + } + + } +} + diff --git a/src/keepass2android/database/edit/FileOnFinish.cs b/src/Kp2aBusinessLogic/database/edit/FileOnFinish.cs similarity index 100% rename from src/keepass2android/database/edit/FileOnFinish.cs rename to src/Kp2aBusinessLogic/database/edit/FileOnFinish.cs diff --git a/src/keepass2android/database/edit/LoadDB.cs b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs similarity index 81% rename from src/keepass2android/database/edit/LoadDB.cs rename to src/Kp2aBusinessLogic/database/edit/LoadDB.cs index a713fa63..85c64ab2 100644 --- a/src/keepass2android/database/edit/LoadDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs @@ -35,32 +35,32 @@ namespace keepass2android private IOConnectionInfo mIoc; private String mPass; private String mKey; - private Database mDb; + private IKp2aApp mApp; private Context mCtx; private bool mRememberKeyfile; - public LoadDB(Database db, Context ctx, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish) + public LoadDB(IKp2aApp app, Context ctx, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish) { - mDb = db; + mApp = app; mCtx = ctx; mIoc = ioc; mPass = pass; mKey = key; - - ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx); - mRememberKeyfile = prefs.GetBoolean(ctx.GetString(Resource.String.keyfile_key), ctx.Resources.GetBoolean(Resource.Boolean.keyfile_default)); + + + mRememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile); } public override void run () { try { - mDb.LoadData (mCtx, mIoc, mPass, mKey, mStatus); + mApp.GetDb().LoadData (mApp, mIoc, mPass, mKey, mStatus); saveFileData (mIoc, mKey); } catch (KeyFileException) { - finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ mCtx.GetString(Resource.String.keyfile_does_not_exist)); + finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ mApp.GetResourceString(UiStringKey.keyfile_does_not_exist)); } catch (Exception e) { finish(false, "An error occured: " + e.Message); @@ -102,13 +102,12 @@ namespace keepass2android } private void saveFileData(IOConnectionInfo ioc, String key) { - FileDbHelper db = App.fileDbHelper; - - if ( ! mRememberKeyfile ) { - key = ""; - } - - db.createFile(ioc, key); + + if (!mRememberKeyfile) + { + key = ""; + } + mApp.StoreOpenedFileAsRecent(ioc, key); } diff --git a/src/keepass2android/database/edit/OnFinish.cs b/src/Kp2aBusinessLogic/database/edit/OnFinish.cs similarity index 100% rename from src/keepass2android/database/edit/OnFinish.cs rename to src/Kp2aBusinessLogic/database/edit/OnFinish.cs diff --git a/src/keepass2android/database/edit/RunnableOnFinish.cs b/src/Kp2aBusinessLogic/database/edit/RunnableOnFinish.cs similarity index 100% rename from src/keepass2android/database/edit/RunnableOnFinish.cs rename to src/Kp2aBusinessLogic/database/edit/RunnableOnFinish.cs diff --git a/src/keepass2android/database/edit/SaveDB.cs b/src/Kp2aBusinessLogic/database/edit/SaveDB.cs similarity index 100% rename from src/keepass2android/database/edit/SaveDB.cs rename to src/Kp2aBusinessLogic/database/edit/SaveDB.cs diff --git a/src/keepass2android/database/edit/SetPassword.cs b/src/Kp2aBusinessLogic/database/edit/SetPassword.cs similarity index 100% rename from src/keepass2android/database/edit/SetPassword.cs rename to src/Kp2aBusinessLogic/database/edit/SetPassword.cs diff --git a/src/keepass2android/database/edit/UpdateEntry.cs b/src/Kp2aBusinessLogic/database/edit/UpdateEntry.cs similarity index 100% rename from src/keepass2android/database/edit/UpdateEntry.cs rename to src/Kp2aBusinessLogic/database/edit/UpdateEntry.cs diff --git a/src/Kp2aUnitTests/Kp2aUnitTests.csproj b/src/Kp2aUnitTests/Kp2aUnitTests.csproj new file mode 100644 index 00000000..7911fd18 --- /dev/null +++ b/src/Kp2aUnitTests/Kp2aUnitTests.csproj @@ -0,0 +1,80 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {46B769B8-2C58-4138-9CC0-70E3AE3C9A3A} + {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Properties + Kp2aUnitTests + Kp2aUnitTests + 512 + true + Resources\Resource.Designer.cs + Off + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + True + None + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + False + SdkOnly + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48} + MonoDroidUnitTesting + + + + + \ No newline at end of file diff --git a/src/Kp2aUnitTests/MainActivity.cs b/src/Kp2aUnitTests/MainActivity.cs new file mode 100644 index 00000000..718670d8 --- /dev/null +++ b/src/Kp2aUnitTests/MainActivity.cs @@ -0,0 +1,27 @@ +using System; + +using Android.App; +using Android.Content; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.OS; +using MonoDroidUnitTesting; +using System.Reflection; + +namespace Kp2aUnitTests +{ + [Activity(Label = "MonoDroidUnit", MainLauncher = true, Icon = "@drawable/icon")] + public class MainActivity : GuiTestRunnerActivity + { + protected override TestRunner CreateTestRunner() + { + TestRunner runner = new TestRunner(); + // Run all tests from this assembly + runner.AddTests(Assembly.GetExecutingAssembly()); + return runner; + } + } + +} + diff --git a/src/Kp2aUnitTests/Properties/AssemblyInfo.cs b/src/Kp2aUnitTests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..10d04ed0 --- /dev/null +++ b/src/Kp2aUnitTests/Properties/AssemblyInfo.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Android.App; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Kp2aUnitTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Kp2aUnitTests")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +// Add some common permissions, these can be removed if not needed +[assembly: UsesPermission(Android.Manifest.Permission.Internet)] +[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] diff --git a/src/Kp2aUnitTests/Resources/AboutResources.txt b/src/Kp2aUnitTests/Resources/AboutResources.txt new file mode 100644 index 00000000..194ae28a --- /dev/null +++ b/src/Kp2aUnitTests/Resources/AboutResources.txt @@ -0,0 +1,50 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.xml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable-hdpi/ + icon.png + + drawable-ldpi/ + icon.png + + drawable-mdpi/ + icon.png + + layout/ + main.xml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called +"Resource" that contains the tokens for each one of the resources included. For example, +for the above Resources layout, this is what the Resource class would expose: + +public class Resource { + public class drawable { + public const int icon = 0x123; + } + + public class layout { + public const int main = 0x456; + } + + public class strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main +to reference the layout/main.xml file, or Resource.strings.first_string to reference the first +string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/src/Kp2aUnitTests/Resources/Drawable/Icon.png b/src/Kp2aUnitTests/Resources/Drawable/Icon.png new file mode 100644 index 00000000..8074c4c5 Binary files /dev/null and b/src/Kp2aUnitTests/Resources/Drawable/Icon.png differ diff --git a/src/Kp2aUnitTests/Resources/Layout/Main.axml b/src/Kp2aUnitTests/Resources/Layout/Main.axml new file mode 100644 index 00000000..98be1643 --- /dev/null +++ b/src/Kp2aUnitTests/Resources/Layout/Main.axml @@ -0,0 +1,13 @@ + + +