115 Commits
V1.10 ... V1.15

Author SHA1 Message Date
638bfacadd Bug corrections 2018-09-12 16:49:01 +02:00
d341535d60 Corrected some tests
Minor code refactor
Main page now correctly shows save page even when opening a DB from Explorer
2018-09-12 12:58:32 +02:00
BONNEVILLE Geoffroy
38e2d1ac51 Updated store screenshots 2018-09-11 10:08:33 +02:00
BONNEVILLE Geoffroy
5b1039b81f Hid useless open from URL
Removed commented out code
2018-09-10 18:26:55 +02:00
BONNEVILLE Geoffroy
37deac2ab9 Basic CSV Import working 2018-09-10 17:29:52 +02:00
BONNEVILLE Geoffroy
34f6d4e793 Correct navigation to root group when creating new database 2018-09-10 11:25:57 +02:00
BONNEVILLE Geoffroy
bbae2c356a Changed implementation of sample data
Creating a new entry does not create an useless history value
WIP import data
2018-09-10 11:13:44 +02:00
deec19a60c Merge branch 'master' of https://geogeob.visualstudio.com/_git/ModernKeePass 2018-09-09 20:02:02 +02:00
b1167594db Finally corrected weird Windows 8 and RT bug
Refactor TopMenu User Control visibility with Visual State Manager
2018-09-09 20:01:56 +02:00
BONNEVILLE Geoffroy
0da6a5fc60 WIP Import mechanism 2018-09-07 18:16:40 +02:00
BONNEVILLE Geoffroy
549006036b Changed default icon from IntToSymbolConverter to a parameter
Filtered symbol list from drop down list to only show actually settable symbols
2018-09-06 18:30:30 +02:00
BONNEVILLE Geoffroy
6ed29e788c Sort menu default visibility set to Collapsed 2018-09-04 15:07:31 +02:00
BONNEVILLE Geoffroy
e437f65f83 Restored useless changes
Code cleanup
2018-08-03 17:41:52 +02:00
BONNEVILLE Geoffroy
6f96e698ec Created Import/Export page (stub)
Changed some dependency properties from Interfaces to implementations
Used CanExecute on Commands
2018-08-02 17:40:30 +02:00
BONNEVILLE Geoffroy
b2dd028fc7 Textbox button now works again correctly (but has caret instead of pointer...) 2018-07-30 16:29:28 +02:00
BONNEVILLE Geoffroy
62f2be8823 Finally corrected strange behaviour in TextBoxWithButton where text would sometimes not appear unless pointed over 2018-07-27 10:52:23 +02:00
BONNEVILLE Geoffroy
89d43e21eb Created a sub style for textbox with buttons in EntryDetailPage
Set long forgotten resources for buttons tooltips
2018-07-26 17:58:34 +02:00
BONNEVILLE Geoffroy
5d9831efb5 Clearer clipboard action toast messages
Created a top menu button style
2018-07-26 16:28:28 +02:00
BONNEVILLE Geoffroy
b65cb87e58 Minor code cleanup 2018-07-26 12:01:49 +02:00
BONNEVILLE Geoffroy
7e687f7001 Donation page now displays a loading ring while page is loaded 2018-07-26 11:49:48 +02:00
BONNEVILLE Geoffroy
1d5a4d6fab Removal of unused string resources
Minor Toast code refactor
2018-07-26 10:18:00 +02:00
BONNEVILLE Geoffroy
2a2a934006 Entry delete button now shows up correctly
Minor code refactoring
2018-07-25 18:39:03 +02:00
BONNEVILLE Geoffroy
4ae65fdbac Created an app theme instead of using the System accent colors (which doesn't work in Win 8.1)
Merged two dictionaries into one
Re-added focus on title when editing an entity
2018-07-25 18:08:59 +02:00
BONNEVILLE Geoffroy
dd347b56a2 Updated some MS packages 2018-07-24 18:06:44 +02:00
BONNEVILLE Geoffroy
ff1cdc265a Removed useless CodeAnalysis packages 2018-07-24 18:05:07 +02:00
BONNEVILLE Geoffroy
9863195684 Added CodeAnalysis package
Better entry history handling
Changing icon now adds an history entry
2018-07-24 17:52:44 +02:00
BONNEVILLE Geoffroy
d6765904a1 Slider control now uses Accent Color
ComboBox enter key now uses Accent Color
Some code cleanup
Updated release notes
2018-07-24 16:26:58 +02:00
BONNEVILLE Geoffroy
7e4d6a2836 Update release notes 2018-07-24 11:00:41 +02:00
BONNEVILLE Geoffroy
8a0b3a0870 HockeyApp correct app id 2018-07-24 10:55:31 +02:00
BONNEVILLE Geoffroy
6f53fc79bb Updated README.md 2018-07-20 17:49:22 +02:00
BONNEVILLE Geoffroy
6f161e8699 Changed search button and search box visibility behavior for a more modern and user friendly mechanism 2018-07-20 17:24:02 +02:00
BONNEVILLE Geoffroy
8f1f80ae38 New version number
New homepage URL
2018-07-20 16:33:13 +02:00
BONNEVILLE Geoffroy
aec09a6890 Updated screenshots
Widened semantic view group header to accomodate larger letters
2018-07-18 18:30:56 +02:00
BONNEVILLE Geoffroy
8e557c608e Hamburger menu expanded size set to static value
LeftIndicator list view pointed over opacity reduced
2018-07-18 16:20:02 +02:00
BONNEVILLE Geoffroy
991a678788 Hamburger button now has a hover opacity change
Search box text bottom margin removed
2018-07-13 11:30:10 +02:00
BONNEVILLE Geoffroy
b88d6131c5 Set a global XAML variable for menu and button sizes
Set global to 60 instead of 50
Changed expired entry icon
2018-07-12 18:19:26 +02:00
BONNEVILLE Geoffroy
c25ae2ad0f Group and entry icon is now shown (and editable) on the left of the title
Added new entry placeholder text in resources
Group detail page small view triggered on larger width
2018-07-12 15:32:54 +02:00
BONNEVILLE Geoffroy
2abab27d5c Updating master key now works again
Security settings page now also uses Toast Action
2018-07-12 12:30:58 +02:00
BONNEVILLE Geoffroy
a91f8b6c5c Entry page now has vertical scrollbar if needed
Removed command bar
Restore button is now correctly enabled or not depending on context
2018-07-11 18:23:52 +02:00
BONNEVILLE Geoffroy
83d37d943f Sorting now works with code behind 2018-07-11 13:48:15 +02:00
BONNEVILLE Geoffroy
81ca11a955 WIP Top Menu - sort buttons present but not working
Removed flyout from textbox with button
Generating a new password creates a new history entry
Top Menu edit mode now works as intended
2018-07-11 12:15:56 +02:00
BONNEVILLE Geoffroy
931f79ac16 WIP Top Menu - added code behind to handle visibility and enabled status in flyouts because XAML doesn't work 2018-07-10 18:26:27 +02:00
BONNEVILLE Geoffroy
2ab84ef4af WIP Top Menu - Overflow mechanism works, commands implemented 2018-07-05 18:32:42 +02:00
BONNEVILLE Geoffroy
056d1af9d0 WIP Top Menu - Button visibility ok when not in menu 2018-07-04 18:26:16 +02:00
BONNEVILLE Geoffroy
34f5f2f6c8 WIP Top Menu 2018-07-02 18:23:43 +02:00
BONNEVILLE Geoffroy
6d32161312 Small layout changes 2018-07-02 14:33:53 +02:00
BONNEVILLE Geoffroy
df6914d1e0 Added possibility to change groups and entries icons
Add new entry link now hides text depending on width
TimePicker uses main color
2018-06-26 18:14:01 +02:00
BONNEVILLE Geoffroy
6f277e7b33 Added ability to change Entries background and foreground colors 2018-06-26 15:01:02 +02:00
BONNEVILLE Geoffroy
7ffcf1c82b Navigate to URL correctly shows the error, should it happen
Entry title linked to history version
Title text boxes selection now uses the main color
2018-06-25 17:31:17 +02:00
BONNEVILLE Geoffroy
c6e27c35c8 Finally a workaround the stupid CommandBar DataContext issues
Delete and Restore actions now work as intended
Renamed styles folder
2018-06-22 18:31:55 +02:00
BONNEVILLE Geoffroy
a6f82b4541 WIP Delete and restore entities as Actions 2018-06-21 18:40:44 +02:00
BONNEVILLE Geoffroy
d533abada5 Better suspend/resume handling 2018-06-21 16:40:04 +02:00
BONNEVILLE Geoffroy
4393aada3e Textbox selection now uses Accent color 2018-06-21 12:16:35 +02:00
BONNEVILLE Geoffroy
559fbe65c3 New toast action to show toast messages from XAML
Code cleanup for Sonar
Tests corrections
2018-06-21 11:13:40 +02:00
BONNEVILLE Geoffroy
803dab0fb5 Replaced almost all CallMethodActions with RelayCommands (allows using async)
SonarQube bug correction
2018-06-20 18:41:56 +02:00
BONNEVILLE Geoffroy
ca377a6684 SonarQube async method return type set to Task 2018-06-20 17:20:15 +02:00
BONNEVILLE Geoffroy
188233cc81 Database file is now handled by each page, instead of a central place
Opening a database while another one is open triggers a warning message
2018-06-20 11:52:17 +02:00
BONNEVILLE Geoffroy
408b4eed90 WIP removing global databaseFile property 2018-06-19 18:47:37 +02:00
BONNEVILLE Geoffroy
b456e56789 Making modifications in an Entry creates a new History entry 2018-06-18 18:40:00 +02:00
BONNEVILLE Geoffroy
9225732c1a Removal of unused License Service 2018-06-18 16:19:56 +02:00
BONNEVILLE Geoffroy
e9601e8d13 Removed unused anti corruption code 2018-06-18 15:39:01 +02:00
BONNEVILLE Geoffroy
b1ded11fa5 Sonar code smells corrections 2018-06-18 14:58:01 +02:00
BONNEVILLE Geoffroy
978929ba48 Correct Sonar vulnerability 2018-06-18 11:25:21 +02:00
BONNEVILLE Geoffroy
7e337c4a40 History list fully functional in Entry page
Viewing a historic entry disables controls on the page
Enhancements in the hamburger menu
2018-06-15 18:07:44 +02:00
BONNEVILLE Geoffroy
62c9719a77 Hamburger menu button visibility is now a property
Hamburger menu now has a display member path property
2018-06-15 10:10:48 +02:00
BONNEVILLE Geoffroy
2b48b64f2f Hamburger button menu is now a User Control
WIP History in Entry page
2018-06-14 18:38:05 +02:00
BONNEVILLE Geoffroy
799b896bfe Breadcrumb finished and working 2018-06-14 10:50:16 +02:00
BONNEVILLE Geoffroy
8a5db88225 Entries and groups icons are now handled with int
Static mapping is changed to a converter
2018-06-14 10:20:00 +02:00
BONNEVILLE Geoffroy
cc65c56042 WIP Breadcrumb
Breadcrumb is now a working User Control (removal of the Templated Control)
AssemblyInfo updated
Some code cleanup
2018-06-13 18:58:28 +02:00
BONNEVILLE Geoffroy
0a4df01354 WIP Breadcrumb 2018-06-12 18:40:54 +02:00
BONNEVILLE Geoffroy
25945b8b3b Add update script version
GroupVM new breadcrumb code
2018-06-12 09:42:08 +02:00
BONNEVILLE Geoffroy
9921a4db52 Correct AppID in HockeyApp 2018-06-11 18:55:55 +02:00
BONNEVILLE Geoffroy
2c6530f3b0 Removed AppCenter and included HockeyApp 2018-06-11 18:42:50 +02:00
BONNEVILLE Geoffroy
f158191e52 Increase version number
WIP new breadcrumb (with hyperlinks)
2018-06-08 18:46:07 +02:00
BONNEVILLE Geoffroy
a7f2ae91a7 Reference ModernKeePassLib as a Nuget package (v2.39.1)
Correct bug when selecting search result
2018-06-08 15:39:28 +02:00
BONNEVILLE Geoffroy
49e1b709f7 ComboBox (including those in DatePicker) now use Accent Color 2018-06-08 14:27:35 +02:00
BONNEVILLE Geoffroy
59c903b635 Search box now recursively search sub groups 2018-06-08 12:08:06 +02:00
BONNEVILLE Geoffroy
c9d599216d List view now set Accent Color on selected item text 2018-06-08 11:22:00 +02:00
BONNEVILLE Geoffroy
8fa3a75a63 ToggleSwitch now also uses Accent Color 2018-06-08 11:12:54 +02:00
BONNEVILLE Geoffroy
e31d1edb99 Use of System Accent Color instead of purple (ToggleButtons still need to be styled) 2018-06-07 18:27:50 +02:00
BONNEVILLE Geoffroy
915cad8c85 Display a title on groups header menu 2018-06-06 18:26:05 +02:00
BONNEVILLE Geoffroy
7bd6c0dd09 XAML code cleanup 2018-06-06 12:21:11 +02:00
BONNEVILLE Geoffroy
0aa8e886ce Entry icon size reduced to 50%, with no side effects 2018-06-06 12:17:28 +02:00
BONNEVILLE Geoffroy
1334b266b9 Updated release notes
Finally a working zoomed out view for the Semantic Zoom
2018-06-06 12:13:25 +02:00
BONNEVILLE Geoffroy
9566c9a719 Open databases errors are cleaner
WIP SemanticView ListView Width issue
2018-06-05 18:40:23 +02:00
BONNEVILLE Geoffroy
0643701c4a Typing a password auto checks the check box
Correct hit test area on entries in group detail page
Correct zoomed out entries (filter and group)
2018-06-05 16:23:09 +02:00
BONNEVILLE Geoffroy
4d86c25411 ModernKeePass lib version 2.39.1 seemeegly functional
WIP in some pages
2018-06-04 18:38:48 +02:00
BONNEVILLE Geoffroy
ad02740d8a WIP Lib version 2.39.1 2018-05-22 18:27:44 +02:00
BONNEVILLE Geoffroy
0b95669db0 Projects renamed 2018-05-22 14:52:31 +02:00
BONNEVILLE Geoffroy
4aefbcb8b9 RecycleBin now uses resources
RecycleBin bugs correction
2018-03-12 17:30:03 +01:00
BONNEVILLE Geoffroy
56129253d9 Use ModernKeePass Lib 2.38.2
Changed suspension save errors handling
2018-03-12 12:45:12 +01:00
BONNEVILLE Geoffroy
7613629d87 Deactivation of buggy Splat custom icon implementation 2018-03-12 12:40:07 +01:00
BONNEVILLE Geoffroy
fb0eab00c2 Create group and delete current group hidden in Recycle Bin 2018-03-12 11:27:15 +01:00
BONNEVILLE Geoffroy
5b8c3b9b11 Typo in restore button 2018-03-12 11:18:42 +01:00
BONNEVILLE Geoffroy
700f76679a Corrected RecycleBin group bug
Database Settings page now has radio button for recycle bin
2018-03-12 10:21:36 +01:00
BONNEVILLE Geoffroy
e7d731bb04 KeepassLib version 2.38
Added a new settings page to allow auto-save or not
App now resumes correctly from suspend
Settings service now allows getting default values
Removed french special characters from metadata
Code cleanup
2018-03-09 18:06:06 +01:00
BONNEVILLE Geoffroy
49637fcc3b KeepassLib version update to 2.38 2018-03-09 17:49:47 +01:00
BONNEVILLE Geoffroy
fc25d7ea93 Update some packages 2018-03-07 18:39:56 +01:00
BONNEVILLE Geoffroy
cca6579274 Removed useless code in Donate page 2018-02-23 18:13:44 +01:00
BONNEVILLE Geoffroy
7dbf93fe7b Changed most services to singletons
Refactor the Database Service (no more enum, ...)
Restored the Donate page with Paypal web page
Added (but not working) MS App Center integration
Corrected tests accordingly
WIP AOP to detect database changes
2018-02-23 18:09:21 +01:00
BONNEVILLE Geoffroy
b46ab8db51 Code cleanup
Popup discard action now works
2018-01-09 18:40:11 +01:00
BONNEVILLE Geoffroy
a19519fa73 Removed database status in favor of much cleaner code
Implemented (but deactivated) anti corruption mechanism
WIP detect changes and save them if opening another database
2018-01-08 18:52:03 +01:00
BONNEVILLE Geoffroy
4a3f36d38b Version bump to 1.13
New group button is now at the bottom of the listview
2018-01-08 11:02:53 +01:00
BONNEVILLE Geoffroy
4ae02fc07b Corrected test case to reflect page removal 2018-01-03 11:37:09 +01:00
BONNEVILLE Geoffroy
047fca32bf Hid donations pages (need to implement 3rd party API) 2018-01-03 11:29:51 +01:00
BONNEVILLE Geoffroy
abbff449c0 Removed User Account from composite key (probably never going to work as intended)
Changed copy URL to navigate to URL in entry quick menu
2017-12-26 17:54:13 +01:00
BONNEVILLE Geoffroy
fba668860b WIP user accounts - not working at all 2017-12-21 18:24:01 +01:00
BONNEVILLE Geoffroy
acb196d9c2 WIP Windows User Accounts Composite Key integration 2017-12-20 18:49:11 +01:00
BONNEVILLE Geoffroy
dfa3a21e6b Removed an useless converter
Groups in menu now use instead a Template selector (depending on IIsSelected)
2017-12-19 18:44:35 +01:00
BONNEVILLE Geoffroy
7ff6bccbc4 Added some tests
Removed false first group, replaced it a button in the header
Code refactor
2017-12-18 18:53:42 +01:00
BONNEVILLE Geoffroy
88e5b80778 Version bump to 1.12
Added small menu on entries list to copy login, password and URL
2017-12-18 14:09:04 +01:00
BONNEVILLE Geoffroy
d127431396 Third try on store special character escaping 2017-12-18 11:52:49 +01:00
BONNEVILLE Geoffroy
588703ecd6 Added a small text explaining how to reorder entries
Code cleanup
2017-12-14 17:54:14 +01:00
BONNEVILLE Geoffroy
223c9b641a Updated release notes
HTML encoded french text
2017-12-14 17:28:22 +01:00
BONNEVILLE Geoffroy
7db34d6517 Corrected critical error when opening file from explorer
Reverted filter mechanisme to search box because of numerous regressions (on ordering, refresh etc.)
2017-12-14 17:15:28 +01:00
283 changed files with 39790 additions and 2982 deletions

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A3354969-5AAC-4075-8CBF-EA4805B59EFA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ModernKeePass.Shared</RootNamespace>
<AssemblyName>ModernKeePass.Shared</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,30 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("ModernKeePass.Shared")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ModernKeePass.Shared")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// 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")]

View File

@@ -0,0 +1,10 @@
{
"supports": {},
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.2": {}
}
}

View File

@@ -3,15 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePassApp", "ModernKeePass\ModernKeePassApp.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.App", "ModernKeePass\ModernKeePass.App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePassLib", "ModernKeePassLib\ModernKeePassLib.csproj", "{2E710089-9559-4967-846C-E763DD1F3ACB}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.Lib", "ModernKeePassLib\ModernKeePass.Lib.csproj", "{2E710089-9559-4967-846C-E763DD1F3ACB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePassLib.Test", "ModernKeePassLib.Test\ModernKeePassLib.Test.csproj", "{0A4279CF-2A67-4868-9906-052E50C25F3B}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.LibTest", "ModernKeePassLib.Test\ModernKeePass.LibTest.csproj", "{0A4279CF-2A67-4868-9906-052E50C25F3B}"
EndProject
Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "Scripts", "Scripts\Scripts.pssproj", "{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePassApp.Test", "ModernKeePassApp.Test\ModernKeePassApp.Test.csproj", "{7E80F5E7-724A-4668-9333-B10F5D75C6D0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernKeePass.AppTest", "ModernKeePassApp.Test\ModernKeePass.AppTest.csproj", "{7E80F5E7-724A-4668-9333-B10F5D75C6D0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -89,22 +87,6 @@ Global
{0A4279CF-2A67-4868-9906-052E50C25F3B}.Release|x86.ActiveCfg = Release|x86
{0A4279CF-2A67-4868-9906-052E50C25F3B}.Release|x86.Build.0 = Release|x86
{0A4279CF-2A67-4868-9906-052E50C25F3B}.Release|x86.Deploy.0 = Release|x86
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|ARM.Build.0 = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|x64.ActiveCfg = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|x64.Build.0 = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|x86.ActiveCfg = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|x86.Build.0 = Debug|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.Build.0 = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|ARM.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|ARM.Build.0 = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|x64.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|x64.Build.0 = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|x86.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|x86.Build.0 = Release|Any CPU
{7E80F5E7-724A-4668-9333-B10F5D75C6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E80F5E7-724A-4668-9333-B10F5D75C6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E80F5E7-724A-4668-9333-B10F5D75C6D0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU

View File

@@ -0,0 +1 @@
C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\out\0

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<AnalysisConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sonarsource.com/msbuild/integration/2015/1">
<SonarConfigDir>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\conf</SonarConfigDir>
<SonarOutputDir>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\out</SonarOutputDir>
<SonarBinDir>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\bin</SonarBinDir>
<SonarScannerWorkingDirectory>C:\Sources\Other\ModernKeePass\ModernKeePass</SonarScannerWorkingDirectory>
<HasBeginStepCommandLineCredentials>true</HasBeginStepCommandLineCredentials>
<SonarQubeHostUrl>https://sonarcloud.io</SonarQubeHostUrl>
<SonarQubeVersion>7.2.0.12953</SonarQubeVersion>
<SonarProjectKey>ModernKeePass</SonarProjectKey>
<AdditionalConfig>
<ConfigSetting Id="BuildUri" />
<ConfigSetting Id="TfsUri" />
<ConfigSetting Id="settings.file.path" Value="c:\sonar\SonarQube.Analysis.xml" />
</AdditionalConfig>
<ServerSettings>
<Property Name="sonaranalyzer-cs.nuget.packageVersion">7.1.0.5212</Property>
<Property Name="sonar.editions.jsonUrl">https://update.sonarsource.org/editions.json</Property>
<Property Name="sonar.cs.ignoreHeaderComments">true</Property>
<Property Name="sonar.cfamily.useSema">true</Property>
<Property Name="sonar.c.file.suffixes">.c,.h</Property>
<Property Name="sonar.typescript.file.suffixes">.ts,.tsx</Property>
<Property Name="email.fromName">SonarQube</Property>
<Property Name="sonar.python.xunit.skipDetails">false</Property>
<Property Name="sonar.auth.bitbucket.loginStrategy">Unique</Property>
<Property Name="sonar.plsql.jdbc.driver.class">oracle.jdbc.OracleDriver</Property>
<Property Name="sonar.go.exclusions">**/vendor/**</Property>
<Property Name="sonar.forceAuthentication">false</Property>
<Property Name="sonar.notifications.delay">60</Property>
<Property Name="sonar.cpp.file.suffixes">.cc,.cpp,.cxx,.c++,.hh,.hpp,.hxx,.h++,.ipp</Property>
<Property Name="sonaranalyzer-cs.ruleNamespace">SonarAnalyzer.CSharp</Property>
<Property Name="sonar.web.file.suffixes">.html,.xhtml,.rhtml,.shtml</Property>
<Property Name="sonar.builtInQualityProfiles.disableNotificationOnUpdate">false</Property>
<Property Name="sonar.java.failOnException">false</Property>
<Property Name="sonar.organizations.createPersonalOrg">true</Property>
<Property Name="sonar.cpd.abap.minimumTokens">100</Property>
<Property Name="sonar.jacoco.reportPaths">target/jacoco.exec, target/jacoco-it.exec</Property>
<Property Name="sonar.cpd.cross_project">false</Property>
<Property Name="sonar.vbnet.ignoreHeaderComments">true</Property>
<Property Name="sonar.leak.period">30</Property>
<Property Name="sonar.auth.github.groupsSync">false</Property>
<Property Name="sonar.dbcleaner.daysBeforeDeletingInactiveShortLivingBranches">30</Property>
<Property Name="sonar.auth.github.loginStrategy">Unique</Property>
<Property Name="sonar.auth.microsoft.enabled">true</Property>
<Property Name="sonaranalyzer-vbnet.ruleNamespace">SonarAnalyzer.VisualBasic</Property>
<Property Name="sonar.auth.microsoft.allowsUsersToSignUp">true</Property>
<Property Name="sonar.javascript.ignoreHeaderComments">true</Property>
<Property Name="sonar.dbcleaner.daysBeforeDeletingClosedIssues">730</Property>
<Property Name="sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByMonth">4</Property>
<Property Name="sonar.lf.gravatarServerUrl">https://secure.gravatar.com/avatar/{EMAIL_MD5}.jpg?s={SIZE}&amp;d=identicon</Property>
<Property Name="sonar.notifications.runningDelayBeforeReportingStatus">600</Property>
<Property Name="sonar.javascript.environments">amd, applescript, atomtest, browser, commonjs, couch, embertest, flow, greasemonkey, jasmine, jest, jquery, meteor, mocha, mongo, nashorn, node, phantomjs, prototypejs, protractor, qunit, rhino, serviceworker, shared-node-browser, shelljs, webextensions, worker, wsh, yui</Property>
<Property Name="sonar.scm.disabled">false</Property>
<Property Name="sonar.typescript.exclusions">**/node_modules/**,**/bower_components/**</Property>
<Property Name="sonar.vbnet.file.suffixes">.vb</Property>
<Property Name="sonar.abap.file.suffixes">.abap,.ab4,.flow,.asprog</Property>
<Property Name="sonar.cfamily.ignoreHeaderComments">true</Property>
<Property Name="sonar.technicalDebt.developmentCost">30</Property>
<Property Name="sonar.python.file.suffixes">py</Property>
<Property Name="sonar.cs.file.suffixes">.cs</Property>
<Property Name="sonar.plsql.file.suffixes">sql,tab,pkb</Property>
<Property Name="sonaranalyzer-vbnet.staticResourceName">SonarAnalyzer-7.1.0.5212.zip</Property>
<Property Name="sonar.java.file.suffixes">.java,.jav</Property>
<Property Name="sonar.php.file.suffixes">php,php3,php4,php5,phtml,inc</Property>
<Property Name="sonar.xml.file.suffixes">.xml,.xsd,.xsl</Property>
<Property Name="sonar.dbcleaner.weeksBeforeDeletingAllSnapshots">480</Property>
<Property Name="sonar.auth.bitbucket.allowUsersToSignUp">true</Property>
<Property Name="sonar.auth.github.enabled">true</Property>
<Property Name="sonar.javascript.jQueryObjectAliases">$, jQuery</Property>
<Property Name="sonaranalyzer-vbnet.nuget.packageVersion">7.1.0.5212</Property>
<Property Name="sonar.go.file.suffixes">.go</Property>
<Property Name="sonar.dbcleaner.weeksBeforeKeepingOnlyAnalysesWithVersion">104</Property>
<Property Name="sonar.swift.file.suffixes">.swift</Property>
<Property Name="sonar.github.endpoint">https://api.github.com</Property>
<Property Name="sonar.plsql.ignoreHeaderComments">false</Property>
<Property Name="sonar.flex.file.suffixes">as</Property>
<Property Name="sonar.auth.github.apiUrl">https://api.github.com/</Property>
<Property Name="sonar.auth.github.allowUsersToSignUp">true</Property>
<Property Name="sonar.python.xunit.reportPath">xunit-reports/xunit-result-*.xml</Property>
<Property Name="sonar.javascript.globals">angular,goog,google,OpenLayers,d3,dojo,dojox,dijit,Backbone,moment,casper</Property>
<Property Name="sonar.dbcleaner.hoursBeforeKeepingOnlyOneSnapshotByDay">24</Property>
<Property Name="sonar.auth.bitbucket.enabled">true</Property>
<Property Name="sonar.javascript.exclusions">**/node_modules/**,**/bower_components/**</Property>
<Property Name="sonar.auth.github.webUrl">https://github.com/</Property>
<Property Name="sonar.dbcleaner.cleanDirectory">true</Property>
<Property Name="sonar.onboardingTutorial.showToNewUsers">false</Property>
<Property Name="sonaranalyzer-vbnet.nuget.packageId">SonarAnalyzer.VisualBasic</Property>
<Property Name="email.from">noreply@sonarcloud.io</Property>
<Property Name="sonaranalyzer-vbnet.pluginVersion">7.1.0.5212</Property>
<Property Name="sonar.typescript.node">node</Property>
<Property Name="sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByWeek">1</Property>
<Property Name="sonaranalyzer-vbnet.analyzerId">SonarAnalyzer.VisualBasic</Property>
<Property Name="email.prefix">[SonarCloud]</Property>
<Property Name="sonar.c.std">c11</Property>
<Property Name="sonaranalyzer-cs.pluginKey">csharp</Property>
<Property Name="sonar.cfamily.useCache">true</Property>
<Property Name="sonar.branch.longLivedBranches.regex">(branch|release)-.*</Property>
<Property Name="sonar.objc.file.suffixes">.m</Property>
<Property Name="sonar.go.coverage.reportPaths">coverage.out</Property>
<Property Name="sonaranalyzer-cs.staticResourceName">SonarAnalyzer-7.1.0.5212.zip</Property>
<Property Name="sonaranalyzer-cs.nuget.packageId">SonarAnalyzer.CSharp</Property>
<Property Name="sonar.auth.bitbucket.apiUrl">https://api.bitbucket.org/</Property>
<Property Name="sonar.authenticator.downcase">false</Property>
<Property Name="sonar.github.disableInlineComments">false</Property>
<Property Name="sonar.python.coverage.reportPath">coverage-reports/*coverage-*.xml</Property>
<Property Name="sonaranalyzer-cs.analyzerId">SonarAnalyzer.CSharp</Property>
<Property Name="sonar.organizations.anyoneCanCreate">true</Property>
<Property Name="sonar.technicalDebt.ratingGrid">0.05,0.1,0.2,0.5</Property>
<Property Name="sonar.lf.enableGravatar">true</Property>
<Property Name="sonar.preview.excludePlugins">devcockpit,pdfreport,governance,ldap,authaad,authgithub,authbitbucket,googleanalytics</Property>
<Property Name="sonaranalyzer-cs.pluginVersion">7.1.0.5212</Property>
<Property Name="sonar.javascript.file.suffixes">.js,.jsx,.vue</Property>
<Property Name="sonar.cpd.abap.minimumLines">20</Property>
<Property Name="sonaranalyzer-vbnet.pluginKey">vbnet</Property>
<Property Name="sonar.java.collectAnalysisErrors">true</Property>
<Property Name="sonar.updatecenter.url">https://update.sonarsource.org/update-center.properties</Property>
<Property Name="sonar.tsql.file.suffixes">.tsql</Property>
<Property Name="sonar.cpp.std">c++11</Property>
<Property Name="sonar.core.serverBaseURL">https://sonarcloud.io</Property>
<Property Name="sonar.lf.logoUrl">https://about.sonarcloud.io/images/SonarCloud-white-210px.png</Property>
<Property Name="sonar.lf.logoWidthPx">105</Property>
<Property Name="sonar.lf.aboutText">&lt;div class="boxed-group" style="border: none; border-radius: 3px;"&gt;
&lt;div class="boxed-group-inner clearfix" style="padding: 30px; border-radius: 3px; border: #e6e6e6 1px solid; background: #f3f3f3;"&gt;
&lt;div style="overflow: hidden; line-height: 1.5; font-size: 16px;"&gt;
&lt;p&gt;
Analyze your open source and private projects on SonarCloud.
Select your &lt;a href="https://about.sonarcloud.io"&gt;plan&lt;/a&gt; and start improving.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</Property>
<Property Name="sonar.core.id">AWHW8ct9-T_TB3XqouNu</Property>
<Property Name="sonar.core.startTime">07/06/2018 12:32:21</Property>
</ServerSettings>
<LocalSettings>
<Property Name="sonar.organization">geogeob</Property>
<Property Name="sonar.host.url">https://sonarcloud.io</Property>
</LocalSettings>
<AnalyzersSettings>
<AnalyzerSettings>
<Language>cs</Language>
<RuleSetFilePath>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\conf\SonarQubeRoslyn-cs.ruleset</RuleSetFilePath>
<AnalyzerAssemblyPaths>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\0\Google.Protobuf.dll</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\0\SonarAnalyzer.CSharp.dll</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\0\SonarAnalyzer.dll</Path>
</AnalyzerAssemblyPaths>
<AdditionalFilePaths>
<Path>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\conf\cs\SonarLint.xml</Path>
</AdditionalFilePaths>
</AnalyzerSettings>
<AnalyzerSettings>
<Language>vbnet</Language>
<RuleSetFilePath>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\conf\SonarQubeRoslyn-vbnet.ruleset</RuleSetFilePath>
<AnalyzerAssemblyPaths>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\SonarAnalyzer.VisualBasic.nuspec</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\[Content_Types].xml</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\analyzers\Google.Protobuf.dll</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\analyzers\SonarAnalyzer.dll</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\analyzers\SonarAnalyzer.VisualBasic.dll</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\package\services\metadata\core-properties\f124441cdae948bb922ac980ea59570c.psmdcp</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\tools\install.ps1</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\tools\uninstall.ps1</Path>
<Path>C:\Users\GBE\AppData\Local\Temp\.sonarqube\resources\1\_rels\.rels</Path>
</AnalyzerAssemblyPaths>
<AdditionalFilePaths>
<Path>C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\conf\vbnet\SonarLint.xml</Path>
</AdditionalFilePaths>
</AnalyzerSettings>
</AnalyzersSettings>
</AnalysisConfig>

View File

@@ -0,0 +1,348 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="Rules for SonarQube" Description="This rule set was automatically generated from SonarQube" ToolsVersion="14.0">
<Rules AnalyzerId="SonarAnalyzer.CSharp" RuleNamespace="SonarAnalyzer.CSharp">
<Rule Id="S2589" Action="Warning" />
<Rule Id="S3433" Action="Warning" />
<Rule Id="S4061" Action="Warning" />
<Rule Id="S1121" Action="Warning" />
<Rule Id="S1854" Action="Warning" />
<Rule Id="S4457" Action="Warning" />
<Rule Id="S4456" Action="Warning" />
<Rule Id="S2278" Action="Warning" />
<Rule Id="S4211" Action="Warning" />
<Rule Id="S3923" Action="Warning" />
<Rule Id="S4426" Action="Warning" />
<Rule Id="S2486" Action="Warning" />
<Rule Id="S4433" Action="Warning" />
<Rule Id="S2758" Action="Warning" />
<Rule Id="S1751" Action="Warning" />
<Rule Id="S1871" Action="Warning" />
<Rule Id="S4586" Action="Warning" />
<Rule Id="S4581" Action="Warning" />
<Rule Id="S2737" Action="Warning" />
<Rule Id="S3400" Action="Warning" />
<Rule Id="S3649" Action="Warning" />
<Rule Id="S1144" Action="Warning" />
<Rule Id="S1264" Action="Warning" />
<Rule Id="S2201" Action="Warning" />
<Rule Id="S1118" Action="Warning" />
<Rule Id="S1006" Action="Warning" />
<Rule Id="S4214" Action="Warning" />
<Rule Id="S4210" Action="Warning" />
<Rule Id="S3241" Action="Warning" />
<Rule Id="S4428" Action="Warning" />
<Rule Id="S1048" Action="Warning" />
<Rule Id="S2183" Action="Warning" />
<Rule Id="S3168" Action="Warning" />
<Rule Id="S4220" Action="Warning" />
<Rule Id="S3261" Action="Warning" />
<Rule Id="S4260" Action="Warning" />
<Rule Id="S4159" Action="Warning" />
<Rule Id="S4277" Action="Warning" />
<Rule Id="S2583" Action="Warning" />
<Rule Id="S3440" Action="Warning" />
<Rule Id="S3776" Action="Warning" />
<Rule Id="S2326" Action="Warning" />
<Rule Id="S1116" Action="Warning" />
<Rule Id="S3358" Action="Warning" />
<Rule Id="S4200" Action="Warning" />
<Rule Id="S1172" Action="Warning" />
<Rule Id="S1862" Action="Warning" />
<Rule Id="S2275" Action="Warning" />
<Rule Id="S3457" Action="Warning" />
<Rule Id="S3459" Action="Warning" />
<Rule Id="S3464" Action="Warning" />
<Rule Id="S3343" Action="Warning" />
<Rule Id="S818" Action="Warning" />
<Rule Id="S1656" Action="Warning" />
<Rule Id="S2184" Action="Warning" />
<Rule Id="S1764" Action="Warning" />
<Rule Id="S2971" Action="Warning" />
<Rule Id="S3060" Action="Warning" />
<Rule Id="S101" Action="Warning" />
<Rule Id="S1066" Action="Warning" />
<Rule Id="S107" Action="Warning" />
<Rule Id="S1075" Action="Warning" />
<Rule Id="S108" Action="Warning" />
<Rule Id="S110" Action="Warning" />
<Rule Id="S1104" Action="Warning" />
<Rule Id="S1110" Action="Warning" />
<Rule Id="S1117" Action="Warning" />
<Rule Id="S112" Action="Warning" />
<Rule Id="S1123" Action="Warning" />
<Rule Id="S1125" Action="Warning" />
<Rule Id="S1134" Action="Warning" />
<Rule Id="S1135" Action="Warning" />
<Rule Id="S1155" Action="Warning" />
<Rule Id="S1163" Action="Warning" />
<Rule Id="S1168" Action="Warning" />
<Rule Id="S1185" Action="Warning" />
<Rule Id="S1186" Action="Warning" />
<Rule Id="S1206" Action="Warning" />
<Rule Id="S1210" Action="Warning" />
<Rule Id="S1215" Action="Warning" />
<Rule Id="S125" Action="Warning" />
<Rule Id="S1450" Action="Warning" />
<Rule Id="S1479" Action="Warning" />
<Rule Id="S1481" Action="Warning" />
<Rule Id="S1607" Action="Warning" />
<Rule Id="S1643" Action="Warning" />
<Rule Id="S1699" Action="Warning" />
<Rule Id="S1848" Action="Warning" />
<Rule Id="S1905" Action="Warning" />
<Rule Id="S1939" Action="Warning" />
<Rule Id="S1940" Action="Warning" />
<Rule Id="S1944" Action="Warning" />
<Rule Id="S2068" Action="Warning" />
<Rule Id="S2114" Action="Warning" />
<Rule Id="S2123" Action="Warning" />
<Rule Id="S2178" Action="Warning" />
<Rule Id="S2187" Action="Warning" />
<Rule Id="S2190" Action="Warning" />
<Rule Id="S2219" Action="Warning" />
<Rule Id="S2223" Action="Warning" />
<Rule Id="S2225" Action="Warning" />
<Rule Id="S2234" Action="Warning" />
<Rule Id="S2259" Action="Warning" />
<Rule Id="S2290" Action="Warning" />
<Rule Id="S2291" Action="Warning" />
<Rule Id="S2292" Action="Warning" />
<Rule Id="S2306" Action="Warning" />
<Rule Id="S2328" Action="Warning" />
<Rule Id="S2342" Action="Warning" />
<Rule Id="S2344" Action="Warning" />
<Rule Id="S2345" Action="Warning" />
<Rule Id="S2346" Action="Warning" />
<Rule Id="S2365" Action="Warning" />
<Rule Id="S2368" Action="Warning" />
<Rule Id="S2372" Action="Warning" />
<Rule Id="S2376" Action="Warning" />
<Rule Id="S2386" Action="Warning" />
<Rule Id="S2436" Action="Warning" />
<Rule Id="S2437" Action="Warning" />
<Rule Id="S2681" Action="Warning" />
<Rule Id="S2688" Action="Warning" />
<Rule Id="S2692" Action="Warning" />
<Rule Id="S2696" Action="Warning" />
<Rule Id="S2743" Action="Warning" />
<Rule Id="S2757" Action="Warning" />
<Rule Id="S2761" Action="Warning" />
<Rule Id="S2930" Action="Warning" />
<Rule Id="S2933" Action="Warning" />
<Rule Id="S2934" Action="Warning" />
<Rule Id="S2953" Action="Warning" />
<Rule Id="S2995" Action="Warning" />
<Rule Id="S2996" Action="Warning" />
<Rule Id="S2997" Action="Warning" />
<Rule Id="S3005" Action="Warning" />
<Rule Id="S3010" Action="Warning" />
<Rule Id="S3169" Action="Warning" />
<Rule Id="S3172" Action="Warning" />
<Rule Id="S3217" Action="Warning" />
<Rule Id="S3218" Action="Warning" />
<Rule Id="S3220" Action="Warning" />
<Rule Id="S3236" Action="Warning" />
<Rule Id="S3237" Action="Warning" />
<Rule Id="S3244" Action="Warning" />
<Rule Id="S3246" Action="Warning" />
<Rule Id="S3247" Action="Warning" />
<Rule Id="S3249" Action="Warning" />
<Rule Id="S3251" Action="Warning" />
<Rule Id="S3256" Action="Warning" />
<Rule Id="S3262" Action="Warning" />
<Rule Id="S3263" Action="Warning" />
<Rule Id="S3264" Action="Warning" />
<Rule Id="S3265" Action="Warning" />
<Rule Id="S3346" Action="Warning" />
<Rule Id="S3376" Action="Warning" />
<Rule Id="S3397" Action="Warning" />
<Rule Id="S3415" Action="Warning" />
<Rule Id="S3427" Action="Warning" />
<Rule Id="S3442" Action="Warning" />
<Rule Id="S3443" Action="Warning" />
<Rule Id="S3444" Action="Warning" />
<Rule Id="S3445" Action="Warning" />
<Rule Id="S3447" Action="Warning" />
<Rule Id="S3449" Action="Warning" />
<Rule Id="S3450" Action="Warning" />
<Rule Id="S3451" Action="Warning" />
<Rule Id="S3453" Action="Warning" />
<Rule Id="S3456" Action="Warning" />
<Rule Id="S3458" Action="Warning" />
<Rule Id="S3466" Action="Warning" />
<Rule Id="S3597" Action="Warning" />
<Rule Id="S3598" Action="Warning" />
<Rule Id="S3600" Action="Warning" />
<Rule Id="S3603" Action="Warning" />
<Rule Id="S3604" Action="Warning" />
<Rule Id="S3610" Action="Warning" />
<Rule Id="S3626" Action="Warning" />
<Rule Id="S3655" Action="Warning" />
<Rule Id="S3693" Action="Warning" />
<Rule Id="S3869" Action="Warning" />
<Rule Id="S3871" Action="Warning" />
<Rule Id="S3875" Action="Warning" />
<Rule Id="S3877" Action="Warning" />
<Rule Id="S3881" Action="Warning" />
<Rule Id="S3884" Action="Warning" />
<Rule Id="S3885" Action="Warning" />
<Rule Id="S3887" Action="Warning" />
<Rule Id="S3889" Action="Warning" />
<Rule Id="S3897" Action="Warning" />
<Rule Id="S3903" Action="Warning" />
<Rule Id="S3904" Action="Warning" />
<Rule Id="S3925" Action="Warning" />
<Rule Id="S3926" Action="Warning" />
<Rule Id="S3927" Action="Warning" />
<Rule Id="S3928" Action="Warning" />
<Rule Id="S3966" Action="Warning" />
<Rule Id="S3971" Action="Warning" />
<Rule Id="S3972" Action="Warning" />
<Rule Id="S3981" Action="Warning" />
<Rule Id="S3984" Action="Warning" />
<Rule Id="S3998" Action="Warning" />
<Rule Id="S4015" Action="Warning" />
<Rule Id="S4016" Action="Warning" />
<Rule Id="S4019" Action="Warning" />
<Rule Id="S4035" Action="Warning" />
<Rule Id="S4144" Action="Warning" />
<Rule Id="S4158" Action="Warning" />
<Rule Id="S907" Action="Warning" />
<Rule Id="S927" Action="Warning" />
<Rule Id="S4524" Action="None" />
<Rule Id="S2228" Action="None" />
<Rule Id="S881" Action="None" />
<Rule Id="S4564" Action="None" />
<Rule Id="S4212" Action="None" />
<Rule Id="S2245" Action="None" />
<Rule Id="S131" Action="None" />
<Rule Id="S3330" Action="None" />
<Rule Id="S2255" Action="None" />
<Rule Id="S4432" Action="None" />
<Rule Id="S109" Action="None" />
<Rule Id="S2070" Action="None" />
<Rule Id="S4462" Action="None" />
<Rule Id="S1192" Action="None" />
<Rule Id="S2302" Action="None" />
<Rule Id="S1694" Action="None" />
<Rule Id="S4040" Action="None" />
<Rule Id="S4142" Action="None" />
<Rule Id="S2092" Action="None" />
<Rule Id="S3900" Action="None" />
<Rule Id="S1821" Action="None" />
<Rule Id="S3235" Action="None" />
<Rule Id="S3366" Action="None" />
<Rule Id="S1151" Action="None" />
<Rule Id="S4041" Action="None" />
<Rule Id="S4261" Action="None" />
<Rule Id="S1147" Action="None" />
<Rule Id="S3532" Action="None" />
<Rule Id="S3353" Action="None" />
<Rule Id="S126" Action="None" />
<Rule Id="S138" Action="None" />
<Rule Id="S1659" Action="None" />
<Rule Id="S2197" Action="None" />
<Rule Id="S100" Action="None" />
<Rule Id="S103" Action="None" />
<Rule Id="S104" Action="None" />
<Rule Id="S105" Action="None" />
<Rule Id="S1067" Action="None" />
<Rule Id="S1109" Action="None" />
<Rule Id="S113" Action="None" />
<Rule Id="S1145" Action="None" />
<Rule Id="S1200" Action="None" />
<Rule Id="S121" Action="None" />
<Rule Id="S122" Action="None" />
<Rule Id="S1226" Action="None" />
<Rule Id="S1227" Action="None" />
<Rule Id="S1244" Action="None" />
<Rule Id="S127" Action="None" />
<Rule Id="S1301" Action="None" />
<Rule Id="S1309" Action="None" />
<Rule Id="S1313" Action="None" />
<Rule Id="S134" Action="None" />
<Rule Id="S1449" Action="None" />
<Rule Id="S1451" Action="None" />
<Rule Id="S1541" Action="None" />
<Rule Id="S1696" Action="None" />
<Rule Id="S1697" Action="None" />
<Rule Id="S1698" Action="None" />
<Rule Id="S1858" Action="None" />
<Rule Id="S1994" Action="None" />
<Rule Id="S2156" Action="None" />
<Rule Id="S2221" Action="None" />
<Rule Id="S2325" Action="None" />
<Rule Id="S2330" Action="None" />
<Rule Id="S2333" Action="None" />
<Rule Id="S2339" Action="None" />
<Rule Id="S2357" Action="None" />
<Rule Id="S2360" Action="None" />
<Rule Id="S2387" Action="None" />
<Rule Id="S2551" Action="None" />
<Rule Id="S2674" Action="None" />
<Rule Id="S2699" Action="None" />
<Rule Id="S2701" Action="None" />
<Rule Id="S2760" Action="None" />
<Rule Id="S2931" Action="None" />
<Rule Id="S2952" Action="None" />
<Rule Id="S2955" Action="None" />
<Rule Id="S3052" Action="None" />
<Rule Id="S3215" Action="None" />
<Rule Id="S3216" Action="None" />
<Rule Id="S3234" Action="None" />
<Rule Id="S3240" Action="None" />
<Rule Id="S3242" Action="None" />
<Rule Id="S3253" Action="None" />
<Rule Id="S3254" Action="None" />
<Rule Id="S3257" Action="None" />
<Rule Id="S3431" Action="None" />
<Rule Id="S3441" Action="None" />
<Rule Id="S3717" Action="None" />
<Rule Id="S3872" Action="None" />
<Rule Id="S3874" Action="None" />
<Rule Id="S3876" Action="None" />
<Rule Id="S3880" Action="None" />
<Rule Id="S3898" Action="None" />
<Rule Id="S3902" Action="None" />
<Rule Id="S3906" Action="None" />
<Rule Id="S3908" Action="None" />
<Rule Id="S3909" Action="None" />
<Rule Id="S3956" Action="None" />
<Rule Id="S3962" Action="None" />
<Rule Id="S3963" Action="None" />
<Rule Id="S3967" Action="None" />
<Rule Id="S3990" Action="None" />
<Rule Id="S3992" Action="None" />
<Rule Id="S3993" Action="None" />
<Rule Id="S3994" Action="None" />
<Rule Id="S3995" Action="None" />
<Rule Id="S3996" Action="None" />
<Rule Id="S3997" Action="None" />
<Rule Id="S4000" Action="None" />
<Rule Id="S4002" Action="None" />
<Rule Id="S4004" Action="None" />
<Rule Id="S4005" Action="None" />
<Rule Id="S4017" Action="None" />
<Rule Id="S4018" Action="None" />
<Rule Id="S4022" Action="None" />
<Rule Id="S4023" Action="None" />
<Rule Id="S4025" Action="None" />
<Rule Id="S4026" Action="None" />
<Rule Id="S4027" Action="None" />
<Rule Id="S4039" Action="None" />
<Rule Id="S4047" Action="None" />
<Rule Id="S4049" Action="None" />
<Rule Id="S4050" Action="None" />
<Rule Id="S4052" Action="None" />
<Rule Id="S4055" Action="None" />
<Rule Id="S4056" Action="None" />
<Rule Id="S4057" Action="None" />
<Rule Id="S4058" Action="None" />
<Rule Id="S4059" Action="None" />
<Rule Id="S4060" Action="None" />
<Rule Id="S4069" Action="None" />
<Rule Id="S4070" Action="None" />
<Rule Id="S4225" Action="None" />
<Rule Id="S4226" Action="None" />
</Rules>
</RuleSet>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="Rules for SonarQube" Description="This rule set was automatically generated from SonarQube" ToolsVersion="14.0">
<Rules AnalyzerId="SonarAnalyzer.VisualBasic" RuleNamespace="SonarAnalyzer.VisualBasic">
<Rule Id="S1751" Action="Warning" />
<Rule Id="S1871" Action="Warning" />
<Rule Id="S1656" Action="Warning" />
<Rule Id="S1862" Action="Warning" />
<Rule Id="S1764" Action="Warning" />
<Rule Id="S2178" Action="Warning" />
<Rule Id="S101" Action="Warning" />
<Rule Id="S1075" Action="Warning" />
<Rule Id="S112" Action="Warning" />
<Rule Id="S114" Action="Warning" />
<Rule Id="S117" Action="Warning" />
<Rule Id="S1197" Action="Warning" />
<Rule Id="S1542" Action="Warning" />
<Rule Id="S1643" Action="Warning" />
<Rule Id="S1645" Action="Warning" />
<Rule Id="S1654" Action="Warning" />
<Rule Id="S2304" Action="Warning" />
<Rule Id="S2340" Action="Warning" />
<Rule Id="S2342" Action="Warning" />
<Rule Id="S2344" Action="Warning" />
<Rule Id="S2345" Action="Warning" />
<Rule Id="S2346" Action="Warning" />
<Rule Id="S2347" Action="Warning" />
<Rule Id="S2349" Action="Warning" />
<Rule Id="S2352" Action="Warning" />
<Rule Id="S2355" Action="Warning" />
<Rule Id="S2358" Action="Warning" />
<Rule Id="S2359" Action="Warning" />
<Rule Id="S2365" Action="Warning" />
<Rule Id="S2368" Action="Warning" />
<Rule Id="S2372" Action="Warning" />
<Rule Id="S2375" Action="Warning" />
<Rule Id="S2376" Action="Warning" />
<Rule Id="S2951" Action="Warning" />
<Rule Id="S3385" Action="Warning" />
<Rule Id="S3981" Action="Warning" />
<Rule Id="S4144" Action="Warning" />
<Rule Id="S4142" Action="None" />
<Rule Id="S1659" Action="None" />
<Rule Id="S131" Action="None" />
<Rule Id="S103" Action="None" />
<Rule Id="S104" Action="None" />
<Rule Id="S105" Action="None" />
<Rule Id="S1067" Action="None" />
<Rule Id="S1147" Action="None" />
<Rule Id="S122" Action="None" />
<Rule Id="S1226" Action="None" />
<Rule Id="S134" Action="None" />
<Rule Id="S139" Action="None" />
<Rule Id="S1541" Action="None" />
<Rule Id="S2339" Action="None" />
<Rule Id="S2343" Action="None" />
<Rule Id="S2348" Action="None" />
<Rule Id="S2353" Action="None" />
<Rule Id="S2354" Action="None" />
<Rule Id="S2357" Action="None" />
<Rule Id="S2360" Action="None" />
<Rule Id="S2362" Action="None" />
<Rule Id="S2363" Action="None" />
<Rule Id="S2364" Action="None" />
<Rule Id="S2366" Action="None" />
<Rule Id="S2367" Action="None" />
<Rule Id="S2369" Action="None" />
<Rule Id="S2370" Action="None" />
<Rule Id="S2373" Action="None" />
<Rule Id="S2374" Action="None" />
<Rule Id="S2429" Action="None" />
<Rule Id="S3860" Action="None" />
<Rule Id="S3866" Action="None" />
</Rules>
</RuleSet>

View File

@@ -0,0 +1,695 @@
<?xml version="1.0" encoding="UTF-8"?>
<AnalysisInput>
<Settings>
<Setting>
<Key>sonar.cs.ignoreHeaderComments</Key>
<Value>true</Value>
</Setting>
<Setting>
<Key>sonar.cs.file.suffixes</Key>
<Value>.cs</Value>
</Setting>
</Settings>
<Rules>
<Rule>
<Key>S2589</Key>
</Rule>
<Rule>
<Key>S3433</Key>
</Rule>
<Rule>
<Key>S4061</Key>
</Rule>
<Rule>
<Key>S1121</Key>
</Rule>
<Rule>
<Key>S1854</Key>
</Rule>
<Rule>
<Key>S4457</Key>
</Rule>
<Rule>
<Key>S4456</Key>
</Rule>
<Rule>
<Key>S2278</Key>
</Rule>
<Rule>
<Key>S4211</Key>
</Rule>
<Rule>
<Key>S3923</Key>
</Rule>
<Rule>
<Key>S4426</Key>
</Rule>
<Rule>
<Key>S2486</Key>
</Rule>
<Rule>
<Key>S4433</Key>
</Rule>
<Rule>
<Key>S2758</Key>
</Rule>
<Rule>
<Key>S1751</Key>
</Rule>
<Rule>
<Key>S1871</Key>
</Rule>
<Rule>
<Key>S4586</Key>
</Rule>
<Rule>
<Key>S4581</Key>
</Rule>
<Rule>
<Key>S2737</Key>
</Rule>
<Rule>
<Key>S3400</Key>
</Rule>
<Rule>
<Key>S3649</Key>
</Rule>
<Rule>
<Key>S1144</Key>
</Rule>
<Rule>
<Key>S1264</Key>
</Rule>
<Rule>
<Key>S2201</Key>
</Rule>
<Rule>
<Key>S1118</Key>
</Rule>
<Rule>
<Key>S1006</Key>
</Rule>
<Rule>
<Key>S4214</Key>
</Rule>
<Rule>
<Key>S4210</Key>
</Rule>
<Rule>
<Key>S3241</Key>
</Rule>
<Rule>
<Key>S4428</Key>
</Rule>
<Rule>
<Key>S1048</Key>
</Rule>
<Rule>
<Key>S2183</Key>
</Rule>
<Rule>
<Key>S3168</Key>
</Rule>
<Rule>
<Key>S4220</Key>
</Rule>
<Rule>
<Key>S3261</Key>
</Rule>
<Rule>
<Key>S4260</Key>
</Rule>
<Rule>
<Key>S4159</Key>
</Rule>
<Rule>
<Key>S4277</Key>
</Rule>
<Rule>
<Key>S2583</Key>
</Rule>
<Rule>
<Key>S3440</Key>
</Rule>
<Rule>
<Key>S3776</Key>
<Parameters>
<Parameter>
<Key>threshold</Key>
<Value>15</Value>
</Parameter>
<Parameter>
<Key>propertyThreshold</Key>
<Value>3</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2326</Key>
</Rule>
<Rule>
<Key>S1116</Key>
</Rule>
<Rule>
<Key>S3358</Key>
</Rule>
<Rule>
<Key>S4200</Key>
</Rule>
<Rule>
<Key>S1172</Key>
</Rule>
<Rule>
<Key>S1862</Key>
</Rule>
<Rule>
<Key>S2275</Key>
</Rule>
<Rule>
<Key>S3457</Key>
</Rule>
<Rule>
<Key>S3459</Key>
</Rule>
<Rule>
<Key>S3464</Key>
</Rule>
<Rule>
<Key>S3343</Key>
</Rule>
<Rule>
<Key>S818</Key>
</Rule>
<Rule>
<Key>S1656</Key>
</Rule>
<Rule>
<Key>S2184</Key>
</Rule>
<Rule>
<Key>S1764</Key>
</Rule>
<Rule>
<Key>S2971</Key>
</Rule>
<Rule>
<Key>S3060</Key>
</Rule>
<Rule>
<Key>S101</Key>
</Rule>
<Rule>
<Key>S1066</Key>
</Rule>
<Rule>
<Key>S107</Key>
<Parameters>
<Parameter>
<Key>max</Key>
<Value>7</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S1075</Key>
</Rule>
<Rule>
<Key>S108</Key>
</Rule>
<Rule>
<Key>S110</Key>
<Parameters>
<Parameter>
<Key>max</Key>
<Value>5</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S1104</Key>
</Rule>
<Rule>
<Key>S1110</Key>
</Rule>
<Rule>
<Key>S1117</Key>
</Rule>
<Rule>
<Key>S112</Key>
</Rule>
<Rule>
<Key>S1123</Key>
</Rule>
<Rule>
<Key>S1125</Key>
</Rule>
<Rule>
<Key>S1134</Key>
</Rule>
<Rule>
<Key>S1135</Key>
</Rule>
<Rule>
<Key>S1155</Key>
</Rule>
<Rule>
<Key>S1163</Key>
</Rule>
<Rule>
<Key>S1168</Key>
</Rule>
<Rule>
<Key>S1185</Key>
</Rule>
<Rule>
<Key>S1186</Key>
</Rule>
<Rule>
<Key>S1206</Key>
</Rule>
<Rule>
<Key>S1210</Key>
</Rule>
<Rule>
<Key>S1215</Key>
</Rule>
<Rule>
<Key>S125</Key>
</Rule>
<Rule>
<Key>S1450</Key>
</Rule>
<Rule>
<Key>S1479</Key>
<Parameters>
<Parameter>
<Key>maximum</Key>
<Value>30</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S1481</Key>
</Rule>
<Rule>
<Key>S1607</Key>
</Rule>
<Rule>
<Key>S1643</Key>
</Rule>
<Rule>
<Key>S1699</Key>
</Rule>
<Rule>
<Key>S1848</Key>
</Rule>
<Rule>
<Key>S1905</Key>
</Rule>
<Rule>
<Key>S1939</Key>
</Rule>
<Rule>
<Key>S1940</Key>
</Rule>
<Rule>
<Key>S1944</Key>
</Rule>
<Rule>
<Key>S2068</Key>
<Parameters>
<Parameter>
<Key>credentialWords</Key>
<Value>password, passwd, pwd</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2114</Key>
</Rule>
<Rule>
<Key>S2123</Key>
</Rule>
<Rule>
<Key>S2178</Key>
</Rule>
<Rule>
<Key>S2187</Key>
</Rule>
<Rule>
<Key>S2190</Key>
</Rule>
<Rule>
<Key>S2219</Key>
</Rule>
<Rule>
<Key>S2223</Key>
</Rule>
<Rule>
<Key>S2225</Key>
</Rule>
<Rule>
<Key>S2234</Key>
</Rule>
<Rule>
<Key>S2259</Key>
</Rule>
<Rule>
<Key>S2290</Key>
</Rule>
<Rule>
<Key>S2291</Key>
</Rule>
<Rule>
<Key>S2292</Key>
</Rule>
<Rule>
<Key>S2306</Key>
</Rule>
<Rule>
<Key>S2328</Key>
</Rule>
<Rule>
<Key>S2342</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
<Parameter>
<Key>flagsAttributeFormat</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?s$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2344</Key>
</Rule>
<Rule>
<Key>S2345</Key>
</Rule>
<Rule>
<Key>S2346</Key>
</Rule>
<Rule>
<Key>S2365</Key>
</Rule>
<Rule>
<Key>S2368</Key>
</Rule>
<Rule>
<Key>S2372</Key>
</Rule>
<Rule>
<Key>S2376</Key>
</Rule>
<Rule>
<Key>S2386</Key>
</Rule>
<Rule>
<Key>S2436</Key>
<Parameters>
<Parameter>
<Key>max</Key>
<Value>2</Value>
</Parameter>
<Parameter>
<Key>maxMethod</Key>
<Value>3</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2437</Key>
</Rule>
<Rule>
<Key>S2681</Key>
</Rule>
<Rule>
<Key>S2688</Key>
</Rule>
<Rule>
<Key>S2692</Key>
</Rule>
<Rule>
<Key>S2696</Key>
</Rule>
<Rule>
<Key>S2743</Key>
</Rule>
<Rule>
<Key>S2757</Key>
</Rule>
<Rule>
<Key>S2761</Key>
</Rule>
<Rule>
<Key>S2930</Key>
</Rule>
<Rule>
<Key>S2933</Key>
</Rule>
<Rule>
<Key>S2934</Key>
</Rule>
<Rule>
<Key>S2953</Key>
</Rule>
<Rule>
<Key>S2995</Key>
</Rule>
<Rule>
<Key>S2996</Key>
</Rule>
<Rule>
<Key>S2997</Key>
</Rule>
<Rule>
<Key>S3005</Key>
</Rule>
<Rule>
<Key>S3010</Key>
</Rule>
<Rule>
<Key>S3169</Key>
</Rule>
<Rule>
<Key>S3172</Key>
</Rule>
<Rule>
<Key>S3217</Key>
</Rule>
<Rule>
<Key>S3218</Key>
</Rule>
<Rule>
<Key>S3220</Key>
</Rule>
<Rule>
<Key>S3236</Key>
</Rule>
<Rule>
<Key>S3237</Key>
</Rule>
<Rule>
<Key>S3244</Key>
</Rule>
<Rule>
<Key>S3246</Key>
</Rule>
<Rule>
<Key>S3247</Key>
</Rule>
<Rule>
<Key>S3249</Key>
</Rule>
<Rule>
<Key>S3251</Key>
</Rule>
<Rule>
<Key>S3256</Key>
</Rule>
<Rule>
<Key>S3262</Key>
</Rule>
<Rule>
<Key>S3263</Key>
</Rule>
<Rule>
<Key>S3264</Key>
</Rule>
<Rule>
<Key>S3265</Key>
</Rule>
<Rule>
<Key>S3346</Key>
</Rule>
<Rule>
<Key>S3376</Key>
</Rule>
<Rule>
<Key>S3397</Key>
</Rule>
<Rule>
<Key>S3415</Key>
</Rule>
<Rule>
<Key>S3427</Key>
</Rule>
<Rule>
<Key>S3442</Key>
</Rule>
<Rule>
<Key>S3443</Key>
</Rule>
<Rule>
<Key>S3444</Key>
</Rule>
<Rule>
<Key>S3445</Key>
</Rule>
<Rule>
<Key>S3447</Key>
</Rule>
<Rule>
<Key>S3449</Key>
</Rule>
<Rule>
<Key>S3450</Key>
</Rule>
<Rule>
<Key>S3451</Key>
</Rule>
<Rule>
<Key>S3453</Key>
</Rule>
<Rule>
<Key>S3456</Key>
</Rule>
<Rule>
<Key>S3458</Key>
</Rule>
<Rule>
<Key>S3466</Key>
</Rule>
<Rule>
<Key>S3597</Key>
</Rule>
<Rule>
<Key>S3598</Key>
</Rule>
<Rule>
<Key>S3600</Key>
</Rule>
<Rule>
<Key>S3603</Key>
</Rule>
<Rule>
<Key>S3604</Key>
</Rule>
<Rule>
<Key>S3610</Key>
</Rule>
<Rule>
<Key>S3626</Key>
</Rule>
<Rule>
<Key>S3655</Key>
</Rule>
<Rule>
<Key>S3693</Key>
</Rule>
<Rule>
<Key>S3869</Key>
</Rule>
<Rule>
<Key>S3871</Key>
</Rule>
<Rule>
<Key>S3875</Key>
</Rule>
<Rule>
<Key>S3877</Key>
</Rule>
<Rule>
<Key>S3881</Key>
</Rule>
<Rule>
<Key>S3884</Key>
</Rule>
<Rule>
<Key>S3885</Key>
</Rule>
<Rule>
<Key>S3887</Key>
</Rule>
<Rule>
<Key>S3889</Key>
</Rule>
<Rule>
<Key>S3897</Key>
</Rule>
<Rule>
<Key>S3903</Key>
</Rule>
<Rule>
<Key>S3904</Key>
</Rule>
<Rule>
<Key>S3925</Key>
</Rule>
<Rule>
<Key>S3926</Key>
</Rule>
<Rule>
<Key>S3927</Key>
</Rule>
<Rule>
<Key>S3928</Key>
</Rule>
<Rule>
<Key>S3966</Key>
</Rule>
<Rule>
<Key>S3971</Key>
</Rule>
<Rule>
<Key>S3972</Key>
</Rule>
<Rule>
<Key>S3981</Key>
</Rule>
<Rule>
<Key>S3984</Key>
</Rule>
<Rule>
<Key>S3998</Key>
</Rule>
<Rule>
<Key>S4015</Key>
</Rule>
<Rule>
<Key>S4016</Key>
</Rule>
<Rule>
<Key>S4019</Key>
</Rule>
<Rule>
<Key>S4035</Key>
</Rule>
<Rule>
<Key>S4144</Key>
</Rule>
<Rule>
<Key>S4158</Key>
</Rule>
<Rule>
<Key>S907</Key>
</Rule>
<Rule>
<Key>S927</Key>
</Rule>
</Rules>
<Files>
</Files>
</AnalysisInput>

View File

@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<AnalysisInput>
<Settings>
<Setting>
<Key>sonar.vbnet.ignoreHeaderComments</Key>
<Value>true</Value>
</Setting>
<Setting>
<Key>sonar.vbnet.file.suffixes</Key>
<Value>.vb</Value>
</Setting>
</Settings>
<Rules>
<Rule>
<Key>S1751</Key>
</Rule>
<Rule>
<Key>S1871</Key>
</Rule>
<Rule>
<Key>S1656</Key>
</Rule>
<Rule>
<Key>S1862</Key>
</Rule>
<Rule>
<Key>S1764</Key>
</Rule>
<Rule>
<Key>S2178</Key>
</Rule>
<Rule>
<Key>S101</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S1075</Key>
</Rule>
<Rule>
<Key>S112</Key>
</Rule>
<Rule>
<Key>S114</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^I([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S117</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^[a-z][a-z0-9]*([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S1197</Key>
</Rule>
<Rule>
<Key>S1542</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S1643</Key>
</Rule>
<Rule>
<Key>S1645</Key>
</Rule>
<Rule>
<Key>S1654</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^[a-z][a-z0-9]*([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2304</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?(\.([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?)*$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2340</Key>
</Rule>
<Rule>
<Key>S2342</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
<Parameter>
<Key>flagsAttributeFormat</Key>
<Value>^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?s$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2344</Key>
</Rule>
<Rule>
<Key>S2345</Key>
</Rule>
<Rule>
<Key>S2346</Key>
</Rule>
<Rule>
<Key>S2347</Key>
<Parameters>
<Parameter>
<Key>format</Key>
<Value>^(([a-z][a-z0-9]*)?([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?_)?([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2349</Key>
</Rule>
<Rule>
<Key>S2352</Key>
</Rule>
<Rule>
<Key>S2355</Key>
</Rule>
<Rule>
<Key>S2358</Key>
</Rule>
<Rule>
<Key>S2359</Key>
</Rule>
<Rule>
<Key>S2365</Key>
</Rule>
<Rule>
<Key>S2368</Key>
</Rule>
<Rule>
<Key>S2372</Key>
</Rule>
<Rule>
<Key>S2375</Key>
<Parameters>
<Parameter>
<Key>minimumSeriesLength</Key>
<Value>6</Value>
</Parameter>
</Parameters>
</Rule>
<Rule>
<Key>S2376</Key>
</Rule>
<Rule>
<Key>S2951</Key>
</Rule>
<Rule>
<Key>S3385</Key>
</Rule>
<Rule>
<Key>S3981</Key>
</Rule>
<Rule>
<Key>S4144</Key>
</Rule>
</Rules>
<Files>
</Files>
</AnalysisInput>

View File

@@ -0,0 +1,7 @@
organization=geogeob
projectKey=ModernKeePass
serverUrl=https://sonarcloud.io
serverVersion=7.2.0.12953
dashboardUrl=https://sonarcloud.io/dashboard/index/ModernKeePass
ceTaskId=AWQER9hfTzX59Iu7A6N0
ceTaskUrl=https://sonarcloud.io/api/ce/task?id=AWQER9hfTzX59Iu7A6N0

Binary file not shown.

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.sonarsource.com/msbuild/integration/2015/1">
<ProjectName>ModernKeePass.App</ProjectName>
<ProjectLanguage>C#</ProjectLanguage>
<ProjectType>Product</ProjectType>
<ProjectGuid>a0cfc681-769b-405a-8482-0cdee595a91f</ProjectGuid>
<FullPath>C:\Sources\Other\ModernKeePass\ModernKeePass\ModernKeePass.App.csproj</FullPath>
<IsExcluded>false</IsExcluded>
<AnalysisResults>
<AnalysisResult Id="FilesToAnalyze" Location="C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\out\0\FilesToAnalyze.txt" />
</AnalysisResults>
<AnalysisSettings>
<Property Name="sonar.cs.roslyn.reportFilePath">C:\Sources\Other\ModernKeePass\ModernKeePass\bin\Debug\ModernKeePass.exe.RoslynCA.json</Property>
<Property Name="sonar.cs.analyzer.projectOutPath">C:\Sources\Other\ModernKeePass\ModernKeePass\.sonarqube\out\0</Property>
</AnalysisSettings>
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectInfo>

View File

@@ -0,0 +1,85 @@
P
GC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\ClipboardAction.csutf-8T
KC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\NavigateToUrlAction.csutf-8Q
HC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\SetupFocusAction.csutf-8A
8C:\Sources\Other\ModernKeePass\ModernKeePass\App.xaml.csutf-8X
OC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\IntToSymbolConverter.csutf-8[
RC:\Sources\Other\ModernKeePass\ModernKeePass\Exceptions\DatabaseOpenedException.csutf-8S
JC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ILicenseService.csutf-8[
RC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IProxyInvocationHandler.csutf-8R
IC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IRecentService.csutf-8O
FC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IRecentItem.csutf-8T
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IResourceService.csutf-8V
MC:\Sources\Other\ModernKeePass\ModernKeePass\Services\SingletonServiceBase.csutf-8i
`C:\Sources\Other\ModernKeePass\ModernKeePass\TemplateSelectors\SelectableDataTemplateSelector.csutf-8X
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsSaveVm.csutf-8]
TC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\DonatePage.xaml.csutf-8Q
HC:\Sources\Other\ModernKeePass\ModernKeePass\Services\DatabaseService.csutf-8T
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ISettingsService.csutf-8S
JC:\Sources\Other\ModernKeePass\ModernKeePass\Common\MessageDialogHelper.csutf-8P
GC:\Sources\Other\ModernKeePass\ModernKeePass\Common\NavigationHelper.csutf-8Y
PC:\Sources\Other\ModernKeePass\ModernKeePass\Common\NotifyPropertyChangedBase.csutf-8T
KC:\Sources\Other\ModernKeePass\ModernKeePass\Common\ObservableDictionary.csutf-8L
CC:\Sources\Other\ModernKeePass\ModernKeePass\Common\RelayCommand.csutf-8Q
HC:\Sources\Other\ModernKeePass\ModernKeePass\Common\SuspensionManager.csutf-8P
GC:\Sources\Other\ModernKeePass\ModernKeePass\Services\LicenseService.csutf-8O
FC:\Sources\Other\ModernKeePass\ModernKeePass\Services\RecentService.csutf-8R
IC:\Sources\Other\ModernKeePass\ModernKeePass\Services\ResourcesService.csutf-8Q
HC:\Sources\Other\ModernKeePass\ModernKeePass\Services\SettingsService.csutf-8W
NC:\Sources\Other\ModernKeePass\ModernKeePass\Common\ToastNotificationHelper.csutf-8i
`C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\DiscreteIntToSolidColorBrushConverter.csutf-8d
[C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\EmptyStringToVisibilityConverter.csutf-8Z
QC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\NullToBooleanConverter.csutf-8Q
HC:\Sources\Other\ModernKeePass\ModernKeePass\Exceptions\SaveException.csutf-8\
SC:\Sources\Other\ModernKeePass\ModernKeePass\Extensions\DispatcherTaskExtensions.csutf-8T
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IDatabaseService.csutf-8X
OC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IHasSelectableObject.csutf-8T
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ISelectableModel.csutf-8\
SC:\Sources\Other\ModernKeePass\ModernKeePass\Views\BasePages\LayoutAwarePageBase.csutf-8k
bC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsDatabasePage.xaml.csutf-8n
eC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.csutf-8g
^C:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsSavePage.xaml.csutf-8k
bC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsSecurityPage.xaml.csutf-8j
aC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsWelcomePage.xaml.csutf-8h
_C:\Sources\Other\ModernKeePass\ModernKeePass\TemplateSelectors\FirstItemDataTemplateSelector.csutf-8U
LC:\Sources\Other\ModernKeePass\ModernKeePass\Controls\ListViewWithDisable.csutf-8f
]C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\BreadCrumbUserControl.xaml.csutf-8h
_C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\CompositeKeyUserControl.xaml.csutf-8S
JC:\Sources\Other\ModernKeePass\ModernKeePass\Controls\TextBoxWithButton.csutf-8`
WC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\BooleanToVisibilityConverter.csutf-8Y
PC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\ColorToBrushConverter.csutf-8d
[C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\DoubleToSolidColorBrushConverter.csutf-8g
^C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\InverseBooleanToVisibilityConverter.csutf-8Z
QC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\PluralizationConverter.csutf-8c
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\ProgressBarLegalValuesConverter.csutf-8X
OC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\TextToWidthConverter.csutf-8Q
HC:\Sources\Other\ModernKeePass\ModernKeePass\Events\PasswordEventArgs.csutf-8N
EC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IIsEnabled.csutf-8M
DC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IPwEntity.csutf-8L
CC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPage.xaml.csutf-8\
SC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\AboutPage.xaml.csutf-8b
YC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\NewDatabasePage.xaml.csutf-8P
GC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPage.xaml.csutf-8^
UC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\WelcomePage.xaml.csutf-8K
BC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\AboutVm.csutf-8R
IC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\CompositeKeyVm.csutf-8X
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\ListMenuItemVm.csutf-8X
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\MainMenuItemVm.csutf-8V
MC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\RecentItemVm.csutf-8S
JC:\Sources\Other\ModernKeePass\ModernKeePass\Views\EntryDetailPage.xaml.csutf-8S
JC:\Sources\Other\ModernKeePass\ModernKeePass\Views\GroupDetailPage.xaml.csutf-8c
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\OpenDatabasePage.xaml.csutf-8f
]C:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\RecentDatabasesPage.xaml.csutf-8c
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\SaveDatabasePage.xaml.csutf-8P
GC:\Sources\Other\ModernKeePass\ModernKeePass\Properties\AssemblyInfo.csutf-8K
BC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\EntryVm.csutf-8K
BC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\GroupVm.csutf-8W
NC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsNewVm.csutf-8N
EC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\SettingsVm.csutf-8J
AC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\MainVm.csutf-8I
@C:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\NewVm.csutf-8J
AC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\OpenVm.csutf-8L
CC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\RecentVm.csutf-8J
AC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\SaveVm.csutf-8\
SC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsDatabaseVm.csutf-8i
`C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\HamburgerMenuUserControl.xaml.csutf-8

View File

@@ -0,0 +1,139 @@
I
GC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\ClipboardAction.csM
KC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\NavigateToUrlAction.csJ
HC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\SetupFocusAction.cs:
8C:\Sources\Other\ModernKeePass\ModernKeePass\App.xaml.csQ
OC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\IntToSymbolConverter.csT
RC:\Sources\Other\ModernKeePass\ModernKeePass\Exceptions\DatabaseOpenedException.csL
JC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ILicenseService.csT
RC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IProxyInvocationHandler.csK
IC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IRecentService.csH
FC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IRecentItem.csM
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IResourceService.csO
MC:\Sources\Other\ModernKeePass\ModernKeePass\Services\SingletonServiceBase.csb
`C:\Sources\Other\ModernKeePass\ModernKeePass\TemplateSelectors\SelectableDataTemplateSelector.csQ
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsSaveVm.csV
TC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\DonatePage.xaml.csJ
HC:\Sources\Other\ModernKeePass\ModernKeePass\Services\DatabaseService.csM
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ISettingsService.csL
JC:\Sources\Other\ModernKeePass\ModernKeePass\Common\MessageDialogHelper.csI
GC:\Sources\Other\ModernKeePass\ModernKeePass\Common\NavigationHelper.csR
PC:\Sources\Other\ModernKeePass\ModernKeePass\Common\NotifyPropertyChangedBase.csM
KC:\Sources\Other\ModernKeePass\ModernKeePass\Common\ObservableDictionary.csE
CC:\Sources\Other\ModernKeePass\ModernKeePass\Common\RelayCommand.csJ
HC:\Sources\Other\ModernKeePass\ModernKeePass\Common\SuspensionManager.csI
GC:\Sources\Other\ModernKeePass\ModernKeePass\Services\LicenseService.csH
FC:\Sources\Other\ModernKeePass\ModernKeePass\Services\RecentService.csK
IC:\Sources\Other\ModernKeePass\ModernKeePass\Services\ResourcesService.csJ
HC:\Sources\Other\ModernKeePass\ModernKeePass\Services\SettingsService.csP
NC:\Sources\Other\ModernKeePass\ModernKeePass\Common\ToastNotificationHelper.csb
`C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\DiscreteIntToSolidColorBrushConverter.cs]
[C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\EmptyStringToVisibilityConverter.csS
QC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\NullToBooleanConverter.csJ
HC:\Sources\Other\ModernKeePass\ModernKeePass\Exceptions\SaveException.csU
SC:\Sources\Other\ModernKeePass\ModernKeePass\Extensions\DispatcherTaskExtensions.csM
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IDatabaseService.csQ
OC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IHasSelectableObject.csM
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ISelectableModel.csU
SC:\Sources\Other\ModernKeePass\ModernKeePass\Views\BasePages\LayoutAwarePageBase.csd
bC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsDatabasePage.xaml.csg
eC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.cs`
^C:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsSavePage.xaml.csd
bC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsSecurityPage.xaml.csc
aC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsWelcomePage.xaml.csa
_C:\Sources\Other\ModernKeePass\ModernKeePass\TemplateSelectors\FirstItemDataTemplateSelector.csN
LC:\Sources\Other\ModernKeePass\ModernKeePass\Controls\ListViewWithDisable.cs_
]C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\BreadCrumbUserControl.xaml.csa
_C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\CompositeKeyUserControl.xaml.csL
JC:\Sources\Other\ModernKeePass\ModernKeePass\Controls\TextBoxWithButton.csY
WC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\BooleanToVisibilityConverter.csR
PC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\ColorToBrushConverter.cs]
[C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\DoubleToSolidColorBrushConverter.cs`
^C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\InverseBooleanToVisibilityConverter.csS
QC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\PluralizationConverter.cs\
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\ProgressBarLegalValuesConverter.csQ
OC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\TextToWidthConverter.csJ
HC:\Sources\Other\ModernKeePass\ModernKeePass\Events\PasswordEventArgs.csG
EC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IIsEnabled.csF
DC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IPwEntity.csE
CC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPage.xaml.csU
SC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\AboutPage.xaml.cs[
YC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\NewDatabasePage.xaml.csI
GC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPage.xaml.csW
UC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\WelcomePage.xaml.csD
BC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\AboutVm.csK
IC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\CompositeKeyVm.csQ
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\ListMenuItemVm.csQ
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\MainMenuItemVm.csO
MC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\RecentItemVm.csL
JC:\Sources\Other\ModernKeePass\ModernKeePass\Views\EntryDetailPage.xaml.csL
JC:\Sources\Other\ModernKeePass\ModernKeePass\Views\GroupDetailPage.xaml.cs\
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\OpenDatabasePage.xaml.cs_
]C:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\RecentDatabasesPage.xaml.cs\
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\SaveDatabasePage.xaml.csI
GC:\Sources\Other\ModernKeePass\ModernKeePass\Properties\AssemblyInfo.csD
BC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\EntryVm.csD
BC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\GroupVm.csP
NC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsNewVm.csG
EC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\SettingsVm.csC
AC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\MainVm.csB
@C:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\NewVm.csC
AC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\OpenVm.csE
CC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\RecentVm.csC
AC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\SaveVm.csU
SC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsDatabaseVm.csb
`C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\HamburgerMenuUserControl.xaml.csE
AC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\App.g.i.csC
?C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\App.g.csO
KC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\Colors.g.i.csM
IC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\Colors.g.csk
gC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsSavePage.g.i.csi
eC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsSavePage.g.csj
fC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\UserControls\BreadCrumbUserControl.g.i.csh
dC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\UserControls\BreadCrumbUserControl.g.csl
hC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\UserControls\CompositeKeyUserControl.g.i.csj
fC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\UserControls\CompositeKeyUserControl.g.csP
LC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPage.g.i.csN
JC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPage.g.cs`
\C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\AboutPage.g.i.cs^
ZC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\AboutPage.g.csW
SC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\EntryDetailPage.g.i.csU
QC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\EntryDetailPage.g.csW
SC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\GroupDetailPage.g.i.csU
QC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\GroupDetailPage.g.csa
]C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\DonatePage.g.i.cs_
[C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\DonatePage.g.csf
bC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\NewDatabasePage.g.i.csd
`C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\NewDatabasePage.g.csg
cC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\OpenDatabasePage.g.i.cse
aC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\OpenDatabasePage.g.csj
fC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\RecentDatabasesPage.g.i.csh
dC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\RecentDatabasesPage.g.csg
cC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\SaveDatabasePage.g.i.cse
aC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\SaveDatabasePage.g.csT
PC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPage.g.i.csR
NC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPage.g.csb
^C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\WelcomePage.g.i.cs`
\C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\MainPageFrames\WelcomePage.g.cso
kC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsDatabasePage.g.i.csm
iC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsDatabasePage.g.csr
nC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsNewDatabasePage.g.i.csp
lC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsNewDatabasePage.g.cso
kC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsSecurityPage.g.i.csm
iC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsSecurityPage.g.csn
jC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsWelcomePage.g.i.csl
hC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\SettingsPageFrames\SettingsWelcomePage.g.cs]
YC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\HamburgerButtonStyle.g.i.cs[
WC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\HamburgerButtonStyle.g.csc
_C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\ListViewLeftIndicatorStyle.g.i.csa
]C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\ListViewLeftIndicatorStyle.g.cs\
XC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\NoBorderButtonStyle.g.i.csZ
VC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\NoBorderButtonStyle.g.csO
KC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\Styles.g.i.csM
IC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\Styles.g.cs_
[C:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\TextBoxWithButtonStyle.g.i.cs]
YC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Styles\TextBoxWithButtonStyle.g.csm
iC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\UserControls\HamburgerMenuUserControl.g.i.csk
gC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\Views\UserControls\HamburgerMenuUserControl.g.csL
HC:\Sources\Other\ModernKeePass\ModernKeePass\obj\Debug\XamlTypeInfo.g.csQ
MC:\Users\GBE\AppData\Local\Temp\.NETCore,Version=v4.5.1.AssemblyAttributes.cs

View File

@@ -0,0 +1,180 @@
<EFBFBD>
GC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\ClipboardAction.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=3;2=0;4=0;6=0;8=0;10=0;12=0r
<1A> <17>
KC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\NavigateToUrlAction.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=3;2=0;4=0;6=0;8=0;10=0;12=0r
 !x<01>
<1D>
HC:\Sources\Other\ModernKeePass\ModernKeePass\Actions\SetupFocusAction.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=2;2=1;4=0;6=0;8=0;10=0;12=0r
<1B>
<18>
8C:\Sources\Other\ModernKeePass\ModernKeePass\App.xaml.cs7 8@HR 0=0;5=0;10=0;20=1;30=0;60=0;90=0Z1=5;2=1;4=2;6=1;8=0;10=0;12=0jH*>?@ABFTZ[^`fluvwz|}<7D><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>r<>
 !"#()+,-./023456789:;<CDEFGIJKLNORSUX\]_bdehjmnpqrstxy<79><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>x<10>I !"+-./24579:EFKRX\_bdhmpsx<73><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>
OC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\IntToSymbolConverter.cs7 (08;@;H;R 0=0;5=0;10=0;20=0;30=1;60=0;90=0Z1=0;2=1;4=0;6=0;8=0;10=0;12=1j<31>+,08<@JKLMZ[\]^_`abcdefgjklmnopqrstuvwxyz{|}~<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03>r[
 !"#$%&'()*-./12345679:;=>?ABCDEFGHINOPQRSUVWXYhi<68><03><03><03><03><03>x<02>?
 !"#$%&'()*-./12345679:;=>?ABCDEFGHINOPQXhi<68><03>
RC:\Sources\Other\ModernKeePass\ModernKeePass\Exceptions\DatabaseOpenedException.cs(0R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r <09>
JC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ILicenseService.cs(08@R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r 
<0C>
RC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IProxyInvocationHandler.cs(0R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r <09>
IC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IRecentService.cs(08@R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r
<0F>
FC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IRecentItem.cs(08@R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r

<0B>
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IResourceService.cs(0R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r<07>
MC:\Sources\Other\ModernKeePass\ModernKeePass\Services\SingletonServiceBase.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0r

<0C>
<EFBFBD>
`C:\Sources\Other\ModernKeePass\ModernKeePass\TemplateSelectors\SelectableDataTemplateSelector.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=4;2=1;4=0;6=0;8=0;10=0;12=0r
x<02><0F>
OC:\Sources\Other\ModernKeePass\ModernKeePass\ViewModels\Items\SettingsSaveVm.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=4;2=0;4=0;6=0;8=0;10=0;12=0r
<18>
<15>
TC:\Sources\Other\ModernKeePass\ModernKeePass\Views\MainPageFrames\DonatePage.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0jr

<0F> <0C>
HC:\Sources\Other\ModernKeePass\ModernKeePass\Services\DatabaseService.csQ (082@2H2R 0=0;5=0;10=0;20=0;30=1;60=0;90=0Z1=25;2=5;4=0;6=2;8=0;10=0;12=0j$cdefghky<6B><01><01><01><01><01><01><01><01><01><01><01><01><01>r<>
 !"#$%')*+,-/0123456789:<=>?@BCDEFHIJKLNOPQRTUVWYZ[]^_`ijlmnopqstuvwz{|}~<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02><02><02><02>x<16><01>"#'+,1468>?DEJKPQTUY_npstuwz{|<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02>
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ISettingsService.cs(0R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r<08>
JC:\Sources\Other\ModernKeePass\ModernKeePass\Common\MessageDialogHelper.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=4;2=2;4=0;6=0;8=0;10=0;12=0j 9<DJMPSr?
 !"$%&')*+,-./01234678:=>@ABEFHIKNQTVWXYx<03> "$%+-.028:=BENQTV<54>
GC:\Sources\Other\ModernKeePass\ModernKeePass\Common\NavigationHelper.csD (8>@>H>R 0=0;5=0;10=0;20=0;30=0;60=1;90=0Z1=12;2=8;4=1;6=1;8=0;10=0;12=1j<31> !"#&(*,-./02579:ABCDEFKLMSW`stuvxyz<79><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03>r<>
;<=>?GHINOTUVXYZ[\^abfghiklpq{|}~<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03><03>x*<2A><01>?INTUXZ[afhi<69><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><03><03><03>
PC:\Sources\Other\ModernKeePass\ModernKeePass\Common\NotifyPropertyChangedBase.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=2;4=0;6=0;8=0;10=0;12=0r
x<01>
<19>
KC:\Sources\Other\ModernKeePass\ModernKeePass\Common\ObservableDictionary.cs( (08!@&H!R 0=0;5=0;10=0;20=0;30=1;60=0;90=0Z1=18;2=5;4=1;6=0;8=0;10=0;12=0j
r<>
 !"#$&'()*,-./12345679:;<=>?@ACDEFGHIJKLMOPQRSTUVWXYZ\]^_`abcdfghiklmnpqrsuvwxz{|}<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>x <09>. "().35;=>@FGIJLSWX^_`bhmrw|<7C><01><01><01><01><01><01><01><01>
CC:\Sources\Other\ModernKeePass\ModernKeePass\Common\RelayCommand.cs (8@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=2;2=3;4=0;6=0;8=0;10=0;12=0j%
$%&'(1234567=>?@ABHIJKLr*  !")*+,-./89:;CDEFMNOPQRSTUVx<03>+,-.:EPR<50>
HC:\Sources\Other\ModernKeePass\ModernKeePass\Common\SuspensionManager.cs8 (08@HR 0=0;5=0;10=0;20=1;30=0;60=0;90=0Z1=5;2=3;4=3;6=0;8=0;10=0;12=0j~ !"#)*+,-3456789>HIN\]^_`abcdefmqv<71><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>r<>
$%&'./01:;<=?@ABCDEFJKLOPQRSTUVWXYZghiklnoprstwxyz{|}~<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><02><02><02><02><02><02><02><02><02><02><02>x<15>S&0?BDLOPRSXinoswz|}<7D><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>
GC:\Sources\Other\ModernKeePass\ModernKeePass\Services\LicenseService.cs (08 @ H R 0=0;5=0;10=1;20=0;30=0;60=0;90=0Z1=5;2=0;4=0;6=1;8=0;10=0;12=0j*+r?
!"#$%&'(),-./012345678:;<=>@ABCEFGHIJx<03>#$&'(),.012346<=BG<42>
FC:\Sources\Other\ModernKeePass\ModernKeePass\Services\RecentService.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=4;2=1;4=0;6=0;8=0;10=0;12=0r,
 !#$%&()*+-./012x<06>
 %*/<2F>
IC:\Sources\Other\ModernKeePass\ModernKeePass\Services\ResourcesService.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0r
<11>
<0E>
HC:\Sources\Other\ModernKeePass\ModernKeePass\Services\SettingsService.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=1;4=0;6=0;8=0;10=0;12=0r
x<03>
<1C>
NC:\Sources\Other\ModernKeePass\ModernKeePass\Common\ToastNotificationHelper.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=2;2=1;4=0;6=0;8=0;10=0;12=0r0
 !#$%&'(*+,-./123456x<01> %&'(,.3<EFBFBD>
`C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\DiscreteIntToSolidColorBrushConverter.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=1;6=0;8=0;10=0;12=0r
x<01>
<18>
[C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\EmptyStringToVisibilityConverter.cs 8@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=1;4=0;6=0;8=0;10=0;12=0r
x<02> <11>
QC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\NullToBooleanConverter.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=2;2=0;4=0;6=0;8=0;10=0;12=0r
<12>
<0F>
HC:\Sources\Other\ModernKeePass\ModernKeePass\Exceptions\SaveException.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=2;2=0;4=0;6=0;8=0;10=0;12=0r 
<0E> <0B>
SC:\Sources\Other\ModernKeePass\ModernKeePass\Extensions\DispatcherTaskExtensions.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=2;2=0;4=0;6=0;8=0;10=0;12=0jr
 x<03>
<1E>
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IDatabaseService.cs(08@R 0=0;5=0;10=0;20=1;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0jr 
 !"#<23>
OC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IHasSelectableObject.cs(08@R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r<07>
KC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\ISelectableModel.cs(08@R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r<07>
SC:\Sources\Other\ModernKeePass\ModernKeePass\Views\BasePages\LayoutAwarePageBase.cs" (08#@#H#R 0=0;5=0;10=0;20=0;30=1;60=0;90=0Z1=13;2=4;4=1;6=1;8=0;10=0;12=0j\
"#*+,-.456789:;<=>ABFGOWXYZ[\]^ijlmnrstuv|}~<><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>r<>
 $%&()/012?@DEHIJKLMNPQRSTU_`abcdepwxyz<79><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>x<10>1 $%/01DHJPRacy<63><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01><01>
bC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsDatabasePage.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0jr

<0F> <0C>
eC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0jr

<0F> <0C>
^C:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsSavePage.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0jr

<0F> <0C>
bC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsSecurityPage.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=2;2=0;4=0;6=0;8=0;10=0;12=0j
r
<17><14>
aC:\Sources\Other\ModernKeePass\ModernKeePass\Views\SettingsPageFrames\SettingsWelcomePage.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=0;8=0;10=0;12=0jr

<0F> <0C>
_C:\Sources\Other\ModernKeePass\ModernKeePass\TemplateSelectors\FirstItemDataTemplateSelector.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=4;2=1;4=0;6=0;8=0;10=0;12=0r
x<01>
<0F>
LC:\Sources\Other\ModernKeePass\ModernKeePass\Controls\ListViewWithDisable.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=1;4=0;6=0;8=0;10=0;12=0r
x<02> <11>
]C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\BreadCrumbUserControl.xaml.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=3;2=0;4=0;6=0;8=0;10=0;12=0jr
<1D>
<1B>
_C:\Sources\Other\ModernKeePass\ModernKeePass\Views\UserControls\CompositeKeyUserControl.xaml.cs
(08@HR 0=0;5=0;10=0;20=1;30=0;60=0;90=0Z1=8;2=4;4=0;6=1;8=0;10=0;12=0j `ort
 !"#$%&'()*,-./01234569;<=>@ABCEFGIJKLMNOPQRSTUVWXY[\]^_abcefghijklmpqrsuvwxyz{|~<><01><01><01>x <09>%"#&*./26=GIKLRSUW]_ajkmpqry|~<><01>
JC:\Sources\Other\ModernKeePass\ModernKeePass\Controls\TextBoxWithButton.cs (
0
8 @ H R 0=0;5=0;10=1;20=0;30=0;60=0;90=0Z1=8;2=1;4=0;6=0;8=0;10=0;12=0r@
 !#$%&'()*+,-/0123456789;<=>?@ABCDEx<01>
!%&)-1259=>?A<>
WC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\BooleanToVisibilityConverter.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=0;2=1;4=1;6=0;8=0;10=0;12=0jr
x<04> <18>
PC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\ColorToBrushConverter.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=1;6=0;8=0;10=0;12=0r
x<03>
<17>
[C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\DoubleToSolidColorBrushConverter.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=2;2=0;4=0;6=0;8=0;10=0;12=0r
x<01><1C>
^C:\Sources\Other\ModernKeePass\ModernKeePass\Converters\InverseBooleanToVisibilityConverter.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=0;2=1;4=1;6=0;8=0;10=0;12=0jr
x<04> <18>
QC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\PluralizationConverter.cs (08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=1;8=0;10=0;12=0jr
x<04>
<15>
ZC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\ProgressBarLegalValuesConverter.cs
(08@HR 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=1;2=0;4=0;6=1;8=0;10=0;12=0r
x<05> <18>
OC:\Sources\Other\ModernKeePass\ModernKeePass\Converters\TextToWidthConverter.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=1;2=1;4=0;6=0;8=0;10=0;12=0r
<14>
<11>
HC:\Sources\Other\ModernKeePass\ModernKeePass\Events\PasswordEventArgs.cs (08@HR 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=3;2=0;4=0;6=0;8=0;10=0;12=0r

<0F> <0C>
EC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IIsEnabled.cs(08@R 0=1;5=0;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0r<07>
DC:\Sources\Other\ModernKeePass\ModernKeePass\Interfaces\IPwEntity.cs(08 @ R 0=0;5=1;10=0;20=0;30=0;60=0;90=0Z1=0;2=0;4=0;6=0;8=0;10=0;12=0j "#$r

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,210 @@
sonar.projectKey=ModernKeePass
sonar.working.directory=C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\.sonarqube\\out\\.sonar
sonar.projectBaseDir=C:\\Sources\\Other\\ModernKeePass\\ModernKeePass
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.projectKey=ModernKeePass:A0CFC681-769B-405A-8482-0CDEE595A91F
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.projectName=ModernKeePass.App
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.projectBaseDir=C:\\Sources\\Other\\ModernKeePass\\ModernKeePass
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.sourceEncoding=utf-8
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.sources=\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Actions\\ClipboardAction.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Actions\\NavigateToUrlAction.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Actions\\SetupFocusAction.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\App.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\IntToSymbolConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Exceptions\\DatabaseOpenedException.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\ILicenseService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IProxyInvocationHandler.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IRecentService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IRecentItem.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IResourceService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Services\\SingletonServiceBase.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\TemplateSelectors\\SelectableDataTemplateSelector.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\Items\\SettingsSaveVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\DonatePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Services\\DatabaseService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\ISettingsService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\MessageDialogHelper.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\NavigationHelper.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\NotifyPropertyChangedBase.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\ObservableDictionary.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\RelayCommand.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\SuspensionManager.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Services\\LicenseService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Services\\RecentService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Services\\ResourcesService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Services\\SettingsService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Common\\ToastNotificationHelper.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\DiscreteIntToSolidColorBrushConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\EmptyStringToVisibilityConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\NullToBooleanConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Exceptions\\SaveException.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Extensions\\DispatcherTaskExtensions.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IDatabaseService.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IHasSelectableObject.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\ISelectableModel.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\BasePages\\LayoutAwarePageBase.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsDatabasePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsNewDatabasePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsSavePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsSecurityPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsWelcomePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\TemplateSelectors\\FirstItemDataTemplateSelector.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Controls\\ListViewWithDisable.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\UserControls\\BreadCrumbUserControl.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\UserControls\\CompositeKeyUserControl.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Controls\\TextBoxWithButton.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\BooleanToVisibilityConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\ColorToBrushConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\DoubleToSolidColorBrushConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\InverseBooleanToVisibilityConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\PluralizationConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\ProgressBarLegalValuesConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Converters\\TextToWidthConverter.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Events\\PasswordEventArgs.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IIsEnabled.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Interfaces\\IPwEntity.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\AboutPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\NewDatabasePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\WelcomePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\AboutVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\CompositeKeyVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\Items\\ListMenuItemVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\Items\\MainMenuItemVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\Items\\RecentItemVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\EntryDetailPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\GroupDetailPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\OpenDatabasePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\RecentDatabasesPage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\SaveDatabasePage.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Properties\\AssemblyInfo.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\EntryVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\GroupVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\Items\\SettingsNewVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\SettingsVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\MainVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\NewVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\OpenVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\RecentVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\SaveVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\ViewModels\\Items\\SettingsDatabaseVm.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\UserControls\\HamburgerMenuUserControl.xaml.cs",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\description.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Entry.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Filter.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Group.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.New.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Open.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Recent.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Semantic.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\description.Settings.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Entry.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Filter.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Group.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\New.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Open.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Recent.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Semantic.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\images\\Screenshot\\Settings.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\keywords.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\privacyPolicy.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\releaseNotes.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\en-us\\baselisting\\websiteUrl.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\description.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Entry.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Filter.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Group.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.New.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Open.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Recent.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Semantic.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\description.Settings.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Entry.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Filter.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Group.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\New.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Open.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Recent.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Semantic.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\images\\Screenshot\\Settings.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\keywords.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\privacyPolicy.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\releaseNotes.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\appMetadata\\fr-fr\\baselisting\\websiteUrl.txt",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Logo.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Logo.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Logo.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Logo.scale-80.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.scale-80.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.targetsize-16.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.targetsize-256.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.targetsize-32.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SmallLogo.targetsize-48.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SplashScreen.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SplashScreen.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\ModernKeePass-SplashScreen.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square310x310Logo.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square310x310Logo.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square310x310Logo.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square310x310Logo.scale-80.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square70x70Logo.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square70x70Logo.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square70x70Logo.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Square70x70Logo.scale-80.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\StoreLogo.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\StoreLogo.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\StoreLogo.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Wide310x150Logo.scale-100.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Wide310x150Logo.scale-140.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Wide310x150Logo.scale-180.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Assets\\Wide310x150Logo.scale-80.png",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\packages.config",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Strings\\fr-FR\\Resources.resw",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Strings\\fr-FR\\CodeBehind.resw",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Strings\\en-US\\CodeBehind.resw",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Strings\\en-US\\Resources.resw",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Styles\\Colors.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsSavePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\UserControls\\BreadCrumbUserControl.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\UserControls\\CompositeKeyUserControl.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\AboutPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\EntryDetailPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\GroupDetailPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\DonatePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\NewDatabasePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\OpenDatabasePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\RecentDatabasesPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\SaveDatabasePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\MainPageFrames\\WelcomePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsDatabasePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsNewDatabasePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsSecurityPage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\SettingsPageFrames\\SettingsWelcomePage.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Styles\\HamburgerButtonStyle.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Styles\\ListViewLeftIndicatorStyle.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Styles\\NoBorderButtonStyle.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Styles\\Styles.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Styles\\TextBoxWithButtonStyle.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\Views\\UserControls\\HamburgerMenuUserControl.xaml",\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\App.xaml"
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.cs.roslyn.reportFilePath=C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\bin\\Debug\\ModernKeePass.exe.RoslynCA.json
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.cs.analyzer.projectOutPath=C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\.sonarqube\\out\\0
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.cs.analyzer.projectOutPaths=\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\.sonarqube\\out\\0"
A0CFC681-769B-405A-8482-0CDEE595A91F.sonar.cs.roslyn.reportFilePaths=\
"C:\\Sources\\Other\\ModernKeePass\\ModernKeePass\\bin\\Debug\\ModernKeePass.exe.RoslynCA.json"
sonar.organization=geogeob
sonar.host.url=https://sonarcloud.io
sonar.visualstudio.enable=false
sonar.modules=A0CFC681-769B-405A-8482-0CDEE595A91F

View File

@@ -0,0 +1,3 @@
Analysis succeeded for SonarQube project "", version [Analysis results](https://sonarcloud.io/dashboard/index/ModernKeePass)
- Product projects: 1, test projects: 0
- Invalid projects: 0, skipped projects: 0, excluded projects: 0

View File

@@ -17,6 +17,7 @@ namespace ModernKeePass.Actions
public object Execute(object sender, object parameter)
{
if (string.IsNullOrEmpty(Text)) return null;
var dataPackage = new DataPackage { RequestedOperation = DataPackageOperation.Copy };
dataPackage.SetText(Text);
Clipboard.SetContent(dataPackage);

View File

@@ -0,0 +1,54 @@
using System.Windows.Input;
using Windows.UI.Xaml;
using Microsoft.Xaml.Interactivity;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Actions
{
public class DeleteEntityAction : DependencyObject, IAction
{
public IPwEntity Entity
{
get { return (IPwEntity)GetValue(EntityProperty); }
set { SetValue(EntityProperty, value); }
}
public static readonly DependencyProperty EntityProperty =
DependencyProperty.Register("Entity", typeof(IPwEntity), typeof(DeleteEntityAction),
new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(DeleteEntityAction),
new PropertyMetadata(null));
public object Execute(object sender, object parameter)
{
var resource = new ResourcesService();
var type = Entity is GroupVm ? "Group" : "Entry";
var message = Entity.IsRecycleOnDelete
? resource.GetResourceValue($"{type}RecyclingConfirmation")
: resource.GetResourceValue($"{type}DeletingConfirmation");
var text = Entity.IsRecycleOnDelete ? resource.GetResourceValue($"{type}Recycled") : resource.GetResourceValue($"{type}Deleted");
MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message,
resource.GetResourceValue("EntityDeleteActionButton"),
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
{
ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text);
Entity.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
Command.Execute(null);
}, null).GetAwaiter();
return null;
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using Windows.UI.Xaml;
using Microsoft.Xaml.Interactivity;
using ModernKeePass.Common;
namespace ModernKeePass.Actions
{
public class NavigateToUrlAction : DependencyObject, IAction
{
public string Url
{
get { return (string)GetValue(UrlProperty); }
set { SetValue(UrlProperty, value); }
}
public static readonly DependencyProperty UrlProperty =
DependencyProperty.Register("Url", typeof(string), typeof(NavigateToUrlAction), new PropertyMetadata(string.Empty));
public object Execute(object sender, object parameter)
{
try
{
var uri = new Uri(Url);
return Windows.System.Launcher.LaunchUriAsync(uri).GetAwaiter().GetResult();
}
catch (Exception ex)
{
MessageDialogHelper.ShowErrorDialog(ex).GetAwaiter();
return false;
}
}
}
}

View File

@@ -0,0 +1,33 @@
using Windows.UI.Xaml;
using Microsoft.Xaml.Interactivity;
using ModernKeePass.Common;
namespace ModernKeePass.Actions
{
public class ToastAction : DependencyObject, IAction
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(ToastAction), new PropertyMetadata(string.Empty));
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(ToastAction), new PropertyMetadata(string.Empty));
public object Execute(object sender, object parameter)
{
ToastNotificationHelper.ShowGenericToast(Title, Message);
return null;
}
}
}

View File

@@ -6,11 +6,12 @@
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/TextBoxWithButtonStyle.xaml" />
<ResourceDictionary Source="Styles/HamburgerButtonStyle.xaml" />
<ResourceDictionary Source="Styles/ListViewLeftIndicatorStyle.xaml" />
<ResourceDictionary Source="Styles/NoBorderButtonStyle.xaml" />
<ResourceDictionary Source="Styles/TextBlockStyles.xaml" />
<ResourceDictionary Source="ResourceDictionaries/TextBoxWithButtonStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries/HamburgerButtonStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries/ListViewLeftIndicatorStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries/NoBorderButtonStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries/NoBorderToggleButtonStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

View File

@@ -1,11 +1,15 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Microsoft.HockeyApp;
using ModernKeePass.Common;
using ModernKeePass.Exceptions;
using ModernKeePass.Services;
@@ -20,22 +24,26 @@ namespace ModernKeePass
/// </summary>
sealed partial class App
{
public DatabaseService Database { get; private set; }
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
#if DEBUG
HockeyClient.Current.Configure("2fe83672887b4910b9de93a4398d0f8f");
#else
HockeyClient.Current.Configure("9eb5fbb79b484fbd8daf04635e975c84");
#endif
InitializeComponent();
Suspending += OnSuspending;
Resuming += OnResuming;
UnhandledException += OnUnhandledException;
}
#region Event Handlers
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
private async void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
// Save the argument exception because it's cleared on first access
var exception = unhandledExceptionEventArgs.Exception;
@@ -45,29 +53,49 @@ namespace ModernKeePass
? exception.InnerException
: exception;
if (!(realException is SaveException)) return;
var database = DatabaseService.Instance;
var resource = new ResourcesService();
if (realException is SaveException)
{
unhandledExceptionEventArgs.Handled = true;
MessageDialogHelper.SaveErrorDialog(realException as SaveException, Database);
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("MessageDialogSaveErrorTitle"),
realException.InnerException.Message,
resource.GetResourceValue("MessageDialogSaveErrorButtonSaveAs"),
resource.GetResourceValue("MessageDialogSaveErrorButtonDiscard"),
async command =>
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
SuggestedFileName = $"{database.Name} - copy"
};
savePicker.FileTypeChoices.Add(resource.GetResourceValue("MessageDialogSaveErrorFileTypeDesc"),
new List<string> {".kdbx"});
var file = await savePicker.PickSaveFileAsync();
if (file != null) database.Save(file);
}, null);
}
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
/// <param name="args">Details about the launch request and process.</param>
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
OnLaunchOrActivated(e);
await OnLaunchOrActivated(args);
await HockeyClient.Current.SendCrashesAsync(/* sendWithoutAsking: true */);
}
protected override void OnActivated(IActivatedEventArgs args)
protected override async void OnActivated(IActivatedEventArgs args)
{
OnLaunchOrActivated(args);
await OnLaunchOrActivated(args);
}
private void OnLaunchOrActivated(IActivatedEventArgs e)
private async Task OnLaunchOrActivated(IActivatedEventArgs e)
{
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
@@ -89,40 +117,44 @@ namespace ModernKeePass
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
// Load state from previously terminated application
await SuspensionManager.RestoreAsync();
#if DEBUG
await MessageDialogHelper.ShowNotificationDialog("App terminated", "Windows or an error made the app terminate");
#endif
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e is LaunchActivatedEventArgs)
{
var lauchActivatedEventArgs = (LaunchActivatedEventArgs) e;
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
var lauchActivatedEventArgs = e as LaunchActivatedEventArgs;
if (lauchActivatedEventArgs != null && rootFrame.Content == null)
rootFrame.Navigate(typeof(MainPage), lauchActivatedEventArgs.Arguments);
}
/*else
{
// App is "launched" via the Toast Activation event
UndoEntityDelete(lauchActivatedEventArgs.Arguments);
}*/
}
// This is only available on Windows 10...
/*else if (e is ToastNotificationActivatedEventArgs)
{
var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
// Parse the query string (using QueryString.NET)
UndoEntityDelete(QueryString.Parse(toastActivationArgs.Argument));
}*/
// Ensure the current window is active
Window.Current.Activate();
Database = new DatabaseService();
}
private void OnResuming(object sender, object e)
{
var currentFrame = Window.Current.Content as Frame;
var database = DatabaseService.Instance;
try
{
database.ReOpen();
#if DEBUG
ToastNotificationHelper.ShowGenericToast(database.Name, "Database reopened (changes were saved)");
#endif
}
catch (Exception)
{
currentFrame?.Navigate(typeof(MainPage));
#if DEBUG
ToastNotificationHelper.ShowGenericToast("App resumed", "Nothing to do, no previous database opened");
#endif
}
}
/// <summary>
@@ -130,9 +162,9 @@ namespace ModernKeePass
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
throw new NavigationException(e.SourcePageType);
}
/// <summary>
@@ -142,11 +174,20 @@ namespace ModernKeePass
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
UnhandledException -= OnUnhandledException;
Database.Save();
var database = DatabaseService.Instance;
try
{
if (SettingsService.Instance.GetSetting("SaveSuspend", true)) database.Save();
database.Close(false);
}
catch (Exception exception)
{
ToastNotificationHelper.ShowErrorToast(exception);
}
await SuspensionManager.SaveAsync();
deferral.Complete();
}
@@ -158,8 +199,8 @@ namespace ModernKeePass
{
base.OnFileActivated(args);
var rootFrame = new Frame();
Database.DatabaseFile = args.Files[0] as StorageFile;
rootFrame.Navigate(typeof(MainPage), args);
var file = args.Files[0] as StorageFile;
rootFrame.Navigate(typeof(MainPage), file);
Window.Current.Content = rootFrame;
Window.Current.Activate();
}

View File

@@ -1,54 +1,34 @@
using System;
using System.Collections.Generic;
using Windows.Storage.Pickers;
using System.Threading.Tasks;
using Windows.UI.Popups;
using Windows.UI.Xaml.Media.Animation;
using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Common
{
public static class MessageDialogHelper
{
public static async void ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler action)
public static async Task ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler actionCommand, UICommandInvokedHandler cancelCommand)
{
// Create the message dialog and set its content
var messageDialog = CreateBasicDialog(title, contentText, cancelButtonText);
var messageDialog = CreateBasicDialog(title, contentText, cancelButtonText, cancelCommand);
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
messageDialog.Commands.Add(new UICommand(actionButtonText, action));
messageDialog.Commands.Add(new UICommand(actionButtonText, actionCommand));
// Show the message dialog
await messageDialog.ShowAsync();
}
public static void SaveErrorDialog(SaveException exception, IDatabase database)
{
ShowActionDialog("Save error", exception.InnerException.Message, "Save as", "Discard", async command =>
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
SuggestedFileName = $"{database.DatabaseFile.DisplayName} - copy"
};
savePicker.FileTypeChoices.Add("KeePass 2.x database", new List<string> { ".kdbx" });
var file = await savePicker.PickSaveFileAsync();
if (file != null) database.Save(file);
});
}
public static async void ShowErrorDialog(Exception exception)
public static async Task ShowErrorDialog(Exception exception)
{
if (exception == null) return;
// Create the message dialog and set its content
var messageDialog = CreateBasicDialog("Error occured", exception.Message, "OK");
var messageDialog = CreateBasicDialog(exception.Message, exception.StackTrace, "OK");
// Show the message dialog
await messageDialog.ShowAsync();
}
public static async void ShowNotificationDialog(string title, string message)
public static async Task ShowNotificationDialog(string title, string message)
{
var dialog = CreateBasicDialog(title, message, "OK");
@@ -56,13 +36,13 @@ namespace ModernKeePass.Common
await dialog.ShowAsync();
}
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText)
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText, UICommandInvokedHandler cancelCommand = null)
{
// Create the message dialog and set its content
var messageDialog = new MessageDialog(message, title);
// Add commands and set their callbacks;
messageDialog.Commands.Add(new UICommand(dismissActionText));
// Add commands and set their callbacks
messageDialog.Commands.Add(new UICommand(dismissActionText, cancelCommand));
// Set the command that will be invoked by default
messageDialog.DefaultCommandIndex = 1;

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Windows.Foundation.Collections;
@@ -15,15 +14,15 @@ namespace ModernKeePass.Common
{
public ObservableDictionaryChangedEventArgs(CollectionChange change, string key)
{
this.CollectionChange = change;
this.Key = key;
CollectionChange = change;
Key = key;
}
public CollectionChange CollectionChange { get; private set; }
public string Key { get; private set; }
}
private Dictionary<string, object> _dictionary = new Dictionary<string, object>();
private readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();
public event MapChangedEventHandler<string, object> MapChanged;
private void InvokeMapChanged(CollectionChange change, string key)
@@ -37,13 +36,13 @@ namespace ModernKeePass.Common
public void Add(string key, object value)
{
this._dictionary.Add(key, value);
this.InvokeMapChanged(CollectionChange.ItemInserted, key);
_dictionary.Add(key, value);
InvokeMapChanged(CollectionChange.ItemInserted, key);
}
public void Add(KeyValuePair<string, object> item)
{
this.Add(item.Key, item.Value);
Add(item.Key, item.Value);
}
public void AddRange(IEnumerable<KeyValuePair<string, object>> values)
@@ -56,9 +55,9 @@ namespace ModernKeePass.Common
public bool Remove(string key)
{
if (this._dictionary.Remove(key))
if (_dictionary.Remove(key))
{
this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
InvokeMapChanged(CollectionChange.ItemRemoved, key);
return true;
}
return false;
@@ -67,10 +66,10 @@ namespace ModernKeePass.Common
public bool Remove(KeyValuePair<string, object> item)
{
object currentValue;
if (this._dictionary.TryGetValue(item.Key, out currentValue) &&
Object.Equals(item.Value, currentValue) && this._dictionary.Remove(item.Key))
if (_dictionary.TryGetValue(item.Key, out currentValue) &&
Equals(item.Value, currentValue) && _dictionary.Remove(item.Key))
{
this.InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
return true;
}
return false;
@@ -80,53 +79,53 @@ namespace ModernKeePass.Common
{
get
{
return this._dictionary[key];
return _dictionary[key];
}
set
{
this._dictionary[key] = value;
this.InvokeMapChanged(CollectionChange.ItemChanged, key);
_dictionary[key] = value;
InvokeMapChanged(CollectionChange.ItemChanged, key);
}
}
public void Clear()
{
var priorKeys = this._dictionary.Keys.ToArray();
this._dictionary.Clear();
var priorKeys = _dictionary.Keys.ToArray();
_dictionary.Clear();
foreach (var key in priorKeys)
{
this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
InvokeMapChanged(CollectionChange.ItemRemoved, key);
}
}
public ICollection<string> Keys
{
get { return this._dictionary.Keys; }
get { return _dictionary.Keys; }
}
public bool ContainsKey(string key)
{
return this._dictionary.ContainsKey(key);
return _dictionary.ContainsKey(key);
}
public bool TryGetValue(string key, out object value)
{
return this._dictionary.TryGetValue(key, out value);
return _dictionary.TryGetValue(key, out value);
}
public ICollection<object> Values
{
get { return this._dictionary.Values; }
get { return _dictionary.Values; }
}
public bool Contains(KeyValuePair<string, object> item)
{
return this._dictionary.Contains(item);
return _dictionary.Contains(item);
}
public int Count
{
get { return this._dictionary.Count; }
get { return _dictionary.Count; }
}
public bool IsReadOnly
@@ -136,18 +135,18 @@ namespace ModernKeePass.Common
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return this._dictionary.GetEnumerator();
return _dictionary.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this._dictionary.GetEnumerator();
return _dictionary.GetEnumerator();
}
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
int arraySize = array.Length;
foreach (var pair in this._dictionary)
foreach (var pair in _dictionary)
{
if (arrayIndex >= arraySize) break;
array[arrayIndex++] = pair;

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace ModernKeePass.Common
@@ -41,7 +37,7 @@ namespace ModernKeePass.Common
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
throw new ArgumentNullException(nameof(execute));
_execute = execute;
_canExecute = canExecute;
}
@@ -55,7 +51,7 @@ namespace ModernKeePass.Common
/// <returns>true if this command can be executed; otherwise, false.</returns>
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
return _canExecute?.Invoke() ?? true;
}
/// <summary>
@@ -76,11 +72,7 @@ namespace ModernKeePass.Common
/// </summary>
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
}

View File

@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
@@ -20,10 +17,10 @@ namespace ModernKeePass.Common
/// carry across sessions, but that should be discarded when an application crashes or is
/// upgraded.
/// </summary>
internal sealed class SuspensionManager
internal static class SuspensionManager
{
private static Dictionary<string, object> _sessionState = new Dictionary<string, object>();
private static List<Type> _knownTypes = new List<Type>();
private static readonly List<Type> _knownTypes = new List<Type>();
private const string sessionStateFilename = "_sessionState.xml";
/// <summary>
@@ -33,20 +30,14 @@ namespace ModernKeePass.Common
/// <see cref="DataContractSerializer"/> and should be as compact as possible. Strings
/// and other self-contained data types are strongly recommended.
/// </summary>
public static Dictionary<string, object> SessionState
{
get { return _sessionState; }
}
public static Dictionary<string, object> SessionState => _sessionState;
/// <summary>
/// List of custom types provided to the <see cref="DataContractSerializer"/> when
/// reading and writing session state. Initially empty, additional types may be
/// added to customize the serialization process.
/// </summary>
public static List<Type> KnownTypes
{
get { return _knownTypes; }
}
public static List<Type> KnownTypes => _knownTypes;
/// <summary>
/// Save the current <see cref="SessionState"/>. Any <see cref="Frame"/> instances

View File

@@ -11,16 +11,16 @@ namespace ModernKeePass.Common
{
public static void ShowMovedToast(IPwEntity entity, string action, string text)
{
var entityType = entity is GroupVm ? "Group" : "Entry";
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
var toastElements = notificationXml.GetElementsByTagName("text");
toastElements[0].AppendChild(notificationXml.CreateTextNode($"{action} {entityType} {entity.Name}"));
toastElements[0].AppendChild(notificationXml.CreateTextNode($"{action} {entity.Name}"));
toastElements[1].AppendChild(notificationXml.CreateTextNode(text));
var toastNode = notificationXml.SelectSingleNode("/toast");
// This is useful only for Windows 10 UWP
var launch = new JsonObject
{
{"entityType", JsonValue.CreateStringValue(entityType)},
{"entityType", JsonValue.CreateStringValue(entity.GetType().Name)},
{"entityId", JsonValue.CreateStringValue(entity.Id)}
};
((XmlElement)toastNode)?.SetAttribute("launch", launch.Stringify());
@@ -45,5 +45,10 @@ namespace ModernKeePass.Common
};
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
public static void ShowErrorToast(Exception exception)
{
ShowGenericToast(exception.Source, exception.Message);
}
}
}

View File

@@ -6,6 +6,8 @@ namespace ModernKeePass.Controls
{
public class TextBoxWithButton : TextBox
{
public event EventHandler<RoutedEventArgs> ButtonClick;
public string ButtonSymbol
{
get { return (string)GetValue(ButtonSymbolProperty); }
@@ -17,7 +19,6 @@ namespace ModernKeePass.Controls
typeof(string),
typeof(TextBoxWithButton),
new PropertyMetadata("&#xE107;", (o, args) => { }));
public event EventHandler<RoutedEventArgs> ButtonClick;
public string ButtonTooltip
{
@@ -43,7 +44,6 @@ namespace ModernKeePass.Controls
typeof(TextBoxWithButton),
new PropertyMetadata(true, (o, args) => { }));
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();

View File

@@ -1,20 +0,0 @@
using System;
using Windows.UI.Text;
using Windows.UI.Xaml.Data;
namespace ModernKeePass.Converters
{
public class BooleanToFontStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var boolean = value is bool ? (bool)value : false;
return boolean ? FontStyle.Italic : FontStyle.Normal;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -8,20 +8,20 @@ namespace ModernKeePass.Converters
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var boolean = value is bool ? (bool) value : false;
var boolean = value as bool? ?? false;
return boolean ? Visibility.Visible : Visibility.Collapsed;
}
// No need to implement this
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
var visibility = value is Visibility ? (Visibility) value : Visibility.Visible;
var visibility = value as Visibility? ?? Visibility.Visible;
switch (visibility)
{
case Visibility.Visible: return true;
case Visibility.Collapsed: return false;
default:
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException(nameof(value));
}
}
}

View File

@@ -20,7 +20,8 @@ namespace ModernKeePass.Converters
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
var brush = value as SolidColorBrush;
return brush == null ? new Color() : Color.FromArgb(brush.Color.A, brush.Color.R, brush.Color.G, brush.Color.B);
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using ModernKeePassLib;
namespace ModernKeePass.Converters
{
public class IntToSymbolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var icon = (PwIcon) value;
switch (icon)
{
case PwIcon.Key: return Symbol.Permissions;
case PwIcon.WorldSocket:
case PwIcon.World: return Symbol.World;
case PwIcon.Warning: return Symbol.Important;
case PwIcon.WorldComputer:
case PwIcon.Drive:
case PwIcon.DriveWindows:
case PwIcon.NetworkServer: return Symbol.MapDrive;
case PwIcon.MarkedDirectory: return Symbol.Map;
case PwIcon.UserCommunication: return Symbol.ContactInfo;
case PwIcon.Parts: return Symbol.ViewAll;
case PwIcon.Notepad: return Symbol.Document;
case PwIcon.Identity: return Symbol.Contact2;
case PwIcon.PaperReady: return Symbol.SyncFolder;
case PwIcon.Digicam: return Symbol.Camera;
case PwIcon.IRCommunication: return Symbol.View;
case PwIcon.Energy: return Symbol.ZeroBars;
case PwIcon.Scanner: return Symbol.Scan;
case PwIcon.CDRom: return Symbol.Rotate;
case PwIcon.Monitor: return Symbol.Caption;
case PwIcon.EMailBox:
case PwIcon.EMail: return Symbol.Mail;
case PwIcon.Configuration: return Symbol.Setting;
case PwIcon.ClipboardReady: return Symbol.Paste;
case PwIcon.PaperNew: return Symbol.Page2;
case PwIcon.Screen: return Symbol.GoToStart;
case PwIcon.EnergyCareful: return Symbol.FourBars;
case PwIcon.Disk: return Symbol.Save;
case PwIcon.Console: return Symbol.SlideShow;
case PwIcon.Printer: return Symbol.Scan;
case PwIcon.ProgramIcons: return Symbol.GoToStart;
case PwIcon.Settings:
case PwIcon.Tool: return Symbol.Repair;
case PwIcon.Archive: return Symbol.Crop;
case PwIcon.Count: return Symbol.Calculator;
case PwIcon.Clock: return Symbol.Clock;
case PwIcon.EMailSearch: return Symbol.Find;
case PwIcon.PaperFlag: return Symbol.Flag;
case PwIcon.TrashBin: return Symbol.Delete;
case PwIcon.Expired: return Symbol.ReportHacked;
case PwIcon.Info: return Symbol.Help;
case PwIcon.Folder:
case PwIcon.FolderOpen:
case PwIcon.FolderPackage: return Symbol.Folder;
case PwIcon.PaperLocked: return Symbol.ProtectedDocument;
case PwIcon.Checked: return Symbol.Accept;
case PwIcon.Pen: return Symbol.Edit;
case PwIcon.Thumbnail: return Symbol.BrowsePhotos;
case PwIcon.Book: return Symbol.Library;
case PwIcon.List: return Symbol.List;
case PwIcon.UserKey: return Symbol.ContactPresence;
case PwIcon.Home: return Symbol.Home;
case PwIcon.Star: return Symbol.OutlineStar;
case PwIcon.Money: return Symbol.Shop;
case PwIcon.Certificate: return Symbol.PreviewLink;
case PwIcon.BlackBerry: return Symbol.CellPhone;
default: return Symbol.Stop;
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
var symbol = (Symbol) value;
var defaultIcon = parameter != null ? int.Parse(parameter as string) : -1;
switch (symbol)
{
case Symbol.Delete: return (int)PwIcon.TrashBin;
case Symbol.Edit: return (int) PwIcon.Pen;
case Symbol.Save: return (int) PwIcon.Disk;
case Symbol.Cancel: return (int) PwIcon.Expired;
case Symbol.Accept: return (int) PwIcon.Checked;
case Symbol.Home: return (int) PwIcon.Home;
case Symbol.Camera: return (int) PwIcon.Digicam;
case Symbol.Setting: return (int) PwIcon.Configuration;
case Symbol.Mail: return (int) PwIcon.EMail;
case Symbol.Find: return (int) PwIcon.EMailSearch;
case Symbol.Help: return (int) PwIcon.Info;
case Symbol.Clock: return (int) PwIcon.Clock;
case Symbol.Crop: return (int) PwIcon.Archive;
case Symbol.World: return (int) PwIcon.World;
case Symbol.Flag: return (int) PwIcon.PaperFlag;
case Symbol.PreviewLink: return (int) PwIcon.Certificate;
case Symbol.Document: return (int) PwIcon.Notepad;
case Symbol.ProtectedDocument: return (int) PwIcon.PaperLocked;
case Symbol.ContactInfo: return (int) PwIcon.UserCommunication;
case Symbol.ViewAll: return (int) PwIcon.Parts;
case Symbol.Rotate: return (int) PwIcon.CDRom;
case Symbol.List: return (int) PwIcon.List;
case Symbol.Shop: return (int) PwIcon.Money;
case Symbol.BrowsePhotos: return (int) PwIcon.Thumbnail;
case Symbol.Caption: return (int) PwIcon.Monitor;
case Symbol.Repair: return (int) PwIcon.Tool;
case Symbol.Page2: return (int) PwIcon.PaperNew;
case Symbol.Paste: return (int) PwIcon.ClipboardReady;
case Symbol.Important: return (int) PwIcon.Warning;
case Symbol.SlideShow: return (int) PwIcon.Console;
case Symbol.MapDrive: return (int) PwIcon.NetworkServer;
case Symbol.ContactPresence: return (int) PwIcon.UserKey;
case Symbol.Contact2: return (int) PwIcon.Identity;
case Symbol.Folder: return (int) PwIcon.Folder;
case Symbol.View: return (int) PwIcon.IRCommunication;
case Symbol.Permissions: return (int) PwIcon.Key;
case Symbol.Map: return (int) PwIcon.MarkedDirectory;
case Symbol.CellPhone: return (int) PwIcon.BlackBerry;
case Symbol.OutlineStar: return (int) PwIcon.Star;
case Symbol.Calculator: return (int) PwIcon.Count;
case Symbol.Library: return (int) PwIcon.Book;
case Symbol.SyncFolder: return (int) PwIcon.PaperReady;
case Symbol.GoToStart: return (int) PwIcon.Screen;
case Symbol.ZeroBars: return (int) PwIcon.Energy;
case Symbol.FourBars: return (int) PwIcon.EnergyCareful;
case Symbol.Scan: return (int) PwIcon.Scanner;
default: return defaultIcon;
}
}
}
}

View File

@@ -8,20 +8,20 @@ namespace ModernKeePass.Converters
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var boolean = value is bool ? (bool)value : false;
var boolean = value as bool? ?? false;
return boolean ? Visibility.Collapsed : Visibility.Visible;
}
// No need to implement this
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
var visibility = value is Visibility ? (Visibility)value : Visibility.Visible;
var visibility = value as Visibility? ?? Visibility.Visible;
switch (visibility)
{
case Visibility.Visible: return false;
case Visibility.Collapsed: return true;
default:
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException(nameof(value));
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace ModernKeePass.Exceptions
{
public class NavigationException: Exception
{
public NavigationException(Type pageType) : base($"Failed to load Page {pageType.FullName}")
{
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Interfaces;
namespace ModernKeePass.ImportFormats
{
public class CsvImportFormat: IFormat
{
public bool HasHeaderRow { get; set; } = true;
public char Delimiter { get; set; } = ';';
public char LineDelimiter { get; set; } = '\n';
public async Task<List<Dictionary<string, string>>> Import(IStorageFile source)
{
var parsedResult = new List<Dictionary<string, string>>();
var content = await FileIO.ReadLinesAsync(source);
foreach (var line in content)
{
var fields = line.Split(Delimiter);
var recordItem = new Dictionary<string, string>();
var i = 0;
foreach (var field in fields)
{
recordItem.Add(i.ToString(), field);
i++;
}
parsedResult.Add(recordItem);
}
return parsedResult;
}
}
}

View File

@@ -0,0 +1,16 @@
using Windows.Storage;
using ModernKeePass.Interfaces;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace ModernKeePass.ImportFormats
{
public class NullImportFormat: IFormat
{
public Task<List<Dictionary<string, string>>> Import(IStorageFile source)
{
throw new NotImplementedException();
}
}
}

View File

@@ -6,24 +6,25 @@ using ModernKeePassLib.Keys;
namespace ModernKeePass.Interfaces
{
public interface IDatabase
public interface IDatabaseService
{
string Name { get; }
bool RecycleBinEnabled { get; set; }
int Status { get; set; }
GroupVm RootGroup { get; set; }
GroupVm RecycleBin { get; set; }
StorageFile DatabaseFile { get; set; }
PwUuid DataCipher { get; set; }
PwCompressionAlgorithm CompressionAlgorithm { get; set; }
KdfParameters KeyDerivation { get; set; }
bool IsOpen { get; }
bool HasChanged { get; set; }
void Open(CompositeKey key, bool createNew);
void UpdateCompositeKey(CompositeKey key);
void Open(StorageFile databaseFile, CompositeKey key, bool createNew = false);
void ReOpen();
void Save();
void Save(StorageFile file);
void CreateRecycleBin();
void CreateRecycleBin(string title);
void AddDeletedItem(PwUuid id);
void Close();
void Close(bool releaseFile = true);
void UpdateCompositeKey(CompositeKey newCompositeKey);
}
}

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IFormat
{
Task<List<Dictionary<string, string>>> Import(IStorageFile source);
}
}

View File

@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Interfaces
{
public interface IImportService<in T> where T: IFormat
{
Task Import(T format, IStorageFile source, GroupVm group);
}
}

View File

@@ -1,12 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel.Store;
namespace ModernKeePass.Interfaces
{
public interface ILicenseService
{
IReadOnlyDictionary<string, ProductListing> Products { get; }
Task<int> Purchase(string addOn);
}
}

View File

@@ -0,0 +1,9 @@
using System.Reflection;
namespace ModernKeePass.Interfaces
{
public interface IProxyInvocationHandler
{
object Invoke(object proxy, MethodInfo method, object[] parameters);
}
}

View File

@@ -1,4 +1,5 @@
using Windows.UI.Xaml.Controls;
using System.Collections.Generic;
using System.Windows.Input;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Interfaces
@@ -7,13 +8,21 @@ namespace ModernKeePass.Interfaces
{
GroupVm ParentGroup { get; }
GroupVm PreviousGroup { get; }
Symbol IconSymbol { get; }
int IconId { get; }
string Id { get; }
string Name { get; set; }
string Path { get; }
IEnumerable<IPwEntity> BreadCrumb { get; }
bool IsEditMode { get; }
bool IsRecycleOnDelete { get; }
/// <summary>
/// Save changes to Model
/// </summary>
ICommand SaveCommand { get; }
/// <summary>
/// Restore ViewModel
/// </summary>
ICommand UndoDeleteCommand { get; }
/// <summary>
/// Move a entity to the destination group
/// </summary>
@@ -24,16 +33,8 @@ namespace ModernKeePass.Interfaces
/// </summary>
void CommitDelete();
/// <summary>
/// Restore ViewModel
/// </summary>
void UndoDelete();
/// <summary>
/// Save changes to Model
/// </summary>
void Save();
/// <summary>
/// Delete from ViewModel
/// </summary>
void MarkForDelete();
void MarkForDelete(string recycleBinTitle);
}
}

View File

@@ -4,7 +4,7 @@ using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IRecent
public interface IRecentService
{
int EntryCount { get; }
Task<IStorageItem> GetFileAsync(string token);

View File

@@ -1,6 +1,6 @@
namespace ModernKeePass.Interfaces
{
public interface IResource
public interface IResourceService
{
string GetResourceValue(string key);
}

View File

@@ -1,8 +0,0 @@
namespace ModernKeePass.Interfaces
{
public interface ISettings
{
T GetSetting<T>(string property);
void PutSetting<T>(string property, T value);
}
}

View File

@@ -0,0 +1,8 @@
namespace ModernKeePass.Interfaces
{
public interface ISettingsService
{
T GetSetting<T>(string property, T defaultValue = default(T));
void PutSetting<T>(string property, T value);
}
}

View File

@@ -1,477 +0,0 @@
using Windows.UI.Xaml.Controls;
using ModernKeePassLib;
namespace ModernKeePass.Mappings
{
public static class PwIconToSegoeMapping
{
public static Symbol GetSymbolFromIcon(PwIcon icon)
{
switch (icon)
{
case PwIcon.Key: return Symbol.Permissions;
case PwIcon.WorldSocket:
case PwIcon.World: return Symbol.World;
case PwIcon.Warning: return Symbol.Important;
case PwIcon.WorldComputer:
case PwIcon.Drive:
case PwIcon.DriveWindows:
case PwIcon.NetworkServer: return Symbol.MapDrive;
case PwIcon.MarkedDirectory: return Symbol.Map;
case PwIcon.UserCommunication: return Symbol.ContactInfo;
case PwIcon.Parts: return Symbol.ViewAll;
case PwIcon.Notepad: return Symbol.Document;
case PwIcon.Identity: return Symbol.Contact2;
case PwIcon.PaperReady: return Symbol.SyncFolder;
case PwIcon.Digicam: return Symbol.Camera;
case PwIcon.IRCommunication: return Symbol.View;
case PwIcon.Energy: return Symbol.ZeroBars;
case PwIcon.Scanner: return Symbol.Scan;
case PwIcon.CDRom: return Symbol.Rotate;
case PwIcon.Monitor: return Symbol.Caption;
case PwIcon.EMailBox:
case PwIcon.EMail: return Symbol.Mail;
case PwIcon.Configuration: return Symbol.Setting;
case PwIcon.ClipboardReady: return Symbol.Paste;
case PwIcon.PaperNew: return Symbol.Page2;
case PwIcon.Screen: return Symbol.GoToStart;
case PwIcon.EnergyCareful: return Symbol.FourBars;
case PwIcon.Disk: return Symbol.Save;
//case PwIcon.PaperQ: return Symbol.;
//case PwIcon.TerminalEncrypted: return Symbol.;
case PwIcon.Console: return Symbol.SlideShow;
case PwIcon.Printer: return Symbol.Scan;
case PwIcon.ProgramIcons: return Symbol.GoToStart;
//case PwIcon.Run: return Symbol.;
case PwIcon.Settings:
case PwIcon.Tool: return Symbol.Repair;
case PwIcon.Archive: return Symbol.Crop;
case PwIcon.Count: return Symbol.Calculator;
case PwIcon.Clock: return Symbol.Clock;
case PwIcon.EMailSearch: return Symbol.Find;
case PwIcon.PaperFlag: return Symbol.Flag;
//case PwIcon.Memory: return Symbol.;
case PwIcon.TrashBin: return Symbol.Delete;
case PwIcon.Expired: return Symbol.Cancel;
case PwIcon.Info: return Symbol.Help;
//case PwIcon.Package: return Symbol.;
case PwIcon.Folder:
case PwIcon.FolderOpen:
case PwIcon.FolderPackage: return Symbol.Folder;
//case PwIcon.LockOpen: return Symbol.;
case PwIcon.PaperLocked: return Symbol.ProtectedDocument;
case PwIcon.Checked: return Symbol.Accept;
case PwIcon.Pen: return Symbol.Edit;
case PwIcon.Thumbnail: return Symbol.BrowsePhotos;
case PwIcon.Book: return Symbol.Library;
case PwIcon.List: return Symbol.List;
case PwIcon.UserKey: return Symbol.ContactPresence;
case PwIcon.Home: return Symbol.Home;
case PwIcon.Star: return Symbol.OutlineStar;
//case PwIcon.Tux: return Symbol.;
//case PwIcon.Feather: return Symbol.;
//case PwIcon.Apple: return Symbol.;
//case PwIcon.Wiki: return Symbol.;
case PwIcon.Money: return Symbol.Shop;
case PwIcon.Certificate: return Symbol.PreviewLink;
case PwIcon.BlackBerry: return Symbol.CellPhone;
default: return Symbol.Stop;
}
}
public static PwIcon GetIconFromSymbol(Symbol symbol)
{
switch (symbol)
{
/*case Symbol.Previous:
break;
case Symbol.Next:
break;
case Symbol.Play:
break;
case Symbol.Pause:
break;
case Symbol.Edit:
break;
case Symbol.Save:
break;
case Symbol.Clear:
break;*/
case Symbol.Delete:
return PwIcon.TrashBin;
/*case Symbol.Remove:
break;
case Symbol.Add:
break;
case Symbol.Cancel:
break;
case Symbol.Accept:
break;
case Symbol.More:
break;
case Symbol.Redo:
break;
case Symbol.Undo:
break;
case Symbol.Home:
break;
case Symbol.Up:
break;
case Symbol.Forward:
break;
case Symbol.Back:
break;
case Symbol.Favorite:
break;
case Symbol.Camera:
break;
case Symbol.Setting:
break;
case Symbol.Video:
break;
case Symbol.Sync:
break;
case Symbol.Download:
break;
case Symbol.Mail:
break;
case Symbol.Find:
break;
case Symbol.Help:
break;
case Symbol.Upload:
break;
case Symbol.Emoji:
break;
case Symbol.TwoPage:
break;
case Symbol.LeaveChat:
break;
case Symbol.MailForward:
break;
case Symbol.Clock:
break;
case Symbol.Send:
break;
case Symbol.Crop:
break;
case Symbol.RotateCamera:
break;
case Symbol.People:
break;
case Symbol.OpenPane:
break;
case Symbol.ClosePane:
break;
case Symbol.World:
break;
case Symbol.Flag:
break;
case Symbol.PreviewLink:
break;
case Symbol.Globe:
break;
case Symbol.Trim:
break;
case Symbol.AttachCamera:
break;
case Symbol.ZoomIn:
break;
case Symbol.Bookmarks:
break;
case Symbol.Document:
break;
case Symbol.ProtectedDocument:
break;
case Symbol.Page:
break;
case Symbol.Bullets:
break;
case Symbol.Comment:
break;
case Symbol.MailFilled:
break;
case Symbol.ContactInfo:
break;
case Symbol.HangUp:
break;
case Symbol.ViewAll:
break;
case Symbol.MapPin:
break;
case Symbol.Phone:
break;
case Symbol.VideoChat:
break;
case Symbol.Switch:
break;
case Symbol.Contact:
break;
case Symbol.Rename:
break;
case Symbol.Pin:
break;
case Symbol.MusicInfo:
break;
case Symbol.Go:
break;
case Symbol.Keyboard:
break;
case Symbol.DockLeft:
break;
case Symbol.DockRight:
break;
case Symbol.DockBottom:
break;
case Symbol.Remote:
break;
case Symbol.Refresh:
break;
case Symbol.Rotate:
break;
case Symbol.Shuffle:
break;
case Symbol.List:
break;
case Symbol.Shop:
break;
case Symbol.SelectAll:
break;
case Symbol.Orientation:
break;
case Symbol.Import:
break;
case Symbol.ImportAll:
break;
case Symbol.BrowsePhotos:
break;
case Symbol.WebCam:
break;
case Symbol.Pictures:
break;
case Symbol.SaveLocal:
break;
case Symbol.Caption:
break;
case Symbol.Stop:
break;
case Symbol.ShowResults:
break;
case Symbol.Volume:
break;
case Symbol.Repair:
break;
case Symbol.Message:
break;
case Symbol.Page2:
break;
case Symbol.CalendarDay:
break;
case Symbol.CalendarWeek:
break;
case Symbol.Calendar:
break;
case Symbol.Character:
break;
case Symbol.MailReplyAll:
break;
case Symbol.Read:
break;
case Symbol.Link:
break;
case Symbol.Account:
break;
case Symbol.ShowBcc:
break;
case Symbol.HideBcc:
break;
case Symbol.Cut:
break;
case Symbol.Attach:
break;
case Symbol.Paste:
break;
case Symbol.Filter:
break;
case Symbol.Copy:
break;
case Symbol.Emoji2:
break;
case Symbol.Important:
break;
case Symbol.MailReply:
break;
case Symbol.SlideShow:
break;
case Symbol.Sort:
break;
case Symbol.Manage:
break;
case Symbol.AllApps:
break;
case Symbol.DisconnectDrive:
break;
case Symbol.MapDrive:
break;
case Symbol.NewWindow:
break;
case Symbol.OpenWith:
break;
case Symbol.ContactPresence:
break;
case Symbol.Priority:
break;
case Symbol.GoToToday:
break;
case Symbol.Font:
break;
case Symbol.FontColor:
break;
case Symbol.Contact2:
break;
case Symbol.Folder:
break;
case Symbol.Audio:
break;
case Symbol.Placeholder:
break;
case Symbol.View:
break;
case Symbol.SetLockScreen:
break;
case Symbol.SetTile:
break;
case Symbol.ClosedCaption:
break;
case Symbol.StopSlideShow:
break;
case Symbol.Permissions:
break;
case Symbol.Highlight:
break;
case Symbol.DisableUpdates:
break;
case Symbol.UnFavorite:
break;
case Symbol.UnPin:
break;
case Symbol.OpenLocal:
break;
case Symbol.Mute:
break;
case Symbol.Italic:
break;
case Symbol.Underline:
break;
case Symbol.Bold:
break;
case Symbol.MoveToFolder:
break;
case Symbol.LikeDislike:
break;
case Symbol.Dislike:
break;
case Symbol.Like:
break;
case Symbol.AlignRight:
break;
case Symbol.AlignCenter:
break;
case Symbol.AlignLeft:
break;
case Symbol.Zoom:
break;
case Symbol.ZoomOut:
break;
case Symbol.OpenFile:
break;
case Symbol.OtherUser:
break;
case Symbol.Admin:
break;
case Symbol.Street:
break;
case Symbol.Map:
break;
case Symbol.ClearSelection:
break;
case Symbol.FontDecrease:
break;
case Symbol.FontIncrease:
break;
case Symbol.FontSize:
break;
case Symbol.CellPhone:
break;
case Symbol.ReShare:
break;
case Symbol.Tag:
break;
case Symbol.RepeatOne:
break;
case Symbol.RepeatAll:
break;
case Symbol.OutlineStar:
break;
case Symbol.SolidStar:
break;
case Symbol.Calculator:
break;
case Symbol.Directions:
break;
case Symbol.Target:
break;
case Symbol.Library:
break;
case Symbol.PhoneBook:
break;
case Symbol.Memo:
break;
case Symbol.Microphone:
break;
case Symbol.PostUpdate:
break;
case Symbol.BackToWindow:
break;
case Symbol.FullScreen:
break;
case Symbol.NewFolder:
break;
case Symbol.CalendarReply:
break;
case Symbol.UnSyncFolder:
break;
case Symbol.ReportHacked:
break;
case Symbol.SyncFolder:
break;
case Symbol.BlockContact:
break;
case Symbol.SwitchApps:
break;
case Symbol.AddFriend:
break;
case Symbol.TouchPointer:
break;
case Symbol.GoToStart:
break;
case Symbol.ZeroBars:
break;
case Symbol.OneBar:
break;
case Symbol.TwoBars:
break;
case Symbol.ThreeBars:
break;
case Symbol.FourBars:
break;
case Symbol.Scan:
break;
case Symbol.Preview:
break;*/
default:
return PwIcon.Folder;
}
}
}
}

View File

@@ -15,8 +15,6 @@
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PackageCertificateKeyFile>ModernKeePass_StoreKey.pfx</PackageCertificateKeyFile>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<PackageCertificateThumbprint>ED3AA34F46D03498F989901C5DB2742B65D72F60</PackageCertificateThumbprint>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<AppxBundlePlatforms>neutral</AppxBundlePlatforms>
@@ -31,6 +29,7 @@
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -109,27 +108,38 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Actions\ClipboardAction.cs" />
<Compile Include="Actions\DeleteEntityAction.cs" />
<Compile Include="Actions\NavigateToUrlAction.cs" />
<Compile Include="Actions\SetupFocusAction.cs" />
<Compile Include="Actions\ToastAction.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Interfaces\ILicenseService.cs" />
<Compile Include="Interfaces\IRecent.cs" />
<Compile Include="Converters\IntToSymbolConverter.cs" />
<Compile Include="Exceptions\NavigationException.cs" />
<Compile Include="ImportFormats\CsvImportFormat.cs" />
<Compile Include="ImportFormats\NullImportFormat.cs" />
<Compile Include="Interfaces\IFormat.cs" />
<Compile Include="Interfaces\IImportService.cs" />
<Compile Include="Interfaces\IProxyInvocationHandler.cs" />
<Compile Include="Interfaces\IRecentService.cs" />
<Compile Include="Interfaces\IRecentItem.cs" />
<Compile Include="Interfaces\IResource.cs" />
<Compile Include="ViewModels\DonateVm.cs" />
<Compile Include="Interfaces\IResourceService.cs" />
<Compile Include="Services\ImportService.cs" />
<Compile Include="Services\SingletonServiceBase.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
<DependentUpon>DonatePage.xaml</DependentUpon>
</Compile>
<Compile Include="Services\DatabaseService.cs" />
<Compile Include="Interfaces\ISettings.cs" />
<Compile Include="Interfaces\ISettingsService.cs" />
<Compile Include="Common\MessageDialogHelper.cs" />
<Compile Include="Common\NavigationHelper.cs" />
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
<Compile Include="Common\ObservableDictionary.cs" />
<Compile Include="Common\RelayCommand.cs" />
<Compile Include="Common\SuspensionManager.cs" />
<Compile Include="Services\LicenseService.cs" />
<Compile Include="Services\RecentService.cs" />
<Compile Include="Services\ResourcesService.cs" />
<Compile Include="Services\SettingsService.cs" />
@@ -139,16 +149,22 @@
<Compile Include="Converters\NullToBooleanConverter.cs" />
<Compile Include="Exceptions\SaveException.cs" />
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
<Compile Include="Interfaces\IDatabase.cs" />
<Compile Include="Interfaces\IDatabaseService.cs" />
<Compile Include="Interfaces\IHasSelectableObject.cs" />
<Compile Include="Interfaces\ISelectableModel.cs" />
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
<Compile Include="Views\MainPageFrames\ImportExportPage.xaml.cs">
<DependentUpon>ImportExportPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsPageFrames\SettingsDatabasePage.xaml.cs">
<DependentUpon>SettingsDatabasePage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.cs">
<DependentUpon>SettingsNewDatabasePage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsPageFrames\SettingsSavePage.xaml.cs">
<DependentUpon>SettingsSavePage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsPageFrames\SettingsSecurityPage.xaml.cs">
<DependentUpon>SettingsSecurityPage.xaml</DependentUpon>
</Compile>
@@ -157,6 +173,12 @@
</Compile>
<Compile Include="TemplateSelectors\FirstItemDataTemplateSelector.cs" />
<Compile Include="Controls\ListViewWithDisable.cs" />
<Compile Include="Views\UserControls\BreadCrumbUserControl.xaml.cs">
<DependentUpon>BreadCrumbUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\ColorPickerUserControl.xaml.cs">
<DependentUpon>ColorPickerUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\CompositeKeyUserControl.xaml.cs">
<DependentUpon>CompositeKeyUserControl.xaml</DependentUpon>
</Compile>
@@ -165,7 +187,6 @@
<Compile Include="Converters\ColorToBrushConverter.cs" />
<Compile Include="Converters\DoubleToSolidColorBrushConverter.cs" />
<Compile Include="Converters\InverseBooleanToVisibilityConverter.cs" />
<Compile Include="Converters\BooleanToFontStyleConverter.cs" />
<Compile Include="Converters\PluralizationConverter.cs" />
<Compile Include="Converters\ProgressBarLegalValuesConverter.cs" />
<Compile Include="Converters\TextToWidthConverter.cs" />
@@ -175,7 +196,6 @@
<Compile Include="Views\MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Mappings\PwIconToSegoeMapping.cs" />
<Compile Include="Views\MainPageFrames\AboutPage.xaml.cs">
<DependentUpon>AboutPage.xaml</DependentUpon>
</Compile>
@@ -219,6 +239,15 @@
<Compile Include="ViewModels\RecentVm.cs" />
<Compile Include="ViewModels\SaveVm.cs" />
<Compile Include="ViewModels\Items\SettingsDatabaseVm.cs" />
<Compile Include="Views\UserControls\HamburgerMenuUserControl.xaml.cs">
<DependentUpon>HamburgerMenuUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\SymbolPickerUserControl.xaml.cs">
<DependentUpon>SymbolPickerUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\TopMenuUserControl.xaml.cs">
<DependentUpon>TopMenuUserControl.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
@@ -240,6 +269,27 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="ResourceDictionaries\NoBorderToggleButtonStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Views\MainPageFrames\ImportExportPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SettingsPageFrames\SettingsSavePage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\BreadCrumbUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\ColorPickerUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\CompositeKeyUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -304,47 +354,99 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\HamburgerButtonStyle.xaml">
<Page Include="ResourceDictionaries\HamburgerButtonStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Styles\ListViewLeftIndicatorStyle.xaml">
<Page Include="ResourceDictionaries\ListViewLeftIndicatorStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Styles\NoBorderButtonStyle.xaml">
<Page Include="ResourceDictionaries\NoBorderButtonStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Styles\TextBlockStyles.xaml">
<Page Include="ResourceDictionaries\Styles.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Styles\TextBoxWithButtonStyle.xaml">
<Page Include="ResourceDictionaries\TextBoxWithButtonStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Views\UserControls\HamburgerMenuUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\SymbolPickerUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\TopMenuUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\packages\Portable.BouncyCastle.1.8.1.3\lib\netstandard1.0\BouncyCastle.Crypto.dll</HintPath>
<Reference Include="BouncyCastle.Crypto, Version=1.8.3.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\packages\Portable.BouncyCastle.1.8.3\lib\netstandard1.0\BouncyCastle.Crypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.HockeyApp.Core45, Version=4.1.6.1005, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\HockeySDK.Core.4.1.6\lib\portable-net45+win8+wp8+wpa81+win81+uap10.0\Microsoft.HockeyApp.Core45.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.HockeyApp.Kit, Version=4.1.6.1005, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\HockeySDK.WINRT.4.1.6\lib\portable-win81\Microsoft.HockeyApp.Kit.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Toolkit.Uwp.Notifications, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ModernKeePassLib, Version=2.37.0.2000, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ModernKeePassLib.2.37.8000\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
<Reference Include="ModernKeePassLib, Version=2.39.1.22027, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ModernKeePassLib.2.39.1\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Splat.2.0.0\lib\Portable-Win81+Wpa81\Splat.dll</HintPath>
<Reference Include="Splat, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Splat.3.0.0\lib\netstandard1.1\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Composition.AttributedModel, Version=1.0.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Composition.AttributedModel.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Composition.Convention, Version=1.0.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Composition.Convention.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Composition.Hosting, Version=1.0.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Composition.Hosting.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Composition.Runtime, Version=1.0.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Composition.Runtime.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Composition.TypedParts, Version=1.0.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Composition.TypedParts.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Drawing.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Drawing.Primitives.4.3.0\lib\netstandard1.1\System.Drawing.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Reflection.Metadata, Version=1.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.6.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
@@ -364,7 +466,6 @@
<ItemGroup>
<Content Include="appMetadata\en-us\baselisting\description.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.Entry.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.Filter.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.Group.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.New.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.Open.txt" />
@@ -372,7 +473,6 @@
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.Semantic.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\description.Settings.txt" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\Entry.png" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\Filter.png" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\Group.png" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\New.png" />
<Content Include="appMetadata\en-us\baselisting\images\Screenshot\Open.png" />
@@ -385,7 +485,6 @@
<Content Include="appMetadata\en-us\baselisting\websiteUrl.txt" />
<Content Include="appMetadata\fr-fr\baselisting\description.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.Entry.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.Filter.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.Group.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.New.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.Open.txt" />
@@ -393,7 +492,6 @@
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.Semantic.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\description.Settings.txt" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\Entry.png" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\Filter.png" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\Group.png" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\New.png" />
<Content Include="appMetadata\fr-fr\baselisting\images\Screenshot\Open.png" />
@@ -434,9 +532,6 @@
<Content Include="Assets\Wide310x150Logo.scale-140.png" />
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
<Content Include="Data\WindowsStoreProxy.xml">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' ">
<VisualStudioVersion>12.0</VisualStudioVersion>
@@ -447,10 +542,8 @@
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
<Error Condition="!Exists('..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets'))" />
</Target>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Import Project="..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets" Condition="Exists('..\packages\NETStandard.Library.2.0.1\build\NETStandard.Library.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.10.0.31" />
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.15.0.0" />
<Properties>
<DisplayName>ModernKeePass</DisplayName>
<PublisherDisplayName>wismna</PublisherDisplayName>

View File

@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@@ -10,7 +9,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("wismna")]
[assembly: AssemblyProduct("ModernKeePass")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -24,6 +23,6 @@ using System.Runtime.InteropServices;
// 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.10.0.0")]
[assembly: AssemblyFileVersion("1.10.0.0")]
[assembly: AssemblyVersion("1.14.0.0")]
[assembly: AssemblyFileVersion("1.14.0.0")]
[assembly: ComVisible(false)]

View File

@@ -2,27 +2,40 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="ToggleButton" x:Name="HamburgerToggleButton">
<Style TargetType="ToggleButton" x:Key="HamburgerToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<ContentControl>
<Grid Background="{StaticResource ListViewItemSelectedBackgroundThemeBrush}" Margin="0" Width="50" Height="50">
<Canvas x:Name="hampurger_menu" HorizontalAlignment="Center" Height="17" UseLayoutRounding="False" VerticalAlignment="Center" Width="28">
<Canvas x:Name="Layer_1" Height="17" Canvas.Left="0" Width="28" Margin="0" RenderTransformOrigin="0.5,0.5">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Opacity">
<DiscreteObjectKeyFrame KeyTime="0" Value="0.8" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="Grid" Background="{StaticResource MainColor}" Margin="0" Width="{StaticResource MenuSize}" Height="{StaticResource MenuSize}">
<Canvas x:Name="HamburgerMenu" HorizontalAlignment="Center" Height="17" UseLayoutRounding="False" VerticalAlignment="Center" Width="28">
<Canvas x:Name="Layer1" Height="17" Canvas.Left="0" Width="28" Margin="0" RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<CompositeTransform/>
</Canvas.RenderTransform>
<Canvas.Projection>
<PlaneProjection/>
</Canvas.Projection>
<Path x:Name="path" Data="M0,12.997 L30,12.997" Height="3" Stretch="Fill" StrokeThickness="3" Width="28" Stroke="{ThemeResource DefaultTextForegroundThemeBrush}" StrokeStartLineCap="Square" StrokeEndLineCap="Square" RenderTransformOrigin="0.5,0.5">
<Path x:Name="Path" Data="M0,12.997 L30,12.997" Height="2" Stretch="Fill" StrokeThickness="2" Width="28" Stroke="{ThemeResource DefaultTextForegroundThemeBrush}" StrokeStartLineCap="Square" StrokeEndLineCap="Square" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<CompositeTransform/>
</Path.RenderTransform>
</Path>
<Path Data="M0,12.997 L30,12.997" Height="3" Stretch="Fill" StrokeThickness="3" Width="28" Stroke="{ThemeResource DefaultTextForegroundThemeBrush}" StrokeStartLineCap="Square" StrokeEndLineCap="Square" Canvas.Top="7"/>
<Path x:Name="path1" Data="M0,12.997 L30,12.997" Height="3" Stretch="Fill" StrokeThickness="3" Width="28" Stroke="{ThemeResource DefaultTextForegroundThemeBrush}" StrokeStartLineCap="Square" StrokeEndLineCap="Square" Canvas.Top="14" RenderTransformOrigin="0.5,0.5">
<Path Data="M0,12.997 L30,12.997" Height="2" Stretch="Fill" StrokeThickness="2" Width="28" Stroke="{ThemeResource DefaultTextForegroundThemeBrush}" StrokeStartLineCap="Square" StrokeEndLineCap="Square" Canvas.Top="7"/>
<Path x:Name="Path1" Data="M0,12.997 L30,12.997" Height="2" Stretch="Fill" StrokeThickness="2" Width="28" Stroke="{ThemeResource DefaultTextForegroundThemeBrush}" StrokeStartLineCap="Square" StrokeEndLineCap="Square" Canvas.Top="14" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<CompositeTransform/>
</Path.RenderTransform>

View File

@@ -1,8 +1,6 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Style for Windows.UI.Xaml.Controls.ListViewItem with left selection indicator -->
<Style TargetType="ListViewItem" x:Key="ListViewLeftIndicatorItemExpanded">
@@ -27,7 +25,7 @@
<DoubleAnimation Storyboard.TargetName="PointerOverBorder"
Storyboard.TargetProperty="Opacity"
Duration="0"
To="1" />
To="0.5" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedEarmark"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" />
@@ -193,7 +191,7 @@
To="1" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" />
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MainColor}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
@@ -360,13 +358,13 @@
</Grid>
</Border>
<Border x:Name="SelectedLeftIndicator"
BorderBrush="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}"
BorderBrush="{StaticResource MainColor}"
BorderThickness="5,0,0,0"
Opacity="0"/>
<Rectangle x:Name="SelectedBorder"
IsHitTestVisible="False"
Opacity="0"
Stroke="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}"
Stroke="{StaticResource MainColor}"
StrokeThickness="{ThemeResource ListViewItemSelectedBorderThemeThickness}"
Margin="0" />
<Border x:Name="SelectedCheckMarkOuter"
@@ -375,7 +373,7 @@
VerticalAlignment="Top"
Margin="4">
<Grid x:Name="SelectedCheckMark" Opacity="0" Height="40" Width="40">
<Path x:Name="SelectedEarmark" Data="M0,0 L40,0 L40,40 z" Fill="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}" Stretch="Fill"/>
<Path x:Name="SelectedEarmark" Data="M0,0 L40,0 L40,40 z" Fill="{StaticResource MainColor}" Stretch="Fill"/>
<Path Data="F1 M133.1,17.9 L137.2,13.2 L144.6,19.6 L156.4,5.8 L161.2,9.9 L145.6,28.4 z" Fill="{ThemeResource ListViewItemCheckThemeBrush}" Height="13" Stretch="Fill" Width="15" HorizontalAlignment="Right" Margin="0,5.5,5.5,0" VerticalAlignment="Top" FlowDirection="LeftToRight"/>
</Grid>
</Border>

View File

@@ -1,7 +1,6 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ModernKeePass.Styles">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Default style for Windows.UI.Xaml.Controls.Button -->
<Style TargetType="Button" x:Key="NoBorderButtonStyle">
<Setter Property="Background" Value="{ThemeResource ButtonBackgroundThemeBrush}" />
@@ -49,7 +48,7 @@
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBackgroundThemeBrush}" />
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">

View File

@@ -0,0 +1,204 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- No border style for Windows.UI.Xaml.Controls.Primitives.ToggleButton -->
<Style TargetType="ToggleButton" x:Key="NoBorderToggleButtonStyle">
<Setter Property="Background" Value="{ThemeResource ToggleButtonBackgroundThemeBrush}" />
<Setter Property="Foreground" Value="{ThemeResource ToggleButtonForegroundThemeBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource ToggleButtonBorderThemeBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ToggleButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="12,4,12,5" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPointerOverBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPressedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CheckedPointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPointerOverBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPointerOverBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CheckedPressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPressedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPressedBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CheckedDisabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedDisabledBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonCheckedDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate" />
<VisualState x:Name="IndeterminatePointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPointerOverBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="IndeterminatePressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPressedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="IndeterminateDisabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleButtonDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<DoubleAnimation Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0"
Margin="0">
<ContentPresenter x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"/>
</Border>
<Rectangle x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5" />
<Rectangle x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

File diff suppressed because it is too large Load Diff

View File

@@ -3,13 +3,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:ModernKeePass.Controls">
<Style TargetType="controls:TextBoxWithButton" x:Name="TextBoxWithButtonStyle">
<Style TargetType="controls:TextBoxWithButton" x:Key="TextBoxWithButtonStyle">
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
<Setter Property="Foreground" Value="{ThemeResource TextBoxForegroundThemeBrush}" />
<Setter Property="Background" Value="{ThemeResource TextBoxBackgroundThemeBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource TextBoxBorderThemeBrush}" />
<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextSelectionHighlightColorThemeBrush}" />
<Setter Property="SelectionHighlightColor" Value="{ThemeResource MainColor}" />
<Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
@@ -62,7 +62,7 @@
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<!--<VisualState x:Name="Disabled">
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BackgroundElement"
Storyboard.TargetProperty="Opacity"
@@ -73,7 +73,7 @@
To="0"
Duration="0" />
</Storyboard>
</VisualState>-->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BorderElement"
@@ -84,12 +84,11 @@
Margin="{TemplateBinding BorderThickness}">
<TextBlock x:Name="GlyphElement"
Foreground="{ThemeResource TextBoxButtonForegroundThemeBrush}"
Padding="4,0,4,0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontStyle="Normal"
Padding="4,0,4,0"
Text="{TemplateBinding Content}"
FontSize="{TemplateBinding FontSize}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
AutomationProperties.AccessibilityView="Raw"/>
</Border>
@@ -194,24 +193,22 @@
Grid.Row="1"
Background="{TemplateBinding Background}"
Margin="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="2"
Grid.RowSpan="1"/>
Grid.ColumnSpan="2" />
<Border x:Name="BorderElement"
Grid.Row="1"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="2"
Grid.RowSpan="1"/>
Grid.ColumnSpan="2" Grid.Column="0" />
<ContentPresenter x:Name="HeaderContentPresenter"
Grid.Row="0"
Foreground="{ThemeResource TextBoxForegroundHeaderThemeBrush}"
Margin="0,4,0,4"
Grid.ColumnSpan="2"
Grid.ColumnSpan="2" Grid.Column="0"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
FontWeight="Semilight" />
<ScrollViewer x:Name="ContentElement"
Grid.Row="1"
Grid.Row="1" Grid.Column="0"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
@@ -219,7 +216,6 @@
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
IsTabStop="False"
@@ -230,9 +226,8 @@
Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"
Margin="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
IsTabStop="False"
Grid.ColumnSpan="2"
Grid.ColumnSpan="2" Grid.Column="0"
Content="{TemplateBinding PlaceholderText}"
IsHitTestVisible="False"/>
<Button x:Name="ActionButton"

View File

@@ -1,35 +1,24 @@
using System;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using Microsoft.HockeyApp;
using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels;
using ModernKeePassLib;
using ModernKeePassLib.Collections;
using ModernKeePassLib.Cryptography.KeyDerivation;
using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Keys;
using ModernKeePassLib.Security;
using ModernKeePassLib.Serialization;
namespace ModernKeePass.Services
{
public class DatabaseService: IDatabase
public class DatabaseService: SingletonServiceBase<DatabaseService>, IDatabaseService
{
public enum DatabaseStatus
{
Error = -3,
NoCompositeKey = -2,
CompositeKeyError = -1,
Closed = 0,
Opening = 1,
Opened = 2
}
private readonly PwDatabase _pwDatabase = new PwDatabase();
private readonly ISettings _settings;
private readonly IResource _resource;
private readonly ISettingsService _settings;
private StorageFile _databaseFile;
private GroupVm _recycleBin;
private CompositeKey _compositeKey;
public GroupVm RootGroup { get; set; }
@@ -39,12 +28,11 @@ namespace ModernKeePass.Services
set
{
_recycleBin = value;
_pwDatabase.RecycleBinUuid = _recycleBin.IdUuid;
_pwDatabase.RecycleBinUuid = _recycleBin?.IdUuid;
}
}
public int Status { get; set; } = (int)DatabaseStatus.Closed;
public string Name => DatabaseFile?.Name;
public string Name => _databaseFile?.Name;
public bool RecycleBinEnabled
{
@@ -52,16 +40,6 @@ namespace ModernKeePass.Services
set { _pwDatabase.RecycleBinEnabled = value; }
}
public StorageFile DatabaseFile
{
get { return _databaseFile; }
set
{
_databaseFile = value;
Status = (int)DatabaseStatus.Opening;
}
}
public PwUuid DataCipher
{
get { return _pwDatabase.DataCipherUuid; }
@@ -80,36 +58,47 @@ namespace ModernKeePass.Services
set { _pwDatabase.KdfParameters = value; }
}
public DatabaseService() : this(new SettingsService())
{ }
public bool IsOpen => _pwDatabase.IsOpen;
public bool IsFileOpen => !_pwDatabase.IsOpen && _databaseFile != null;
public bool IsClosed => _databaseFile == null;
public bool HasChanged { get; set; }
public DatabaseService(ISettings settings)
public DatabaseService() : this(SettingsService.Instance)
{
}
public DatabaseService(ISettingsService settings)
{
_settings = settings;
}
/// <summary>
/// Open a KeePass database
/// </summary>
/// <param name="databaseFile">The database file</param>
/// <param name="key">The database composite key</param>
/// <param name="createNew">True to create a new database before opening it</param>
/// <returns>An error message, if any</returns>
public void Open(CompositeKey key, bool createNew = false)
public void Open(StorageFile databaseFile, CompositeKey key, bool createNew = false)
{
try
{
if (databaseFile == null)
{
throw new ArgumentNullException(nameof(databaseFile));
}
if (key == null)
{
Status = (int)DatabaseStatus.NoCompositeKey;
return;
throw new ArgumentNullException(nameof(key));
}
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
_compositeKey = key;
var ioConnection = IOConnectionInfo.FromFile(databaseFile);
if (createNew)
{
_pwDatabase.New(ioConnection, key);
//Get settings default values
if (_settings.GetSetting<bool>("Sample")) CreateSampleData();
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
switch (fileFormat)
{
@@ -120,42 +109,19 @@ namespace ModernKeePass.Services
}
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
if (!_pwDatabase.IsOpen) return;
Status = (int)DatabaseStatus.Opened;
_databaseFile = databaseFile;
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
}
catch (InvalidCompositeKeyException)
catch (InvalidCompositeKeyException ex)
{
Status = (int)DatabaseStatus.CompositeKeyError;
}
catch (Exception)
{
Status = (int)DatabaseStatus.Error;
throw;
HockeyClient.Current.TrackException(ex);
throw new ArgumentException(ex.Message, ex);
}
}
/// <summary>
/// Save the current database to another file and open it
/// </summary>
/// <param name="file">The new database file</param>
public void Save(StorageFile file)
public void ReOpen()
{
var oldFile = DatabaseFile;
DatabaseFile = file;
try
{
_pwDatabase.SaveAs(IOConnectionInfo.FromFile(DatabaseFile), true, new NullStatusLogger());
}
catch
{
DatabaseFile = oldFile;
throw;
}
finally
{
Status = (int)DatabaseStatus.Opened;
}
Open(_databaseFile, _compositeKey);
}
/// <summary>
@@ -163,7 +129,7 @@ namespace ModernKeePass.Services
/// </summary>
public void Save()
{
if (_pwDatabase == null || !_pwDatabase.IsOpen) return;
if (!IsOpen) return;
try
{
_pwDatabase.Save(new NullStatusLogger());
@@ -174,13 +140,32 @@ namespace ModernKeePass.Services
}
}
/// <summary>
/// Save the current database to another file and open it
/// </summary>
/// <param name="file">The new database file</param>
public void Save(StorageFile file)
{
var oldFile = _databaseFile;
_databaseFile = file;
try
{
_pwDatabase.SaveAs(IOConnectionInfo.FromFile(_databaseFile), true, new NullStatusLogger());
}
catch
{
_databaseFile = oldFile;
throw;
}
}
/// <summary>
/// Close the currently opened database
/// </summary>
public void Close()
public void Close(bool releaseFile = true)
{
_pwDatabase?.Close();
Status = (int)DatabaseStatus.Closed;
if (releaseFile) _databaseFile = null;
}
public void AddDeletedItem(PwUuid id)
@@ -188,48 +173,18 @@ namespace ModernKeePass.Services
_pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow));
}
public void CreateRecycleBin()
public void CreateRecycleBin(string title)
{
RecycleBin = RootGroup.AddNewGroup("Recycle bin");
RecycleBin = RootGroup.AddNewGroup(title);
RecycleBin.IsSelected = true;
RecycleBin.IconSymbol = Symbol.Delete;
RecycleBin.IconId = (int)PwIcon.TrashBin;
}
public void UpdateCompositeKey(CompositeKey key)
public void UpdateCompositeKey(CompositeKey newCompositeKey)
{
_pwDatabase.MasterKey = key;
}
private void CreateSampleData()
{
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Banking", PwIcon.Count), true);
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Email", PwIcon.EMail), true);
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Internet", PwIcon.World), true);
var pe = new PwEntry(true, true);
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectTitle,
"Sample Entry"));
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUserName,
"Username"));
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUrl,
PwDefs.HomepageUrl));
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectPassword,
"Password"));
pe.Strings.Set(PwDefs.NotesField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectNotes,
"You may safely delete this sample"));
_pwDatabase.RootGroup.AddEntry(pe, true);
pe = new PwEntry(true, true);
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectTitle,
"Sample Entry #2"));
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUserName,
"Michael321"));
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUrl,
PwDefs.HelpUrl + "kb/testform.html"));
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectPassword,
"12345"));
pe.AutoType.Add(new AutoTypeAssociation("*Test Form - KeePass*", string.Empty));
_pwDatabase.RootGroup.AddEntry(pe, true);
if (newCompositeKey == null) return;
_compositeKey = newCompositeKey;
_pwDatabase.MasterKey = newCompositeKey;
}
}
}

View File

@@ -0,0 +1,25 @@
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class ImportService : IImportService<IFormat>
{
public async Task Import(IFormat format, IStorageFile source, GroupVm group)
{
var data = await format.Import(source);
foreach (var entity in data)
{
var entry = group.AddNewEntry();
entry.Name = entity["0"];
entry.UserName = entity["1"];
entry.Password = entity["2"];
if (entity.Count > 3) entry.Url = entity["3"];
if (entity.Count > 4) entry.Notes = entity["4"];
}
}
}
}

View File

@@ -1,100 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Store;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class LicenseService : ILicenseService
{
public enum PurchaseResult
{
Succeeded,
NothingToFulfill,
PurchasePending,
PurchaseReverted,
ServerError,
NotPurchased,
AlreadyPurchased
}
public IReadOnlyDictionary<string, ProductListing> Products { get; }
//private LicenseInformation _licenseInformation;
private readonly HashSet<Guid> _consumedTransactionIds = new HashSet<Guid>();
public LicenseService()
{
// Initialize the license info for use in the app that is uploaded to the Store.
// Uncomment the following line in the release version of your app.
//_licenseInformation = CurrentApp.LicenseInformation;
// Initialize the license info for testing.
// Comment the following line in the release version of your app.
//_licenseInformation = CurrentAppSimulator.LicenseInformation;
#if DEBUG
try
{
var proxyFile = Package.Current.InstalledLocation.GetFileAsync("data\\WindowsStoreProxy.xml").GetAwaiter().GetResult();
CurrentAppSimulator.ReloadSimulatorAsync(proxyFile).GetAwaiter().GetResult();
}
catch { }
var listing = CurrentAppSimulator.LoadListingInformationAsync().GetAwaiter().GetResult();
#else
var listing = CurrentApp.LoadListingInformationAsync().GetAwaiter().GetResult();
#endif
Products = listing.ProductListings;
}
public async Task<int> Purchase(string addOn)
{
#if DEBUG
var purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync(addOn);
#else
var purchaseResults = await CurrentApp.RequestProductPurchaseAsync(addOn);
#endif
switch (purchaseResults.Status)
{
case ProductPurchaseStatus.Succeeded:
GrantFeatureLocally(purchaseResults.TransactionId);
return (int) await ReportFulfillmentAsync(purchaseResults.TransactionId, addOn);
case ProductPurchaseStatus.NotFulfilled:
// The purchase failed because we haven't confirmed fulfillment of a previous purchase.
// Fulfill it now.
if (!IsLocallyFulfilled(purchaseResults.TransactionId))
{
GrantFeatureLocally(purchaseResults.TransactionId);
}
return (int) await ReportFulfillmentAsync(purchaseResults.TransactionId, addOn);
case ProductPurchaseStatus.NotPurchased:
return (int) PurchaseResult.NotPurchased;
case ProductPurchaseStatus.AlreadyPurchased:
return (int) PurchaseResult.AlreadyPurchased;
default:
throw new ArgumentOutOfRangeException();
}
}
private async Task<PurchaseResult> ReportFulfillmentAsync(Guid transactionId, string productName)
{
#if DEBUG
var result = await CurrentAppSimulator.ReportConsumableFulfillmentAsync(productName, transactionId);
#else
var result = await CurrentApp.ReportConsumableFulfillmentAsync(productName, transactionId);
#endif
return (PurchaseResult) result;
}
private void GrantFeatureLocally(Guid transactionId)
{
_consumedTransactionIds.Add(transactionId);
}
private bool IsLocallyFulfilled(Guid transactionId)
{
return _consumedTransactionIds.Contains(transactionId);
}
}
}

View File

@@ -8,7 +8,7 @@ using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class RecentService : IRecent
public class RecentService : SingletonServiceBase<RecentService>, IRecentService
{
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;

View File

@@ -3,7 +3,7 @@ using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class ResourcesService: IResource
public class ResourcesService: IResourceService
{
private const string ResourceFileName = "CodeBehind";
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();

View File

@@ -5,11 +5,11 @@ using ModernKeePass.Interfaces;
namespace ModernKeePass.Services
{
public class SettingsService : ISettings
public class SettingsService : SingletonServiceBase<SettingsService>, ISettingsService
{
private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values;
public T GetSetting<T>(string property)
public T GetSetting<T>(string property, T defaultValue = default(T))
{
try
{
@@ -17,7 +17,7 @@ namespace ModernKeePass.Services
}
catch (InvalidCastException)
{
return default(T);
return defaultValue;
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace ModernKeePass.Services
{
public abstract class SingletonServiceBase<T> where T : new()
{
private static readonly Lazy<T> LazyInstance =
new Lazy<T>(() => new T());
public static T Instance => LazyInstance.Value;
}
}

View File

@@ -121,19 +121,13 @@
<value>Select key file from disk...</value>
</data>
<data name="CompositeKeyErrorOpen" xml:space="preserve">
<value>Error</value>
<value>Error: </value>
</data>
<data name="CompositeKeyErrorUserKeyFile" xml:space="preserve">
<value>key file</value>
</data>
<data name="CompositeKeyErrorUserOr" xml:space="preserve">
<value> or </value>
<value>- wrong key file</value>
</data>
<data name="CompositeKeyErrorUserPassword" xml:space="preserve">
<value>password</value>
</data>
<data name="CompositeKeyErrorUserStart" xml:space="preserve">
<value>Error: wrong </value>
<value>- password incorrect</value>
</data>
<data name="CompositeKeyOpening" xml:space="preserve">
<value>Opening...</value>
@@ -141,48 +135,6 @@
<data name="CompositeKeyUpdated" xml:space="preserve">
<value>Database composite key updated.</value>
</data>
<data name="DonateAlreadyPurchasedMessage" xml:space="preserve">
<value>Your product has already been purchased.</value>
</data>
<data name="DonateAlreadyPurchasedTitle" xml:space="preserve">
<value>Purchase</value>
</data>
<data name="DonateNothingToFulfillMessage" xml:space="preserve">
<value>No purchased product to fulfill</value>
</data>
<data name="DonateNothingToFulfillTitle" xml:space="preserve">
<value>Fulfillment</value>
</data>
<data name="DonateNotPurchasedMessage" xml:space="preserve">
<value>The purchase failed because we haven't confirmed fulfillment of a previous purchase.</value>
</data>
<data name="DonateNotPurchasedTitle" xml:space="preserve">
<value>Purchase</value>
</data>
<data name="DonatePurchasePendingMessage" xml:space="preserve">
<value>The purchase is pending so we cannot fulfill the product.</value>
</data>
<data name="DonatePurchasePendingTitle" xml:space="preserve">
<value>Purchase</value>
</data>
<data name="DonatePurchaseRevertedMessage" xml:space="preserve">
<value>Your purchase has been reverted.</value>
</data>
<data name="DonatePurchaseRevertedTitle" xml:space="preserve">
<value>Purchase</value>
</data>
<data name="DonateServerErrorMessage" xml:space="preserve">
<value>Impossible to contact the Windows Store, there was an error when fulfilling.</value>
</data>
<data name="DonateServerErrorTitle" xml:space="preserve">
<value>Error</value>
</data>
<data name="DonateSucceededMessage" xml:space="preserve">
<value>Your donation was successful.</value>
</data>
<data name="DonateSucceededTitle" xml:space="preserve">
<value>Thank you!</value>
</data>
<data name="EntityDeleteActionButton" xml:space="preserve">
<value>Delete</value>
</data>
@@ -204,9 +156,6 @@
<data name="EntryDeletingConfirmation" xml:space="preserve">
<value>Are you sure you want to delete this entry?</value>
</data>
<data name="EntryNew" xml:space="preserve">
<value>&lt; New entry &gt;</value>
</data>
<data name="EntryRecycled" xml:space="preserve">
<value>Entry moved to the Recycle bin</value>
</data>
@@ -222,9 +171,6 @@
<data name="GroupDeletingConfirmation" xml:space="preserve">
<value>Are you sure you want to delete the whole group and all its entries?</value>
</data>
<data name="GroupNew" xml:space="preserve">
<value>&lt; New group &gt;</value>
</data>
<data name="GroupRecycled" xml:space="preserve">
<value>Group moved to the Recycle bin</value>
</data>
@@ -270,4 +216,46 @@
<data name="SettingsMenuItemSecurity" xml:space="preserve">
<value>Security</value>
</data>
<data name="CompositeKeyErrorUserAccount" xml:space="preserve">
<value>- user account</value>
</data>
<data name="SettingsMenuItemSave" xml:space="preserve">
<value>Saving</value>
</data>
<data name="RecycleBinTitle" xml:space="preserve">
<value>Recycle Bin</value>
</data>
<data name="EntryCurrent" xml:space="preserve">
<value>Current</value>
</data>
<data name="MessageDialogDBOpenButtonDiscard" xml:space="preserve">
<value>Discard</value>
</data>
<data name="MessageDialogDBOpenButtonSave" xml:space="preserve">
<value>Save changes</value>
</data>
<data name="MessageDialogDBOpenDesc" xml:space="preserve">
<value>Database {0} is currently opened. What would you wish to do?</value>
</data>
<data name="MessageDialogDBOpenTitle" xml:space="preserve">
<value>Opened database</value>
</data>
<data name="MessageDialogSaveErrorButtonDiscard" xml:space="preserve">
<value>Discard</value>
</data>
<data name="MessageDialogSaveErrorButtonSaveAs" xml:space="preserve">
<value>Save as</value>
</data>
<data name="MessageDialogSaveErrorFileTypeDesc" xml:space="preserve">
<value>KeePass 2.x database</value>
</data>
<data name="MessageDialogSaveErrorTitle" xml:space="preserve">
<value>Save error</value>
</data>
<data name="ToastSavedMessage" xml:space="preserve">
<value>Database successfully saved!</value>
</data>
<data name="NewImportFormatHelpCSV" xml:space="preserve">
<value>The CSV file needs to be formatted as such: Name of the account;Login;Password;URL;Comments</value>
</data>
</root>

View File

@@ -171,11 +171,14 @@
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
<value>Password</value>
</data>
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
<value>Windows User Account</value>
</data>
<data name="DonateButton.Content" xml:space="preserve">
<value>Donate</value>
</data>
<data name="DonateDesc.Text" xml:space="preserve">
<value>Like this app? Why not make a small donation to support my work and help this app stay ad-free :) ?</value>
<value>Like this app? Why not make a small donation to support my work and help me keep it ad-free :) ?</value>
</data>
<data name="EntryExpirationDate.Content" xml:space="preserve">
<value>Expiration date</value>
@@ -183,6 +186,15 @@
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
<value>Password has expired</value>
</data>
<data name="EntryItemCopyLogin.Text" xml:space="preserve">
<value>Copy login</value>
</data>
<data name="EntryItemCopyPassword.Text" xml:space="preserve">
<value>Copy password</value>
</data>
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
<value>Navigate to URL</value>
</data>
<data name="EntryLogin.Text" xml:space="preserve">
<value>User name or login</value>
</data>
@@ -198,15 +210,6 @@
<data name="GroupCreateEntry.Text" xml:space="preserve">
<value>Create new entry</value>
</data>
<data name="GroupFilter.PlaceholderText" xml:space="preserve">
<value>Filter...</value>
</data>
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
<value>&lt; New group &gt;</value>
</data>
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
<value>&lt; New group &gt;</value>
</data>
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
<value>Search...</value>
</data>
@@ -270,6 +273,9 @@
<data name="RecentClear.Text" xml:space="preserve">
<value>Clear all</value>
</data>
<data name="ReorderEntriesLabel.Text" xml:space="preserve">
<value>Drag and drop entries to reorder them</value>
</data>
<data name="SaveAsButton.Content" xml:space="preserve">
<value>Save as...</value>
</data>
@@ -300,6 +306,12 @@
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
<value>Enabled</value>
</data>
<data name="SettingsDatabaseRecycleBinCreate.Content" xml:space="preserve">
<value>Create a new group</value>
</data>
<data name="SettingsDatabaseRecycleBinExisting.Content" xml:space="preserve">
<value>Use an existing group</value>
</data>
<data name="SettingsNewDatabaseDesc.Text" xml:space="preserve">
<value>Here, you can change some default options when creating a database.</value>
</data>
@@ -318,6 +330,18 @@
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
<value>Yes</value>
</data>
<data name="SettingsSaveDatabaseSuspend.OffContent" xml:space="preserve">
<value>Don't save</value>
</data>
<data name="SettingsSaveDatabaseSuspend.OnContent" xml:space="preserve">
<value>Save</value>
</data>
<data name="SettingsSaveDatabaseSuspendDesc.Text" xml:space="preserve">
<value>This settings is generally recommended. If you enable it, database will automatically be saved on application suspension and closing. However, if your database is huge, saving may be deemed too long by Windows, which will then forcibly kill the app.</value>
</data>
<data name="SettingsSaveDatabaseSuspendTitle.Text" xml:space="preserve">
<value>Auto-save on suspend?</value>
</data>
<data name="SettingsSecurityDesc1.Text" xml:space="preserve">
<value>Here, you may change your database password, key file, or both. Just click on on</value>
</data>
@@ -351,4 +375,121 @@
<data name="WelcomeOpen.Text" xml:space="preserve">
<value>Have an existing password database? Open it here.</value>
</data>
<data name="GroupsLeftListView.ButtonLabel" xml:space="preserve">
<value>New group</value>
</data>
<data name="GroupsLeftListView.HeaderLabel" xml:space="preserve">
<value>Groups</value>
</data>
<data name="HistoryLeftListView.HeaderLabel" xml:space="preserve">
<value>History</value>
</data>
<data name="ToastCopyLogin.Message" xml:space="preserve">
<value>Login copied to clipboard</value>
</data>
<data name="ToastCopyPassword.Message" xml:space="preserve">
<value>Password copied to clipboard</value>
</data>
<data name="ToastCopyUrl.Message" xml:space="preserve">
<value>URL copied to clipboard</value>
</data>
<data name="EntryBackgroundColor.Text" xml:space="preserve">
<value>Background color</value>
</data>
<data name="EntryForegroundColor.Text" xml:space="preserve">
<value>Foreground color</value>
</data>
<data name="EntrySymbol.Text" xml:space="preserve">
<value>Icon</value>
</data>
<data name="AddEntryTooltip.Content" xml:space="preserve">
<value>Create a new entry</value>
</data>
<data name="HamburgerMenuHomeLabel.Text" xml:space="preserve">
<value>Home</value>
</data>
<data name="HamburgerMenuHomeTooltip.Content" xml:space="preserve">
<value>Home</value>
</data>
<data name="HamburgerMenuSettingsLabel.Text" xml:space="preserve">
<value>Settings</value>
</data>
<data name="HamburgerMenuSettingsTooltip.Content" xml:space="preserve">
<value>Settings</value>
</data>
<data name="TopMenuDeleteButton.Content" xml:space="preserve">
<value>Delete</value>
</data>
<data name="TopMenuDeleteFlyout.Text" xml:space="preserve">
<value>Delete</value>
</data>
<data name="TopMenuEditButton.Content" xml:space="preserve">
<value>Edit</value>
</data>
<data name="TopMenuEditFlyout.Text" xml:space="preserve">
<value>Edit</value>
</data>
<data name="TopMenuMoreButton.Content" xml:space="preserve">
<value>More</value>
</data>
<data name="TopMenuRestoreButton.Content" xml:space="preserve">
<value>Restore</value>
</data>
<data name="TopMenuRestoreFlyout.Text" xml:space="preserve">
<value>Restore</value>
</data>
<data name="TopMenuSaveButton.Content" xml:space="preserve">
<value>Save</value>
</data>
<data name="TopMenuSaveFlyout.Text" xml:space="preserve">
<value>Save</value>
</data>
<data name="TopMenuSortButton.Content" xml:space="preserve">
<value>Sort</value>
</data>
<data name="TopMenuSortEntriesFlyout.Text" xml:space="preserve">
<value>Sort entries</value>
</data>
<data name="TopMenuSortGroupsFlyout.Text" xml:space="preserve">
<value>Sort groups</value>
</data>
<data name="ToastUpdateDatabase.Message" xml:space="preserve">
<value>Database successfully updated</value>
</data>
<data name="ToastUpdateDatabase.Title" xml:space="preserve">
<value>Composite Key</value>
</data>
<data name="EntryTitle.PlaceholderText" xml:space="preserve">
<value>New entry name...</value>
</data>
<data name="SearchButtonLabel.Text" xml:space="preserve">
<value>Search</value>
</data>
<data name="SearchButtonTooltip.Content" xml:space="preserve">
<value>Search</value>
</data>
<data name="LoginTextBox.ButtonTooltip" xml:space="preserve">
<value>Copy login</value>
</data>
<data name="PasswordTextBox.ButtonTooltip" xml:space="preserve">
<value>Copy password</value>
</data>
<data name="UrlTextBox.ButtonTooltip" xml:space="preserve">
<value>Navigate to URL</value>
</data>
<data name="RestoreEntryCommand.Message" xml:space="preserve">
<value>Entry restored to its original position</value>
</data>
<data name="RestoreGroupCommand.Message" xml:space="preserve">
<value>Group restored to its original position</value>
</data>
<data name="NewImportCheckbox.Content" xml:space="preserve">
<value>Import existing data</value>
</data>
<data name="NewImportFile.Content" xml:space="preserve">
<value>Select a file to import...</value>
</data>
<data name="NewImportFormat.Text" xml:space="preserve">
<value>Format</value>
</data>
</root>

View File

@@ -121,19 +121,13 @@
<value>Choisissez un fichier...</value>
</data>
<data name="CompositeKeyErrorOpen" xml:space="preserve">
<value>Erreur</value>
<value>Erreur: </value>
</data>
<data name="CompositeKeyErrorUserKeyFile" xml:space="preserve">
<value>fichier de clé</value>
</data>
<data name="CompositeKeyErrorUserOr" xml:space="preserve">
<value> ou </value>
<value>- mauvais fichier de clé</value>
</data>
<data name="CompositeKeyErrorUserPassword" xml:space="preserve">
<value>mot de passe</value>
</data>
<data name="CompositeKeyErrorUserStart" xml:space="preserve">
<value>Erreur: mauvais </value>
<value>- mot de passe incorrect</value>
</data>
<data name="CompositeKeyOpening" xml:space="preserve">
<value>Ouverture...</value>
@@ -141,48 +135,6 @@
<data name="CompositeKeyUpdated" xml:space="preserve">
<value>Clé composite de la base de données mise à jour.</value>
</data>
<data name="DonateAlreadyPurchasedMessage" xml:space="preserve">
<value>Vous avez déjà acheté ce produit.</value>
</data>
<data name="DonateAlreadyPurchasedTitle" xml:space="preserve">
<value>Achat</value>
</data>
<data name="DonateNothingToFulfillMessage" xml:space="preserve">
<value>Il n'y a aucun produit acheté à valider.</value>
</data>
<data name="DonateNothingToFulfillTitle" xml:space="preserve">
<value>Validation</value>
</data>
<data name="DonateNotPurchasedMessage" xml:space="preserve">
<value>L'achat a échoué parce que nous n'avons pas pu valider un achat précédent.</value>
</data>
<data name="DonateNotPurchasedTitle" xml:space="preserve">
<value>Achat</value>
</data>
<data name="DonatePurchasePendingMessage" xml:space="preserve">
<value>Un achat est en cours donc nous ne pouvons le valider.</value>
</data>
<data name="DonatePurchasePendingTitle" xml:space="preserve">
<value>Achat</value>
</data>
<data name="DonatePurchaseRevertedMessage" xml:space="preserve">
<value>Votre achat a été annulé.</value>
</data>
<data name="DonatePurchaseRevertedTitle" xml:space="preserve">
<value>Achat</value>
</data>
<data name="DonateServerErrorMessage" xml:space="preserve">
<value>Impossible de contacter le Windows Store, l'achat n'a pas été réalisé.</value>
</data>
<data name="DonateServerErrorTitle" xml:space="preserve">
<value>Erreur</value>
</data>
<data name="DonateSucceededMessage" xml:space="preserve">
<value>Votre don a été enregistré.</value>
</data>
<data name="DonateSucceededTitle" xml:space="preserve">
<value>Merci!</value>
</data>
<data name="EntityDeleteActionButton" xml:space="preserve">
<value>Supprimer</value>
</data>
@@ -193,7 +145,7 @@
<value>Attention</value>
</data>
<data name="EntityDeleting" xml:space="preserve">
<value>Suprression</value>
<value>Suppression</value>
</data>
<data name="EntityRestoredTitle" xml:space="preserve">
<value>Restauré</value>
@@ -204,10 +156,6 @@
<data name="EntryDeletingConfirmation" xml:space="preserve">
<value>Êtes-vous sûr de vouloir supprimer cette entrée ?</value>
</data>
<data name="EntryNew" xml:space="preserve">
<value>&lt; Nouvelle entrée &gt;</value>
<comment>Unused</comment>
</data>
<data name="EntryRecycled" xml:space="preserve">
<value>Entrée placée dans la Corbeille</value>
</data>
@@ -218,13 +166,10 @@
<value>Entrée replacée dans son groupe d'origine</value>
</data>
<data name="GroupDeleted" xml:space="preserve">
<value>Groupe supprimé défnitivement</value>
<value>Groupe supprimé définitivement</value>
</data>
<data name="GroupDeletingConfirmation" xml:space="preserve">
<value>Êtes-vous sûr de vouloir supprimer ce group et toutes ses entrées ?</value>
</data>
<data name="GroupNew" xml:space="preserve">
<value>&lt; Nouveau groupe &gt;</value>
<value>Êtes-vous sûr de vouloir supprimer ce groupe et toutes ses entrées ?</value>
</data>
<data name="GroupRecycled" xml:space="preserve">
<value>Groupe placé dans la Corbeille</value>
@@ -271,4 +216,46 @@
<data name="SettingsMenuItemSecurity" xml:space="preserve">
<value>Sécurité</value>
</data>
<data name="CompositeKeyErrorUserAccount" xml:space="preserve">
<value>- compte utilisateur</value>
</data>
<data name="SettingsMenuItemSave" xml:space="preserve">
<value>Sauvegardes</value>
</data>
<data name="RecycleBinTitle" xml:space="preserve">
<value>Corbeille</value>
</data>
<data name="EntryCurrent" xml:space="preserve">
<value>Courante</value>
</data>
<data name="MessageDialogDBOpenButtonDiscard" xml:space="preserve">
<value>Abandonner</value>
</data>
<data name="MessageDialogDBOpenButtonSave" xml:space="preserve">
<value>Sauvegarder</value>
</data>
<data name="MessageDialogDBOpenDesc" xml:space="preserve">
<value>La base de données {0} est actuellement ouverte. Que souhaitez-vous faire ?</value>
</data>
<data name="MessageDialogDBOpenTitle" xml:space="preserve">
<value>Base de données ouverte</value>
</data>
<data name="MessageDialogSaveErrorButtonDiscard" xml:space="preserve">
<value>Abandonner</value>
</data>
<data name="MessageDialogSaveErrorButtonSaveAs" xml:space="preserve">
<value>Sauvegarder sous</value>
</data>
<data name="MessageDialogSaveErrorFileTypeDesc" xml:space="preserve">
<value>Base de données KeePass 2.x</value>
</data>
<data name="MessageDialogSaveErrorTitle" xml:space="preserve">
<value>Erreur de sauvegarde</value>
</data>
<data name="ToastSavedMessage" xml:space="preserve">
<value>Base de données sauvegardée avec succès !</value>
</data>
<data name="NewImportFormatHelpCSV" xml:space="preserve">
<value>Le fichier CSV doit être formatté de la façon suivante: Nom du compte;Login;Mot de passe;URL;Commentaires</value>
</data>
</root>

View File

@@ -142,7 +142,7 @@
<value>Accueil</value>
</data>
<data name="AppBarRestore.Label" xml:space="preserve">
<value>Restorer</value>
<value>Restaurer</value>
</data>
<data name="AppBarSave.Label" xml:space="preserve">
<value>Sauvegarder</value>
@@ -171,6 +171,9 @@
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
<value>Mot de passe</value>
</data>
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
<value>Compte Utilisateur Windows</value>
</data>
<data name="DonateButton.Content" xml:space="preserve">
<value>Donner</value>
</data>
@@ -183,6 +186,15 @@
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
<value>Le mot de passe a expiré</value>
</data>
<data name="EntryItemCopyLogin.Text" xml:space="preserve">
<value>Copier le login</value>
</data>
<data name="EntryItemCopyPassword.Text" xml:space="preserve">
<value>Copier le mot de passe</value>
</data>
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
<value>Naviguer vers l'URL</value>
</data>
<data name="EntryLogin.Text" xml:space="preserve">
<value>Nom d'utilisateur ou login</value>
</data>
@@ -198,15 +210,6 @@
<data name="GroupCreateEntry.Text" xml:space="preserve">
<value>Créer une nouvelle entrée</value>
</data>
<data name="GroupFilter.PlaceholderText" xml:space="preserve">
<value>Filtrer...</value>
</data>
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
<value>&lt; Nouveau groupe &gt;</value>
</data>
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
<value>&lt; Nouveau groupe &gt;</value>
</data>
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
<value>Rechercher...</value>
</data>
@@ -270,6 +273,9 @@
<data name="RecentClear.Text" xml:space="preserve">
<value>Supprimer tout</value>
</data>
<data name="ReorderEntriesLabel.Text" xml:space="preserve">
<value>Glissez-déposez les entrées pour les réorganiser</value>
</data>
<data name="SaveAsButton.Content" xml:space="preserve">
<value>Sauvegarder sous...</value>
</data>
@@ -300,6 +306,12 @@
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
<value>Activé</value>
</data>
<data name="SettingsDatabaseRecycleBinCreate.Content" xml:space="preserve">
<value>Créer un nouveau groupe</value>
</data>
<data name="SettingsDatabaseRecycleBinExisting.Content" xml:space="preserve">
<value>Utiliser un groupe existant</value>
</data>
<data name="SettingsNewDatabaseDesc.Text" xml:space="preserve">
<value>Ici, vous pouvez changer certains options lors de la création d'une nouvelle base de données</value>
</data>
@@ -318,6 +330,18 @@
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
<value>Oui</value>
</data>
<data name="SettingsSaveDatabaseSuspend.OffContent" xml:space="preserve">
<value>Ne pas sauvegarder</value>
</data>
<data name="SettingsSaveDatabaseSuspend.OnContent" xml:space="preserve">
<value>Sauvegarder</value>
</data>
<data name="SettingsSaveDatabaseSuspendDesc.Text" xml:space="preserve">
<value>Ce paramètre est généralement recommandé. Si vous l'activez, la base de données sera sauvegardée automatiquement lors de la suspension et de la fermeture. Cependant, si votre base de données est très volumineuse, il se peut que Windows estime que cela prend trop de temps et tue l'application.</value>
</data>
<data name="SettingsSaveDatabaseSuspendTitle.Text" xml:space="preserve">
<value>Sauvegarder automatiquement lors de la suspension ?</value>
</data>
<data name="SettingsSecurityDesc1.Text" xml:space="preserve">
<value>Ici, vous pouvez changer le mot de passe maître, le fichier de clé, ou les deux. Cliquez simplement sur</value>
</data>
@@ -351,4 +375,124 @@
<data name="WelcomeOpen.Text" xml:space="preserve">
<value>Pour ouvrir une base de données existante, c'est ici.</value>
</data>
<data name="GroupsLeftListView.ButtonLabel" xml:space="preserve">
<value>Nouveau groupe</value>
</data>
<data name="GroupsLeftListView.HeaderLabel" xml:space="preserve">
<value>Groupes</value>
</data>
<data name="HistoryLeftListView.HeaderLabel" xml:space="preserve">
<value>Historique</value>
</data>
<data name="ToastCopyLogin.Message" xml:space="preserve">
<value>Login copié dans le presse-papiers</value>
</data>
<data name="ToastCopyPassword.Message" xml:space="preserve">
<value>Mot de passe copié dans le presse-papiers</value>
</data>
<data name="ToastCopyUrl.Message" xml:space="preserve">
<value>URL copié dans le presse-papiers</value>
</data>
<data name="EntryBackgroundColor.Text" xml:space="preserve">
<value>Couleur d'arrière plan</value>
</data>
<data name="EntryForegroundColor.Text" xml:space="preserve">
<value>Couleur du texte</value>
</data>
<data name="EntrySymbol.Text" xml:space="preserve">
<value>Icône</value>
</data>
<data name="AddEntryTooltip.Content" xml:space="preserve">
<value>Créer une nouvelle entrée</value>
</data>
<data name="HamburgerMenuHomeLabel.Text" xml:space="preserve">
<value>Accueil</value>
</data>
<data name="HamburgerMenuHomeTooltip.Content" xml:space="preserve">
<value>Accueil</value>
</data>
<data name="HamburgerMenuSettingsLabel.Text" xml:space="preserve">
<value>Paramètres</value>
</data>
<data name="HamburgerMenuSettingsTooltip.Content" xml:space="preserve">
<value>Paramètres</value>
</data>
<data name="TopMenuDeleteButton.Content" xml:space="preserve">
<value>Supprimer</value>
</data>
<data name="TopMenuDeleteFlyout.Text" xml:space="preserve">
<value>Supprimer</value>
</data>
<data name="TopMenuEditButton.Content" xml:space="preserve">
<value>Editer</value>
</data>
<data name="TopMenuEditFlyout.Text" xml:space="preserve">
<value>Editer</value>
</data>
<data name="TopMenuMoreButton.Content" xml:space="preserve">
<value>Plus</value>
</data>
<data name="TopMenuRestoreButton.Content" xml:space="preserve">
<value>Restaurer</value>
</data>
<data name="TopMenuRestoreFlyout.Text" xml:space="preserve">
<value>Restaurer</value>
</data>
<data name="TopMenuSaveButton.Content" xml:space="preserve">
<value>Sauvegarder</value>
</data>
<data name="TopMenuSaveFlyout.Text" xml:space="preserve">
<value>Sauvegarder</value>
</data>
<data name="TopMenuSortButton.Content" xml:space="preserve">
<value>Trier</value>
</data>
<data name="TopMenuSortEntriesFlyout.Text" xml:space="preserve">
<value>Trier les entrées</value>
</data>
<data name="TopMenuSortGroupsFlyout.Text" xml:space="preserve">
<value>Trier les groupes</value>
</data>
<data name="ToastUpdateDatabase.Message" xml:space="preserve">
<value>Base de données mise à jour</value>
</data>
<data name="ToastUpdateDatabase.Title" xml:space="preserve">
<value>Clé maître</value>
</data>
<data name="EntryTitle.PlaceholderText" xml:space="preserve">
<value>Nom de la nouvelle entrée...</value>
</data>
<data name="SearchButtonLabel.Text" xml:space="preserve">
<value>Recherche</value>
</data>
<data name="SearchButtonTooltip.Content" xml:space="preserve">
<value>Rechercher</value>
</data>
<data name="LoginTextBox.ButtonTooltip" xml:space="preserve">
<value>Copier le login</value>
</data>
<data name="PasswordTextBox.ButtonTooltip" xml:space="preserve">
<value>Copier le mot de passe</value>
</data>
<data name="UrlTextBox.ButtonTooltip" xml:space="preserve">
<value>Naviguer vers l'URL</value>
</data>
<data name="RestoreEntryCommand.Message" xml:space="preserve">
<value>Entrée replacée à son emplacement d'origine</value>
</data>
<data name="RestoreGroupCommand.Message" xml:space="preserve">
<value>Groupe replacée à son emplacement d'origine</value>
</data>
<data name="NewImportCheckbox.Content" xml:space="preserve">
<value>Importer des données existantes</value>
</data>
<data name="NewImportFile.Content" xml:space="preserve">
<value>Sélectionnez un fichier à importer...</value>
</data>
<data name="NewImportFormat.Text" xml:space="preserve">
<value>Format</value>
</data>
<data name="NewImportFormatHelp.Text" xml:space="preserve">
<value>Le fichier CSV doit être formatté de la façon suivante: Nom du compte;Login;Mot de passe:URL;Commentaires</value>
</data>
</root>

View File

@@ -1,9 +0,0 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBlock" x:Name="TextBlockSettingsHeaderStyle" >
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="14.667" />
<Setter Property="FontWeight" Value="SemiLight" />
</Style>
</ResourceDictionary>

View File

@@ -11,7 +11,7 @@ namespace ModernKeePass.TemplateSelectors
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
var returnTemplate = itemsControl.IndexFromContainer(container) == 0 ? FirstItem : OtherItem;
var returnTemplate = itemsControl?.IndexFromContainer(container) == 0 ? FirstItem : OtherItem;
return returnTemplate;
}
}

View File

@@ -0,0 +1,18 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Interfaces;
namespace ModernKeePass.TemplateSelectors
{
public class SelectableDataTemplateSelector: DataTemplateSelector
{
public DataTemplate TrueItem { get; set; }
public DataTemplate FalseItem { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var isSelectableItem = item as ISelectableModel;
return isSelectableItem != null && isSelectableItem.IsSelected ? TrueItem : FalseItem;
}
}
}

View File

@@ -2,7 +2,6 @@
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
@@ -22,7 +21,7 @@ namespace ModernKeePass.ViewModels
Success = 5
}
public IDatabase Database { get; set; }
public IDatabaseService Database { get; set; }
public bool HasPassword
{
@@ -44,7 +43,17 @@ namespace ModernKeePass.ViewModels
}
}
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null);
public bool HasUserAccount
{
get { return _hasUserAccount; }
set
{
SetProperty(ref _hasUserAccount, value);
OnPropertyChanged("IsValid");
}
}
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null || HasUserAccount);
public string Status
{
@@ -93,54 +102,51 @@ namespace ModernKeePass.ViewModels
private bool _hasPassword;
private bool _hasKeyFile;
private bool _hasUserAccount;
private bool _isOpening;
private string _password = string.Empty;
private string _status;
private StatusTypes _statusType;
private StorageFile _keyFile;
private string _keyFileText;
private readonly IResource _resource;
private readonly IResourceService _resource;
public CompositeKeyVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
public CompositeKeyVm() : this(DatabaseService.Instance, new ResourcesService()) { }
public CompositeKeyVm(IDatabase database, IResource resource)
public CompositeKeyVm(IDatabaseService database, IResourceService resource)
{
_resource = resource;
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
Database = database;
}
public async Task<bool> OpenDatabase(bool createNew)
public async Task<bool> OpenDatabase(StorageFile databaseFile, bool createNew)
{
var error = string.Empty;
try
{
_isOpening = true;
Database.Open(CreateCompositeKey(), createNew);
OnPropertyChanged("IsValid");
Database.Open(databaseFile, CreateCompositeKey(), createNew);
await Task.Run(() => RootGroup = Database.RootGroup);
return true;
}
catch (ArgumentException)
{
var errorMessage = new StringBuilder($"{_resource.GetResourceValue("CompositeKeyErrorOpen")}\n");
if (HasPassword) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
if (HasKeyFile) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
if (HasUserAccount) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserAccount"));
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
}
catch (Exception e)
{
error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}: {e.Message}";
var error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}{e.Message}";
UpdateStatus(error, StatusTypes.Error);
}
finally
{
_isOpening = false;
}
switch ((DatabaseService.DatabaseStatus)Database.Status)
{
case DatabaseService.DatabaseStatus.Opened:
await Task.Run(() => RootGroup = Database.RootGroup);
return true;
case DatabaseService.DatabaseStatus.CompositeKeyError:
var errorMessage = new StringBuilder(_resource.GetResourceValue("CompositeKeyErrorUserStart"));
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
break;
case DatabaseService.DatabaseStatus.Error:
UpdateStatus(error, StatusTypes.Error);
break;
OnPropertyChanged("IsValid");
}
return false;
}
@@ -169,6 +175,7 @@ namespace ModernKeePass.ViewModels
var compositeKey = new CompositeKey();
if (HasPassword) compositeKey.AddUserKey(new KcpPassword(Password));
if (HasKeyFile && KeyFile != null) compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromFile(KeyFile)));
if (HasUserAccount) compositeKey.AddUserKey(new KcpUserAccount());
return compositeKey;
}
}

View File

@@ -1,44 +0,0 @@
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Store;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class DonateVm: NotifyPropertyChangedBase
{
public ObservableCollection<ProductListing> Donations { get; }
public ProductListing SelectedItem
{
get { return _selectedItem; }
set { SetProperty(ref _selectedItem, value); }
}
private readonly ILicenseService _license;
private ProductListing _selectedItem;
public DonateVm() : this (new LicenseService()) { }
public DonateVm(ILicenseService license)
{
// TODO: find a nice way to order products
_license = license;
Donations = new ObservableCollection<ProductListing>(
_license.Products.Values
/*.OrderBy(p => decimal.Parse(p.FormattedPrice.Replace('\u00A0', ' '), NumberStyles.Currency,
CultureInfo.CurrentCulture.NumberFormat))*/
);
}
public async Task<int> Purchase()
{
return await _license.Purchase(SelectedItem.ProductId);
}
}
}

View File

@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Drawing;
using System.Windows.Input;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Mappings;
using ModernKeePass.Services;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.PasswordGenerator;
@@ -13,16 +13,13 @@ using ModernKeePassLib.Cryptography;
namespace ModernKeePass.ViewModels
{
public class EntryVm : INotifyPropertyChanged, IPwEntity
public class EntryVm : INotifyPropertyChanged, IPwEntity, ISelectableModel
{
public GroupVm ParentGroup { get; private set; }
public GroupVm PreviousGroup { get; private set; }
public System.Drawing.Color? BackgroundColor => _pwEntry?.BackgroundColor;
public System.Drawing.Color? ForegroundColor => _pwEntry?.ForegroundColor;
public bool IsRevealPasswordEnabled => !string.IsNullOrEmpty(Password);
public bool HasExpired => HasExpirationDate && _pwEntry.ExpiryTime < DateTime.Now;
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password.ToCharArray());
public bool IsFirstItem => _pwEntry == null;
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
public bool UpperCasePatternSelected { get; set; } = true;
public bool LowerCasePatternSelected { get; set; } = true;
public bool DigitsPatternSelected { get; set; } = true;
@@ -34,6 +31,12 @@ namespace ModernKeePass.ViewModels
public string CustomChars { get; set; } = string.Empty;
public PwUuid IdUuid => _pwEntry?.Uuid;
public string Id => _pwEntry?.Uuid.ToHexString();
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
public IEnumerable<IPwEntity> BreadCrumb => new List<IPwEntity>(ParentGroup.BreadCrumb) {ParentGroup};
/// <summary>
/// Determines if the Entry is current or from history
/// </summary>
public bool IsSelected { get; set; } = true;
public double PasswordLength
{
@@ -47,20 +50,15 @@ namespace ModernKeePass.ViewModels
public string Name
{
get
{
/*var title = GetEntryValue(PwDefs.TitleField);
return title == null ? _resource.GetResourceValue("EntryNew") : title;*/
return GetEntryValue(PwDefs.TitleField);
}
set { SetEntryValue(PwDefs.TitleField, value); }
get { return GetEntryValue(PwDefs.TitleField); }
set { SetEntryValue(PwDefs.TitleField, new ProtectedString(true, value)); }
}
public string UserName
{
get { return GetEntryValue(PwDefs.UserNameField); }
set { SetEntryValue(PwDefs.UserNameField, value); }
set { SetEntryValue(PwDefs.UserNameField, new ProtectedString(true, value)); }
}
public string Password
@@ -68,48 +66,64 @@ namespace ModernKeePass.ViewModels
get { return GetEntryValue(PwDefs.PasswordField); }
set
{
SetEntryValue(PwDefs.PasswordField, value);
SetEntryValue(PwDefs.PasswordField, new ProtectedString(true, value));
NotifyPropertyChanged("Password");
NotifyPropertyChanged("PasswordComplexityIndicator");
}
}
public string Url
{
get { return GetEntryValue(PwDefs.UrlField); }
set { SetEntryValue(PwDefs.UrlField, value); }
set { SetEntryValue(PwDefs.UrlField, new ProtectedString(true, value)); }
}
public string Notes
{
get { return GetEntryValue(PwDefs.NotesField); }
set { SetEntryValue(PwDefs.NotesField, value); }
set { SetEntryValue(PwDefs.NotesField, new ProtectedString(true, value)); }
}
public Symbol IconSymbol
public int IconId
{
get
{
if (_pwEntry == null) return Symbol.Add;
if (HasExpired) return Symbol.Priority;
var result = PwIconToSegoeMapping.GetSymbolFromIcon(_pwEntry.IconId);
return result == Symbol.More ? Symbol.Permissions : result;
if (HasExpired) return (int) PwIcon.Expired;
if (_pwEntry?.IconId != null) return (int) _pwEntry?.IconId;
return -1;
}
set
{
HandleBackup();
_pwEntry.IconId = (PwIcon)value;
}
}
public DateTimeOffset ExpiryDate
{
get { return new DateTimeOffset(_pwEntry.ExpiryTime.Date); }
set { if (HasExpirationDate) _pwEntry.ExpiryTime = value.DateTime; }
set
{
if (!HasExpirationDate) return;
HandleBackup();
_pwEntry.ExpiryTime = value.DateTime;
}
}
public TimeSpan ExpiryTime
{
get { return _pwEntry.ExpiryTime.TimeOfDay; }
set { if (HasExpirationDate) _pwEntry.ExpiryTime = _pwEntry.ExpiryTime.Date.Add(value); }
set
{
if (!HasExpirationDate) return;
HandleBackup();
_pwEntry.ExpiryTime = _pwEntry.ExpiryTime.Date.Add(value);
}
}
public bool IsEditMode
{
get { return _isEditMode; }
get { return IsSelected && _isEditMode; }
set
{
_isEditMode = value;
@@ -117,7 +131,15 @@ namespace ModernKeePass.ViewModels
}
}
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
public bool IsVisible
{
get { return _isVisible; }
set
{
_isVisible = value;
NotifyPropertyChanged("IsVisible");
}
}
public bool IsRevealPassword
{
@@ -138,23 +160,54 @@ namespace ModernKeePass.ViewModels
}
}
public string Path
public IEnumerable<IPwEntity> History
{
get
{
var path = new StringBuilder(ParentGroup.Path);
path.Append($" > {ParentGroup.Name}");
return path.ToString();
var history = new Stack<EntryVm>();
foreach (var historyEntry in _pwEntry.History)
{
history.Push(new EntryVm(historyEntry, ParentGroup) {IsSelected = false});
}
history.Push(this);
return history;
}
}
public Color? BackgroundColor
{
get { return _pwEntry?.BackgroundColor; }
set
{
if (value != null) _pwEntry.BackgroundColor = (Color) value;
}
}
public Color? ForegroundColor
{
get { return _pwEntry?.ForegroundColor; }
set
{
if (value != null) _pwEntry.ForegroundColor = (Color)value;
}
}
public ICommand SaveCommand { get; }
public ICommand GeneratePasswordCommand { get; }
public ICommand UndoDeleteCommand { get; }
public event PropertyChangedEventHandler PropertyChanged;
private readonly PwEntry _pwEntry;
private readonly IDatabase _database;
private readonly IDatabaseService _database;
private readonly IResourceService _resource;
private bool _isEditMode;
private bool _isDirty = true;
private bool _isRevealPassword;
private double _passwordLength = 25;
private bool _isVisible = true;
private void NotifyPropertyChanged(string propertyName)
{
@@ -163,13 +216,18 @@ namespace ModernKeePass.ViewModels
public EntryVm() { }
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, (Application.Current as App)?.Database) { }
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance, new ResourcesService()) { }
public EntryVm(PwEntry entry, GroupVm parent, IDatabase database)
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database, IResourceService resource)
{
_database = database;
_resource = resource;
_pwEntry = entry;
ParentGroup = parent;
SaveCommand = new RelayCommand(() => _database.Save());
GeneratePasswordCommand = new RelayCommand(GeneratePassword);
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
}
public void GeneratePassword()
@@ -195,34 +253,20 @@ namespace ModernKeePass.ViewModels
ProtectedString password;
PwGenerator.Generate(out password, pwProfile, null, new CustomPwGeneratorPool());
_pwEntry?.Strings.Set(PwDefs.PasswordField, password);
SetEntryValue(PwDefs.PasswordField, password);
NotifyPropertyChanged("Password");
NotifyPropertyChanged("IsRevealPasswordEnabled");
NotifyPropertyChanged("PasswordComplexityIndicator");
}
private string GetEntryValue(string key)
{
return _pwEntry?.Strings.GetSafe(key).ReadString();
}
private void SetEntryValue(string key, string newValue)
{
_pwEntry?.Strings.Set(key, new ProtectedString(true, newValue));
}
public void MarkForDelete()
public void MarkForDelete(string recycleBinTitle)
{
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
_database.CreateRecycleBin();
_database.CreateRecycleBin(recycleBinTitle);
Move(_database.RecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
}
public void UndoDelete()
{
Move(PreviousGroup);
}
public void Move(GroupVm destination)
{
PreviousGroup = ParentGroup;
@@ -242,14 +286,37 @@ namespace ModernKeePass.ViewModels
if (!_database.RecycleBinEnabled || PreviousGroup.IsSelected) _database.AddDeletedItem(IdUuid);
}
public void Save()
{
_database.Save();
}
public PwEntry GetPwEntry()
{
return _pwEntry;
}
public void Reset()
{
_isDirty = false;
}
public override string ToString()
{
return IsSelected ? _resource.GetResourceValue("EntryCurrent") : _pwEntry.LastModificationTime.ToString("g");
}
private void HandleBackup()
{
if (_isDirty) return;
_pwEntry?.Touch(true);
_pwEntry?.CreateBackup(null);
_isDirty = true;
}
private string GetEntryValue(string key)
{
return _pwEntry?.Strings.GetSafe(key).ReadString();
}
private void SetEntryValue(string key, ProtectedString newValue)
{
HandleBackup();
_pwEntry?.Strings.Set(key, newValue);
}
}
}

View File

@@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Threading.Tasks;
using System.Windows.Input;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Mappings;
using ModernKeePass.Services;
using ModernKeePassLib;
namespace ModernKeePass.ViewModels
@@ -20,7 +20,22 @@ namespace ModernKeePass.ViewModels
public ObservableCollection<EntryVm> Entries
{
get { return _entries; }
set { SetProperty(ref _entries, value); }
private set { SetProperty(ref _entries, value); }
}
public IEnumerable<EntryVm> SubEntries
{
get
{
var subEntries = new List<EntryVm>();
subEntries.AddRange(Entries);
foreach (var group in Groups)
{
subEntries.AddRange(group.SubEntries);
}
return subEntries;
}
}
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
@@ -29,10 +44,10 @@ namespace ModernKeePass.ViewModels
public string Id => IdUuid?.ToHexString();
public bool IsNotRoot => ParentGroup != null;
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !IsSelected && !ParentGroup.IsSelected;
/// <summary>
/// Is the Group the database Recycle Bin?
/// </summary>
@@ -46,8 +61,7 @@ namespace ModernKeePass.ViewModels
}
public IOrderedEnumerable<IGrouping<char, EntryVm>> EntriesZoomedOut => from e in Entries
where !e.IsFirstItem
group e by e.Name.FirstOrDefault() into grp
group e by e.Name.ToUpper().FirstOrDefault() into grp
orderby grp.Key
select grp;
@@ -57,21 +71,25 @@ namespace ModernKeePass.ViewModels
set { _pwGroup.Name = value; }
}
public Symbol IconSymbol
public int IconId
{
get
{
if (_pwGroup == null) return Symbol.Add;
var result = PwIconToSegoeMapping.GetSymbolFromIcon(_pwGroup.IconId);
return result == Symbol.More ? Symbol.Folder : result;
if (_pwGroup?.IconId != null) return (int) _pwGroup?.IconId;
return -1;
}
set { _pwGroup.IconId = PwIconToSegoeMapping.GetIconFromSymbol(value); }
set { _pwGroup.IconId = (PwIcon)value; }
}
public bool IsEditMode
{
get { return _isEditMode; }
set { SetProperty(ref _isEditMode, value); }
set
{
SetProperty(ref _isEditMode, value);
((RelayCommand)SortEntriesCommand).RaiseCanExecuteChanged();
((RelayCommand)SortGroupsCommand).RaiseCanExecuteChanged();
}
}
public bool IsMenuClosed
@@ -80,55 +98,57 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _isMenuClosed, value); }
}
public string Filter
{
get { return _filter; }
set
{
SetProperty(ref _filter, value);
OnPropertyChanged("EntriesFiltered");
}
}
public ObservableCollection<EntryVm> EntriesFiltered =>
new ObservableCollection<EntryVm>(Entries.Where(e => e.Name.IndexOf(Filter, StringComparison.OrdinalIgnoreCase) >= 0));
public string Path
public IEnumerable<IPwEntity> BreadCrumb
{
get
{
if (ParentGroup == null) return string.Empty;
var path = new StringBuilder(ParentGroup.Path);
path.Append($" > {ParentGroup.Name}");
return path.ToString();
var groups = new Stack<GroupVm>();
var group = this;
while (group.ParentGroup != null)
{
group = group.ParentGroup;
groups.Push(group);
}
return groups;
}
}
public ICommand SaveCommand { get; }
public ICommand SortEntriesCommand { get; }
public ICommand SortGroupsCommand { get; }
public ICommand UndoDeleteCommand { get; }
private readonly PwGroup _pwGroup;
private readonly IDatabase _database;
private readonly IDatabaseService _database;
private bool _isEditMode;
private PwEntry _reorderedEntry;
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
private string _filter = string.Empty;
private bool _isMenuClosed = true;
public GroupVm() {}
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
(Application.Current as App)?.Database, recycleBinId)
DatabaseService.Instance, recycleBinId)
{ }
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabase database, PwUuid recycleBinId = null)
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabaseService database, PwUuid recycleBinId = null)
{
_pwGroup = pwGroup;
_database = database;
ParentGroup = parent;
SaveCommand = new RelayCommand(() => _database.Save());
SortEntriesCommand = new RelayCommand(async () =>
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
SortGroupsCommand = new RelayCommand(async () =>
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
if (recycleBinId != null && _pwGroup.Uuid.Equals(recycleBinId)) _database.RecycleBin = this;
Entries = new ObservableCollection<EntryVm>(pwGroup.Entries.Select(e => new EntryVm(e, this)));
Entries.CollectionChanged += Entries_CollectionChanged;
Groups = new ObservableCollection<GroupVm>(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)));
Groups.Insert(0, new GroupVm());
}
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -165,11 +185,12 @@ namespace ModernKeePass.ViewModels
return newEntry;
}
public void MarkForDelete()
public void MarkForDelete(string recycleBinTitle)
{
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
_database.CreateRecycleBin();
_database.CreateRecycleBin(recycleBinTitle);
Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
((RelayCommand)UndoDeleteCommand).RaiseCanExecuteChanged();
}
public void UndoDelete()
@@ -199,12 +220,12 @@ namespace ModernKeePass.ViewModels
else _database.AddDeletedItem(IdUuid);
}
public void Save()
public override string ToString()
{
_database.Save();
return Name;
}
public void SortEntries()
private async Task SortEntriesAsync()
{
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
try
@@ -214,11 +235,11 @@ namespace ModernKeePass.ViewModels
}
catch (Exception e)
{
MessageDialogHelper.ShowErrorDialog(e);
await MessageDialogHelper.ShowErrorDialog(e);
}
}
public void SortGroups()
private async Task SortGroupsAsync()
{
try
{
@@ -228,13 +249,9 @@ namespace ModernKeePass.ViewModels
}
catch (Exception e)
{
MessageDialogHelper.ShowErrorDialog(e);
await MessageDialogHelper.ShowErrorDialog(e);
}
}
public override string ToString()
{
return Name;
}
}
}

View File

@@ -1,6 +1,6 @@
using Windows.Storage;
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Common;
using Windows.UI.Xaml;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
@@ -29,22 +29,12 @@ namespace ModernKeePass.ViewModels
DatabaseFile = file as StorageFile;
}
public void OpenDatabaseFile()
{
OpenDatabaseFile((Application.Current as App)?.Database);
}
public void OpenDatabaseFile(IDatabase database)
{
database.DatabaseFile = DatabaseFile;
}
public void UpdateAccessTime()
{
UpdateAccessTime(new RecentService());
UpdateAccessTime(RecentService.Instance).Wait();
}
public async void UpdateAccessTime(IRecent recent)
public async Task UpdateAccessTime(IRecentService recent)
{
await recent.GetFileAsync(Token);
}

View File

@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.Cipher;
using ModernKeePassLib.Cryptography.KeyDerivation;
@@ -14,7 +14,7 @@ namespace ModernKeePass.ViewModels
// TODO: implement Kdf settings
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
{
private readonly IDatabase _database;
private readonly IDatabaseService _database;
private GroupVm _selectedItem;
public bool HasRecycleBin
@@ -27,6 +27,15 @@ namespace ModernKeePass.ViewModels
}
}
public bool IsNewRecycleBin
{
get { return _database.RecycleBin == null; }
set
{
if (value) _database.RecycleBin = null;
}
}
public ObservableCollection<GroupVm> Groups { get; set; }
public IEnumerable<string> Ciphers
@@ -73,7 +82,7 @@ namespace ModernKeePass.ViewModels
get { return Groups.FirstOrDefault(g => g.IsSelected); }
set
{
if (_selectedItem == value) return;
if (_selectedItem == value || IsNewRecycleBin) return;
if (_selectedItem != null)
{
_selectedItem.IsSelected = false;
@@ -88,9 +97,9 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsDatabaseVm() : this((Application.Current as App)?.Database) { }
public SettingsDatabaseVm() : this(DatabaseService.Instance) { }
public SettingsDatabaseVm(IDatabase database)
public SettingsDatabaseVm(IDatabaseService database)
{
_database = database;
Groups = _database?.RootGroup.Groups;

View File

@@ -6,12 +6,12 @@ namespace ModernKeePass.ViewModels
{
public class SettingsNewVm
{
private ISettings _settings;
private readonly ISettingsService _settings;
public SettingsNewVm() : this(new SettingsService())
public SettingsNewVm() : this(SettingsService.Instance)
{ }
public SettingsNewVm(ISettings settings)
public SettingsNewVm(ISettingsService settings)
{
_settings = settings;
}

View File

@@ -0,0 +1,24 @@
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class SettingsSaveVm
{
private readonly ISettingsService _settings;
public SettingsSaveVm() : this(SettingsService.Instance)
{ }
public SettingsSaveVm(ISettingsService settings)
{
_settings = settings;
}
public bool IsSaveSuspend
{
get { return _settings.GetSetting("SaveSuspend", true); }
set { _settings.PutSetting("SaveSuspend", value); }
}
}
}

View File

@@ -1,7 +1,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.ApplicationModel;
using Windows.UI.Xaml;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
@@ -45,13 +45,13 @@ namespace ModernKeePass.ViewModels
public MainVm() {}
internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame,
(Application.Current as App)?.Database, new ResourcesService(), new RecentService())
internal MainVm(Frame referenceFrame, Frame destinationFrame, StorageFile databaseFile = null) : this(referenceFrame, destinationFrame,
DatabaseService.Instance, new ResourcesService(), RecentService.Instance, databaseFile)
{ }
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabase database, IResource resource, IRecent recent)
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabaseService database, IResourceService resource, IRecentService recent, StorageFile databaseFile = null)
{
var isDatabaseOpen = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opened;
var isDatabaseOpen = database != null && database.IsOpen;
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
{
@@ -60,9 +60,9 @@ namespace ModernKeePass.ViewModels
Title = resource.GetResourceValue("MainMenuItemOpen"),
PageType = typeof(OpenDatabasePage),
Destination = destinationFrame,
Parameter = referenceFrame,
Parameter = databaseFile,
SymbolIcon = Symbol.Page2,
IsSelected = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opening
IsSelected = databaseFile != null && !database.IsOpen
},
new MainMenuItemVm
{
@@ -90,7 +90,7 @@ namespace ModernKeePass.ViewModels
Parameter = referenceFrame,
SymbolIcon = Symbol.Copy,
IsSelected =
(database == null || database.Status == (int) DatabaseService.DatabaseStatus.Closed) &&
(database == null || !database.IsOpen) &&
recent.EntryCount > 0,
IsEnabled = recent.EntryCount > 0
},
@@ -120,7 +120,7 @@ namespace ModernKeePass.ViewModels
SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected);
// Add currently opened database to the menu
if (database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opened)
if (database != null && database.IsOpen)
mainMenuItems.Add(new MainMenuItemVm
{
Title = database.Name,

View File

@@ -1,7 +1,66 @@
namespace ModernKeePass.ViewModels
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Converters;
using ModernKeePass.ImportFormats;
using ModernKeePass.Interfaces;
using ModernKeePassLib;
namespace ModernKeePass.ViewModels
{
public class NewVm : OpenVm
{
private string _importFormatHelp;
public string Password { get; set; }
public bool IsImportChecked { get; set; }
public IStorageFile ImportFile { get; set; }
public string ImportFileExtensionFilter { get; set; } = "*";
public IFormat ImportFormat { get; set; }
public string ImportFormatHelp
{
get { return _importFormatHelp; }
set
{
_importFormatHelp = value;
OnPropertyChanged(nameof(ImportFormatHelp));
}
}
public void PopulateInitialData(IDatabaseService database, ISettingsService settings, IImportService<IFormat> importService)
{
if (settings.GetSetting<bool>("Sample") && !IsImportChecked) CreateSampleData(database.RootGroup);
else if (IsImportChecked && ImportFile != null && ! (ImportFormat is NullImportFormat)) importService.Import(ImportFormat, ImportFile, database.RootGroup);
}
private void CreateSampleData(GroupVm group)
{
var converter = new IntToSymbolConverter();
var bankingGroup = group.AddNewGroup("Banking");
bankingGroup.IconId = (int)converter.ConvertBack(Symbol.Calculator, null, null, string.Empty);
var emailGroup = group.AddNewGroup("Email");
emailGroup.IconId = (int)converter.ConvertBack(Symbol.Mail, null, null, string.Empty);
var internetGroup = group.AddNewGroup("Internet");
internetGroup.IconId = (int)converter.ConvertBack(Symbol.World, null, null, string.Empty);
var sample1 = group.AddNewEntry();
sample1.Name = "Sample Entry";
sample1.UserName = "Username";
sample1.Url = PwDefs.HomepageUrl;
sample1.Password = "Password";
sample1.Notes = "You may safely delete this sample";
var sample2 = group.AddNewEntry();
sample2.Name = "Sample Entry #2";
sample2.UserName = "Michael321";
sample2.Url = PwDefs.HelpUrl + "kb/testform.html";
sample2.Password = "12345";
}
}
}

View File

@@ -1,5 +1,4 @@
using Windows.Storage;
using Windows.UI.Xaml;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
@@ -8,35 +7,27 @@ namespace ModernKeePass.ViewModels
{
public class OpenVm: NotifyPropertyChangedBase
{
public bool ShowPasswordBox => _database?.Status == (int) DatabaseService.DatabaseStatus.Opening;
public bool IsFileSelected => DatabaseFile != null;
public string Name => _database?.Name;
public string Name => DatabaseFile?.DisplayName;
private readonly IDatabase _database;
public StorageFile DatabaseFile { get; private set; }
public OpenVm() : this((Application.Current as App)?.Database) { }
public OpenVm(IDatabase database)
internal void OpenFile(StorageFile file)
{
_database = database;
if (database == null || database.Status != (int) DatabaseService.DatabaseStatus.Opening) return;
OpenFile(database.DatabaseFile);
OpenFile(file, RecentService.Instance);
}
public void OpenFile(StorageFile file)
public void OpenFile(StorageFile file, IRecentService recent)
{
OpenFile(file, new RecentService());
}
public void OpenFile(StorageFile file, IRecent recent)
{
_database.DatabaseFile = file;
DatabaseFile = file;
OnPropertyChanged("Name");
OnPropertyChanged("ShowPasswordBox");
OnPropertyChanged("IsFileSelected");
OnPropertyChanged("DatabaseFile");
AddToRecentList(file, recent);
}
private void AddToRecentList(StorageFile file, IRecent recent)
private void AddToRecentList(StorageFile file, IRecentService recent)
{
recent.Add(file, file.DisplayName);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
@@ -7,7 +8,7 @@ namespace ModernKeePass.ViewModels
{
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
{
private readonly IRecent _recent;
private readonly IRecentService _recent;
private ISelectableModel _selectedItem;
private ObservableCollection<IRecentItem> _recentItems = new ObservableCollection<IRecentItem>();
@@ -35,18 +36,22 @@ namespace ModernKeePass.ViewModels
}
}
public RecentVm() : this (new RecentService())
public ICommand ClearAllCommand { get; }
public RecentVm() : this (RecentService.Instance)
{ }
public RecentVm(IRecent recent)
public RecentVm(IRecentService recent)
{
_recent = recent;
ClearAllCommand = new RelayCommand(ClearAll);
RecentItems = _recent.GetAllFiles();
if (RecentItems.Count > 0)
SelectedItem = RecentItems[0] as RecentItemVm;
}
public void ClearAll()
private void ClearAll()
{
_recent.ClearAll();
RecentItems.Clear();

View File

@@ -1,15 +1,15 @@
using Windows.Storage;
using Windows.UI.Xaml;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
namespace ModernKeePass.ViewModels
{
public class SaveVm
{
private readonly IDatabase _database;
public SaveVm() : this((Application.Current as App)?.Database) { }
private readonly IDatabaseService _database;
public SaveVm() : this(DatabaseService.Instance) { }
public SaveVm(IDatabase database)
public SaveVm(IDatabaseService database)
{
_database = database;
}

View File

@@ -1,6 +1,5 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
@@ -41,9 +40,9 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
public SettingsVm() : this(DatabaseService.Instance, new ResourcesService()) { }
public SettingsVm(IDatabase database, IResource resource)
public SettingsVm(IDatabaseService database, IResourceService resource)
{
var menuItems = new ObservableCollection<ListMenuItemVm>
{
@@ -56,12 +55,19 @@ namespace ModernKeePass.ViewModels
IsSelected = true
},
new ListMenuItemVm
{
Title = resource.GetResourceValue("SettingsMenuItemSave"),
Group = resource.GetResourceValue("SettingsMenuGroupApplication"),
SymbolIcon = Symbol.Save,
PageType = typeof(SettingsSavePage)
},
new ListMenuItemVm
{
Title = resource.GetResourceValue("SettingsMenuItemGeneral"),
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
SymbolIcon = Symbol.Setting,
PageType = typeof(SettingsDatabasePage),
IsEnabled = database?.Status == 2
IsEnabled = database.IsOpen
},
new ListMenuItemVm
{
@@ -69,7 +75,7 @@ namespace ModernKeePass.ViewModels
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
SymbolIcon = Symbol.Permissions,
PageType = typeof(SettingsSecurityPage),
IsEnabled = database?.Status == 2
IsEnabled = database.IsOpen
}
};
SelectedItem = menuItems.FirstOrDefault(m => m.IsSelected);

View File

@@ -16,7 +16,7 @@ namespace ModernKeePass.Views.BasePages
/// </summary>
public NavigationHelper NavigationHelper { get; }
public virtual ListView ListView { get; set; }
public ListView ListView { get; set; }
public virtual CollectionViewSource ListViewSource { get; set; }
public virtual IHasSelectableObject Model { get; set; }
@@ -29,7 +29,7 @@ namespace ModernKeePass.Views.BasePages
// Setup the logical page navigation components that allow
// the page to only show one pane at a time.
NavigationHelper.GoBackCommand = new RelayCommand(() => GoBack(), () => CanGoBack());
NavigationHelper.GoBackCommand = new RelayCommand(GoBack, CanGoBack);
// Start listening for Window size changes
// to change from showing two panes to showing a single pane
@@ -62,9 +62,6 @@ namespace ModernKeePass.Views.BasePages
/// session. The state will be null the first time a page is visited.</param>
protected void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
// TODO: Assign a bindable group to Me.DefaultViewModel("Group")
// TODO: Assign a collection of bindable items to Me.DefaultViewModel("Items")
if (e.PageState == null)
{
// When this is a new page, select the first item automatically unless logical page

View File

@@ -9,6 +9,7 @@
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:actions="using:ModernKeePass.Actions"
xmlns:userControls="using:ModernKeePass.Views.UserControls"
x:Name="PageRoot"
x:Class="ModernKeePass.Views.EntryDetailPage"
mc:Ignorable="d"
@@ -18,13 +19,14 @@
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter" />
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushComplexityConverter" />
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter" />
<converters:IntToSymbolConverter x:Key="IntToSymbolConverter" />
<Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle">
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
<Setter Property="Foreground" Value="{ThemeResource TextBoxForegroundThemeBrush}" />
<Setter Property="Background" Value="{ThemeResource TextBoxBackgroundThemeBrush}" />
<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextSelectionHighlightColorThemeBrush}" />
<Setter Property="SelectionHighlightColor" Value="{StaticResource MainColor}" />
<Setter Property="BorderBrush" Value="{ThemeResource TextBoxBorderThemeBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
@@ -115,7 +117,7 @@
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPressedBackgroundThemeBrush}" />
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MainColor}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement"
Storyboard.TargetProperty="BorderBrush">
@@ -272,16 +274,17 @@
Grid.Row="1"
Background="{TemplateBinding Background}"
Margin="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="3"
Grid.RowSpan="1"/>
Grid.ColumnSpan="3"/>
<Border x:Name="BorderElement"
Grid.Row="1"
Grid.Column="0"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="3"
Grid.RowSpan="1"/>
<ContentPresenter x:Name="HeaderContentPresenter"
Grid.ColumnSpan="3"/>
<ContentPresenter
x:Name="HeaderContentPresenter"
Grid.Row="0"
Grid.Column="0"
Foreground="{ThemeResource TextBoxForegroundHeaderThemeBrush}"
Margin="0,4,0,4"
Grid.ColumnSpan="3"
@@ -290,6 +293,7 @@
FontWeight="Semilight" />
<ScrollViewer x:Name="ContentElement"
Grid.Row="1"
Grid.Column="0"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
@@ -301,8 +305,10 @@
IsTabStop="False"
ZoomMode="Disabled"
AutomationProperties.AccessibilityView="Raw"/>
<ContentControl x:Name="PlaceholderTextContentPresenter"
<ContentControl
x:Name="PlaceholderTextContentPresenter"
Grid.Row="1"
Grid.Column="0"
Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"
Margin="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
@@ -341,7 +347,7 @@
<Run x:Uid="PasswordGeneratorLength" />
<Run Text="{Binding PasswordLength}" />
</TextBlock>
<Slider Value="{Binding PasswordLength, Mode=TwoWay}" Margin="0,-10,0,-20" />
<Slider Value="{Binding PasswordLength, Mode=TwoWay}" Margin="0,-10,0,-20" Style="{StaticResource MainColorSlider}"/>
<CheckBox IsChecked="{Binding UpperCasePatternSelected, Mode=TwoWay}" x:Uid="PasswordGeneratorUpper" />
<CheckBox IsChecked="{Binding LowerCasePatternSelected, Mode=TwoWay}" x:Uid="PasswordGeneratorLower" />
<CheckBox IsChecked="{Binding DigitsPatternSelected, Mode=TwoWay}" x:Uid="PasswordGeneratorDigits" />
@@ -352,13 +358,7 @@
<CheckBox IsChecked="{Binding BracketsPatternSelected, Mode=TwoWay}" x:Uid="PasswordGeneratorBrackets" />
<TextBlock x:Uid="PasswordGeneratorAlso" Margin="0,5,0,0"/>
<TextBox Text="{Binding CustomChars, Mode=TwoWay}" />
<Button x:Uid="PasswordGeneratorButton">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction TargetObject="{Binding}" MethodName="GeneratePassword"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Button>
<Button x:Uid="PasswordGeneratorButton" Command="{Binding GeneratePasswordCommand}" />
</StackPanel>
</Flyout>
</Button.Flyout>
@@ -375,49 +375,6 @@
<Page.DataContext>
<viewModels:EntryVm />
</Page.DataContext>
<Page.BottomAppBar>
<CommandBar x:Name="CommandBar" VerticalAlignment="Center">
<CommandBar.SecondaryCommands>
<AppBarButton Icon="Home" x:Uid="AppBarHome">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.MainPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
<AppBarButton Icon="Save" x:Uid="AppBarSave">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction TargetObject="{Binding}" MethodName="Save"/>
<core:ChangePropertyAction TargetObject="{Binding ElementName=CommandBar}" PropertyName="IsOpen" Value="False" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
<AppBarButton Icon="Setting" x:Uid="AppBarSettings">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.SettingsPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
</CommandBar.SecondaryCommands>
<AppBarToggleButton Icon="Edit" x:Uid="AppBarEdit" IsChecked="{Binding IsEditMode, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:ChangePropertyAction TargetObject="{Binding ElementName=CommandBar}" PropertyName="IsOpen" Value="False" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarToggleButton>
<AppBarButton Icon="Undo" x:Uid="AppBarRestore" Visibility="{Binding ParentGroup.IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding PreviousGroup, Converter={StaticResource NullToBooleanConverter}}" Click="RestoreButton_Click">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction MethodName="UndoDelete" TargetObject="{Binding}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
<AppBarButton Icon="Delete" x:Uid="AppBarDelete" Click="DeleteButton_Click" />
</CommandBar>
</Page.BottomAppBar>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ChildrenTransitions>
<TransitionCollection>
@@ -425,43 +382,66 @@
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="{StaticResource MenuGridLength}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Margin="20,0,0,0" >
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource MenuGridLength}" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<userControls:HamburgerMenuUserControl x:Uid="HistoryLeftListView" ItemsSource="{Binding History}" ResizeTarget="{Binding ElementName=LeftListViewColumn}" SelectionChanged="HamburgerMenuUserControl_OnSelectionChanged" />
<Grid x:Name="StackPanel" Grid.Column="1">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="20,0,0,20">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0,20,0,0"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="0,20,0,0"/>
<Setter Property="FontSize" Value="18"/>
</Style>
<Style BasedOn="{StaticResource TextBoxWithButtonStyle}" TargetType="local:TextBoxWithButton" x:Key="EntryTextBoxWithButtonStyle">
<Setter Property="Width" Value="350"/>
<Setter Property="Height" Value="32"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</StackPanel.Resources>
<TextBlock x:Uid="EntryLogin" TextWrapping="Wrap" FontSize="18"/>
<local:TextBoxWithButton HorizontalAlignment="Left" Text="{Binding UserName, Mode=TwoWay}" Width="350" Height="32" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;" ButtonTooltip="Copy">
<TextBlock x:Uid="EntryLogin" />
<local:TextBoxWithButton x:Uid="LoginTextBox" Text="{Binding UserName, Mode=TwoWay}" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;" IsEnabled="{Binding IsSelected}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick">
<actions:ClipboardAction Text="{Binding UserName}" />
<actions:ToastAction x:Uid="ToastCopyLogin" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</local:TextBoxWithButton>
<TextBlock x:Uid="EntryPassword" TextWrapping="Wrap" FontSize="18"/>
<PasswordBox HorizontalAlignment="Left" Password="{Binding Password, Mode=TwoWay}" Width="350" Height="32" IsPasswordRevealButtonEnabled="True" Visibility="{Binding IsRevealPassword, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Style="{StaticResource PasswordBoxWithButtonStyle}" />
<local:TextBoxWithButton HorizontalAlignment="Left" Text="{Binding Password, Mode=TwoWay}" Width="350" Height="32" Visibility="{Binding IsRevealPassword, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;" ButtonTooltip="Copy">
<TextBlock x:Uid="EntryPassword" />
<PasswordBox HorizontalAlignment="Left" Password="{Binding Password, Mode=TwoWay}" Width="350" Height="32" IsPasswordRevealButtonEnabled="True" Visibility="{Binding IsRevealPassword, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Style="{StaticResource PasswordBoxWithButtonStyle}" IsEnabled="{Binding IsSelected}" />
<local:TextBoxWithButton x:Uid="PasswordTextBox" Text="{Binding Password, Mode=TwoWay}" Visibility="{Binding IsRevealPassword, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;" IsEnabled="{Binding IsSelected}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick">
<actions:ClipboardAction Text="{Binding Password}" />
<actions:ToastAction x:Uid="ToastCopyPassword" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</local:TextBoxWithButton>
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushComplexityConverter}}" />
<CheckBox x:Uid="EntryShowPassword" HorizontalAlignment="Left" Margin="-3,0,0,0" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/>
<local:TextBoxWithButton x:Name="UrlTextBox" HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonClick="UrlButton_Click" ButtonSymbol="&#xE111;" ButtonTooltip="Navigate to URL" />
<TextBlock x:Uid="EntryNotes" TextWrapping="Wrap" FontSize="18" />
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
<CheckBox x:Uid="EntryExpirationDate" FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" />
<local:TextBoxWithButton x:Uid="UrlTextBox" Text="{Binding Url, Mode=TwoWay}" MaxLength="256" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="&#xE111;" IsEnabled="{Binding IsSelected}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick">
<actions:NavigateToUrlAction Url="{Binding Url}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</local:TextBoxWithButton>
<TextBlock x:Uid="EntryNotes" />
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" IsEnabled="{Binding IsSelected}" />
<CheckBox x:Uid="EntryExpirationDate" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -473,63 +453,116 @@
</ToolTipService.ToolTip>
</SymbolIcon>
<StackPanel Grid.Column="1" x:Name="ExpirationDatePanel" Orientation="Horizontal" Visibility="{Binding HasExpirationDate, Converter={StaticResource BooleanToVisibilityConverter}}">
<DatePicker Margin="0,0,20,0" Date="{Binding ExpiryDate, Mode=TwoWay}" />
<TimePicker Time="{Binding ExpiryTime, Mode=TwoWay}"/>
<DatePicker Margin="0,0,20,0" Date="{Binding ExpiryDate, Mode=TwoWay}" Style="{StaticResource MainColorDatePicker}" />
<TimePicker Time="{Binding ExpiryTime, Mode=TwoWay}" Style="{StaticResource MainColorTimePicker}" />
</StackPanel>
</Grid>
<StackPanel x:Name="EditDesign" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}" Orientation="Horizontal">
<StackPanel Width="250" HorizontalAlignment="Left">
<TextBlock x:Uid="EntryBackgroundColor" />
<userControls:ColorPickerUserControl SelectedColor="{Binding BackgroundColor, Converter={StaticResource ColorToBrushConverter}, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
</StackPanel>
<StackPanel Width="250" HorizontalAlignment="Left">
<TextBlock x:Uid="EntryForegroundColor" />
<userControls:ColorPickerUserControl SelectedColor="{Binding ForegroundColor, Converter={StaticResource ColorToBrushConverter}, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
</StackPanel>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Grid>
<!-- Bouton Précédent et titre de la page -->
<Grid Grid.Row="0" Background="{ThemeResource AppBarBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="{StaticResource MenuGridLength}"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Height="50"
Width="50"
Height="{StaticResource MenuSize}"
Width="{StaticResource MenuSize}"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"
Style="{StaticResource NoBorderButtonStyle}">
<SymbolIcon Symbol="Back" />
</Button>
<StackPanel Grid.Column="1" >
<TextBox
x:Name="TitleTextBox"
<Grid Grid.Column="1" x:Name="TopGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}">
<userControls:SymbolPickerUserControl Width="80" Height="40" SelectedSymbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=0, Mode=TwoWay}" />
</Viewbox>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Width="80" Height="40" />
</Viewbox>
<TextBox Grid.Column="1" Grid.Row="0"
Text="{Binding Name, Mode=TwoWay}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
Background="Transparent"
SelectionHighlightColor="{StaticResource MainColor}"
IsHitTestVisible="{Binding IsEditMode}"
BorderThickness="0"
FontSize="20"
FontWeight="SemiBold"
FontWeight="Light"
TextWrapping="NoWrap"
VerticalAlignment="Center"
PlaceholderText="New entry name...">
x:Uid="EntryTitle">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding IsEditMode}" Value="True">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
<TextBlock FontSize="12" Text="{Binding Path}" />
</StackPanel>
<userControls:BreadCrumbUserControl Grid.Column="1" Grid.Row="1" ItemsSource="{Binding BreadCrumb}" Margin="5,-5,0,0" />
</Grid>
<userControls:TopMenuUserControl
x:Name="TopMenu" Grid.Column="2"
RestoreButtonVisibility="{Binding ParentGroup.IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"
DeleteButtonVisibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEditButtonChecked="{Binding IsEditMode, Mode=TwoWay}"
SaveCommand="{Binding SaveCommand}"
RestoreCommand="{Binding UndoDeleteCommand}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="EditButtonClick">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="DeleteButtonClick">
<actions:DeleteEntityAction Entity="{Binding}" Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="RestoreButtonClick">
<core:InvokeCommandAction Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
<actions:ToastAction x:Uid="RestoreEntryCommand" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:TopMenuUserControl>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Small">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpirationDatePanel" Storyboard.TargetProperty="Orientation">
<DiscreteObjectKeyFrame KeyTime="0" Value="Vertical"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="EditDesign" Storyboard.TargetProperty="Orientation">
<DiscreteObjectKeyFrame KeyTime="0" Value="Vertical"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Large">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpirationDatePanel" Storyboard.TargetProperty="Orientation">
<DiscreteObjectKeyFrame KeyTime="0" Value="Horizontal"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Small">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpirationDatePanel" Storyboard.TargetProperty="Orientation">
<DiscreteObjectKeyFrame KeyTime="0" Value="Vertical"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="EditDesign" Storyboard.TargetProperty="Orientation">
<DiscreteObjectKeyFrame KeyTime="0" Value="Horizontal"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>

View File

@@ -1,9 +1,7 @@
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Common;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
// Pour en savoir plus sur le modèle d'élément Page Détail de l'élément, consultez la page http://go.microsoft.com/fwlink/?LinkId=234232
@@ -28,22 +26,8 @@ namespace ModernKeePass.Views
{
InitializeComponent();
NavigationHelper = new NavigationHelper(this);
NavigationHelper.LoadState += navigationHelper_LoadState;
}
/// <summary>
/// Remplit la page à l'aide du contenu passé lors de la navigation. Tout état enregistré est également
/// fourni lorsqu'une page est recréée à partir d'une session antérieure.
/// </summary>
/// <param name="sender">
/// Source de l'événement ; en général <see cref="Common.NavigationHelper"/>
/// </param>
/// <param name="e">Données d'événement qui fournissent le paramètre de navigation transmis à
/// <see cref="Frame.Navigate(Type, object)"/> lors de la requête initiale de cette page et
/// un dictionnaire d'état conservé par cette page durant une session
/// antérieure. L'état n'aura pas la valeur Null lors de la première visite de la page.</param>
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e) {}
#region Inscription de NavigationHelper
/// Les méthodes fournies dans cette section sont utilisées simplement pour permettre
@@ -65,50 +49,30 @@ namespace ModernKeePass.Views
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
NavigationHelper.OnNavigatedFrom(e);
Model.Reset();
}
#endregion
private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
var resource = new ResourcesService();
var message = Model.IsRecycleOnDelete
? resource.GetResourceValue("EntryRecyclingConfirmation")
: resource.GetResourceValue("EntryDeletingConfirmation");
var text = Model.IsRecycleOnDelete ? resource.GetResourceValue("EntryRecycled") : resource.GetResourceValue("EntryDeleted");
MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message,
resource.GetResourceValue("EntityDeleteActionButton"),
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
{
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
Model.MarkForDelete();
if (Frame.CanGoBack) Frame.GoBack();
});
}
private void RestoreButton_Click(object sender, RoutedEventArgs e)
{
var resource = new ResourcesService();
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityRestoredTitle"), resource.GetResourceValue("EntryRestored"));
if (Frame.CanGoBack) Frame.GoBack();
}
private async void UrlButton_Click(object sender, RoutedEventArgs e)
{
try
{
var uri = new Uri(UrlTextBox.Text);
await Windows.System.Launcher.LaunchUriAsync(uri);
}
catch (Exception ex)
{
MessageDialogHelper.ShowErrorDialog(ex);
}
}
private void EntryDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
VisualStateManager.GoToState(TopMenu, e.NewSize.Width < 800 ? "Collapsed" : "Overflowed", true);
}
private void HamburgerMenuUserControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listView = sender as ListView;
switch (listView?.SelectedIndex)
{
case -1:
return;
default:
var entry = listView?.SelectedItem as EntryVm;
StackPanel.DataContext = entry;
TopGrid.DataContext = entry;
break;
}
}
}
}

View File

@@ -8,93 +8,26 @@
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:actions="using:ModernKeePass.Actions"
xmlns:controls="using:ModernKeePass.Controls"
xmlns:templateSelectors="using:ModernKeePass.TemplateSelectors"
xmlns:userControls="using:ModernKeePass.Views.UserControls"
x:Name="PageRoot"
x:Class="ModernKeePass.Views.GroupDetailPage"
mc:Ignorable="d"
SizeChanged="GroupDetailPage_OnSizeChanged">
<Page.Resources>
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
<converters:BooleanToFontStyleConverter x:Key="BooleanToFontStyleConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
<converters:IntToSymbolConverter x:Key="IntToSymbolConverter"/>
</Page.Resources>
<Page.DataContext>
<viewModels:GroupVm />
</Page.DataContext>
<Page.BottomAppBar>
<CommandBar x:Name="CommandBar" VerticalAlignment="Center">
<CommandBar.SecondaryCommands>
<AppBarButton Icon="Home" x:Uid="AppBarHome">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.MainPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
<AppBarButton Icon="Save" x:Uid="AppBarSave">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction TargetObject="{Binding}" MethodName="Save"/>
<core:ChangePropertyAction TargetObject="{Binding ElementName=CommandBar}" PropertyName="IsOpen" Value="False" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
<AppBarButton Icon="Setting" x:Uid="AppBarSettings">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.SettingsPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
</CommandBar.SecondaryCommands>
<AppBarButton Icon="Sort" x:Uid="AppBarSort" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}">
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="AppBarSortEntries">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction MethodName="SortEntries" TargetObject="{Binding}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>
<MenuFlyoutItem x:Uid="AppBarSortGroups">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction MethodName="SortGroups" TargetObject="{Binding}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>
</MenuFlyout>
</Button.Flyout>
</AppBarButton>
<AppBarToggleButton Icon="Edit" x:Uid="AppBarEdit" IsChecked="{Binding IsEditMode, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:ChangePropertyAction TargetObject="{Binding ElementName=CommandBar}" PropertyName="IsOpen" Value="False" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarToggleButton>
<AppBarButton Icon="Undo" x:Uid="AppBarRestore" Visibility="{Binding ShowRestore, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding PreviousGroup, Converter={StaticResource NullToBooleanConverter}}" Click="RestoreButton_Click">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:CallMethodAction MethodName="UndoDelete" TargetObject="{Binding}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AppBarButton>
<AppBarButton Icon="Delete" x:Uid="AppBarDelete" IsEnabled="{Binding IsNotRoot}" Click="DeleteButton_Click" />
</CommandBar>
</Page.BottomAppBar>
<Grid>
<Grid.Resources>
<CollectionViewSource
x:Name="GroupsViewSource"
Source="{Binding Groups}" />
<CollectionViewSource
x:Name="EntriesViewSource"
Source="{Binding EntriesFiltered}" />
Source="{Binding Entries}" />
<CollectionViewSource
x:Name="EntriesZoomedOutViewSource"
Source="{Binding EntriesZoomedOut}" IsSourceGrouped="True" />
@@ -108,91 +41,48 @@
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="{StaticResource MenuGridLength}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="{StaticResource MenuGridLength}" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView
Grid.Column="0"
x:Name="LeftListView"
SelectionChanged="groups_SelectionChanged"
IsSwipeEnabled="false"
IsSynchronizedWithCurrentItem="False"
DataContext="{Binding DataContext, ElementName=PageRoot}"
RequestedTheme="Dark"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}">
<ListView.Resources>
<DataTemplate x:Name="GroupOtherItem">
<userControls:HamburgerMenuUserControl x:Uid="GroupsLeftListView" ItemsSource="{Binding Groups}" SelectionChanged="groups_SelectionChanged" ButtonClicked="CreateGroup_ButtonClick" ResizeTarget="{Binding ElementName=LeftListViewColumn}" IsButtonVisible="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" />
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" x:Uid="ReorderEntriesLabel" Margin="10,10,0,0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource BodyTextBlockStyle}" />
<!--<TextBlock Grid.Column="1" Grid.Row="0" x:Uid="EntrySymbol" Margin="40,20,0,0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource BodyTextBlockStyle}" />-->
<HyperlinkButton Grid.Column="2" Grid.Row="0" VerticalAlignment="Top" Click="CreateEntry_ButtonClick" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" HorizontalAlignment="Right" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
<SymbolIcon Symbol="Add">
<ToolTipService.ToolTip>
<ToolTip Content="{Binding Name}" />
<ToolTip x:Uid="AddEntryTooltip" />
</ToolTipService.ToolTip>
</SymbolIcon>
<TextBlock Text="{Binding Name}" x:Name="GroupTextBlock" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" FontStyle="{Binding IsSelected, Converter={StaticResource BooleanToFontStyleConverter}}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="GroupFirstItem">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
<ToolTipService.ToolTip>
<ToolTip x:Uid="GroupNewItemTooltip" />
</ToolTipService.ToolTip>
</SymbolIcon>
<TextBlock x:Name="GroupTextBlock" x:Uid="GroupNewItemTextBox" FontWeight="SemiBold" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" />
</StackPanel>
</DataTemplate>
</ListView.Resources>
<ListView.ItemsSource>
<Binding Source="{StaticResource GroupsViewSource}"/>
</ListView.ItemsSource>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="AllowDrop" Value="True"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.HeaderTemplate>
<DataTemplate>
<ToggleButton Style="{StaticResource HamburgerToggleButton}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Checked">
<core:ChangePropertyAction PropertyName="Width" Value="Auto" TargetObject="{Binding ElementName=LeftListViewColumn}"/>
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="Unchecked">
<core:ChangePropertyAction PropertyName="Width" Value="50" TargetObject="{Binding ElementName=LeftListViewColumn}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ToggleButton>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplateSelector>
<templateSelectors:FirstItemDataTemplateSelector
FirstItem="{StaticResource GroupFirstItem}"
OtherItem="{StaticResource GroupOtherItem}" />
</ListView.ItemTemplateSelector>
</ListView>
<!-- Horizontal scrolling grid -->
<HyperlinkButton Grid.Column="1" VerticalAlignment="Top" Margin="40,10,0,0" Click="CreateEntry_ButtonClick" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Add"></SymbolIcon>
<TextBlock x:Uid="GroupCreateEntry" VerticalAlignment="Center" Margin="10,0,0,0" />
<TextBlock x:Name="AddEntryTextBlock" x:Uid="GroupCreateEntry" VerticalAlignment="Center" Margin="10,0,0,0" />
</StackPanel>
</HyperlinkButton>
<SemanticZoom Grid.Column="1" ViewChangeStarted="SemanticZoom_ViewChangeStarted" Margin="20,60,0,0">
<SemanticZoom Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" ViewChangeStarted="SemanticZoom_ViewChangeStarted" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<SemanticZoom.ZoomedInView>
<!-- Horizontal scrolling grid -->
<GridView
x:Name="GridView"
ItemsSource="{Binding Source={StaticResource EntriesViewSource}}"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Entries"
TabIndex="1"
Margin="10,0,0,0"
SelectionChanged="entries_SelectionChanged"
IsSynchronizedWithCurrentItem="False"
BorderBrush="{StaticResource ListViewItemSelectedBackgroundThemeBrush}"
@@ -207,124 +97,131 @@
</interactivity:Interaction.Behaviors>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Height="110" Width="480" x:Name="EntryGrid" Background="{Binding BackgroundColor, ConverterParameter={StaticResource AppBarBackgroundThemeBrush}, Converter={StaticResource ColorToBrushConverter}}">
<Grid Height="110" Width="480" x:Name="EntryGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<SymbolIcon Grid.Column="0" Symbol="{Binding IconSymbol}" Width="100" Height="100" RenderTransformOrigin="0.5,0.5" >
<SymbolIcon.RenderTransform>
<CompositeTransform ScaleX="2" TranslateX="0" TranslateY="0" ScaleY="2"/>
</SymbolIcon.RenderTransform>
</SymbolIcon>
<Border Grid.Column="0" Background="{Binding BackgroundColor, ConverterParameter={StaticResource MainColor}, Converter={StaticResource ColorToBrushConverter}}">
<Viewbox MaxHeight="50" Width="100">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=0}" Foreground="{StaticResource TextColor}" />
</Viewbox>
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,10,0,0" >
<TextBlock x:Name="NameTextBlock" Text="{Binding Name}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap" Foreground="{Binding ForegroundColor, ConverterParameter={StaticResource TextBoxForegroundThemeBrush}, Converter={StaticResource ColorToBrushConverter}}"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{Binding UserName}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
<TextBlock Text="{Binding Url}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
<TextBlock Text="{Binding UserName}" Style="{StaticResource BodyTextBlockStyle}" Foreground="{Binding ForegroundColor, ConverterParameter={StaticResource TextBoxForegroundThemeBrush}, Converter={StaticResource ColorToBrushConverter}}" MaxHeight="60" />
<TextBlock Text="{Binding Url}" Style="{StaticResource BodyTextBlockStyle}" Foreground="{Binding ForegroundColor, ConverterParameter={StaticResource TextBoxForegroundThemeBrush}, Converter={StaticResource ColorToBrushConverter}}" MaxHeight="60" />
</StackPanel>
<Button Grid.Column="2" Style="{StaticResource NoBorderButtonStyle}" Background="{StaticResource AppBarBackgroundThemeBrush}" VerticalAlignment="Bottom">
<SymbolIcon Symbol="More" />
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="EntryItemCopyLogin">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<actions:ClipboardAction Text="{Binding UserName}" />
<actions:ToastAction x:Uid="ToastCopyLogin" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>
<MenuFlyoutItem x:Uid="EntryItemCopyPassword">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<actions:ClipboardAction Text="{Binding Password}" />
<actions:ToastAction x:Uid="ToastCopyPassword" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<actions:NavigateToUrlAction Url="{Binding Url}" />
<actions:ToastAction x:Uid="ToastCopyUrl" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>
</MenuFlyout>
</Button.Flyout>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsSource>
<Binding Source="{StaticResource EntriesViewSource}"/>
</GridView.ItemsSource>
<GridView.DataContext>
<viewModels:EntryVm/>
</GridView.DataContext>
<GridView.ItemContainerStyle>
<Style TargetType = "GridViewItem" >
<Setter Property = "Template" >
<Setter.Value>
<ControlTemplate TargetType = "GridViewItem" >
<GridViewItemPresenter
SelectionCheckMarkVisualEnabled="True"
CheckHintBrush="{ThemeResource ListViewItemCheckHintThemeBrush}"
CheckSelectingBrush="{ThemeResource ListViewItemCheckSelectingThemeBrush}"
CheckBrush="{ThemeResource ListViewItemCheckThemeBrush}"
DragBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderThemeBrush}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
PointerOverBackground="{ThemeResource ListViewItemPointerOverBackgroundThemeBrush}"
SelectedBorderThickness="{ThemeResource GridViewItemCompactSelectedBorderThemeThickness}"
SelectedBackground="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}"
SelectedForeground="{ThemeResource ListViewItemSelectedForegroundThemeBrush}"
SelectedPointerOverBackground="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}"
SelectedPointerOverBorderBrush="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
PointerOverBackgroundMargin="1"
ContentMargin="4" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GridView.ItemContainerStyle>
</GridView>
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
<ListView
<GridView
ItemsSource="{Binding Source={StaticResource EntriesZoomedOutViewSource}}"
IsSwipeEnabled="false"
SelectionChanged="groups_SelectionChanged"
SelectionMode="None"
IsSynchronizedWithCurrentItem="False">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap"/>
<TextBlock Width="100" Text="{Binding Name}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle HidesIfEmpty="True">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Background="LightGray" Margin="0,0,10,0" HorizontalAlignment="Left">
<TextBlock Text="{Binding Key}" Width="40" Foreground="Black" Margin="30" Style="{StaticResource HeaderTextBlockStyle}"/>
<Grid Background="LightGray" HorizontalAlignment="Left">
<TextBlock Text="{Binding Key}" Width="50" Margin="30" Foreground="{StaticResource MainColor}" Style="{StaticResource HeaderTextBlockStyle}" TextAlignment="Center" />
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</GridView.GroupStyle>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
</Grid>
</Grid>
<!-- Back button and page title -->
<Grid Grid.Row="0" Background="{ThemeResource AppBarBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="{StaticResource MenuGridLength}"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Height="50"
Width="50"
Height="{StaticResource MenuSize}"
Width="{StaticResource MenuSize}"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"
Style="{StaticResource NoBorderButtonStyle}">
<SymbolIcon Symbol="Back" />
</Button>
<StackPanel Grid.Column="1" >
<TextBox
<Grid Grid.Column="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}">
<userControls:SymbolPickerUserControl Width="80" Height="40" SelectedSymbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=48, Mode=TwoWay}" />
</Viewbox>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Width="80" Height="40" />
</Viewbox>
<TextBox Grid.Column="1" Grid.Row="0"
x:Name="TitleTextBox"
Text="{Binding Name, Mode=TwoWay}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
SelectionHighlightColor="{StaticResource MainColor}"
Background="Transparent"
IsHitTestVisible="{Binding IsEditMode}"
BorderThickness="0"
FontSize="20"
FontWeight="SemiBold"
FontWeight="Light"
TextWrapping="NoWrap"
VerticalAlignment="Center"
x:Uid="GroupTitle">
@@ -334,17 +231,56 @@
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
<TextBlock FontSize="12" Text="{Binding Path}" />
<userControls:BreadCrumbUserControl Grid.Column="1" Grid.Row="1" ItemsSource="{Binding BreadCrumb}" Margin="5,-5,0,0" />
</Grid>
<userControls:TopMenuUserControl x:Name="TopMenu" Grid.Column="2"
RestoreButtonVisibility="{Binding ShowRestore, Converter={StaticResource BooleanToVisibilityConverter}}"
DeleteButtonVisibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
SortButtonVisibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEditButtonChecked="{Binding IsEditMode, Mode=TwoWay}"
IsDeleteButtonEnabled="{Binding IsNotRoot}"
SaveCommand="{Binding SaveCommand}"
RestoreCommand="{Binding UndoDeleteCommand}"
SortEntriesCommand="{Binding SortEntriesCommand}"
SortGroupsCommand="{Binding SortGroupsCommand}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="EditButtonClick">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="DeleteButtonClick">
<actions:DeleteEntityAction Entity="{Binding}" Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="RestoreButtonClick">
<core:InvokeCommandAction Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
<actions:ToastAction x:Uid="RestoreGroupCommand" Title="{Binding Name}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:TopMenuUserControl>
<Button Grid.Column="3" x:Name="SearchButton" Style="{StaticResource NoBorderButtonStyle}" Background="{ThemeResource ToggleButtonBackgroundThemeBrush}" Height="{StaticResource MenuSize}" Padding="25,0,25,0">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Find" />
<TextBlock x:Uid="SearchButtonLabel" x:Name="SearchButtonLabel" TextWrapping="NoWrap" FontSize="16" VerticalAlignment="Center" Margin="10,0,0,0" />
</StackPanel>
<Button Grid.Column="2" x:Name="FilterButton" Style="{StaticResource NoBorderButtonStyle}" Height="50">
<SymbolIcon Symbol="Filter" />
<Button.Flyout>
<Flyout>
<controls:TextBoxWithButton x:Uid="GroupFilter" ButtonSymbol="&#xE16E;" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="18" VerticalContentAlignment="Center" Width="400" Style="{StaticResource TextBoxWithButtonStyle}" IsButtonEnabled="False" />
</Flyout>
</Button.Flyout>
<ToolTipService.ToolTip>
<ToolTip x:Uid="SearchButtonTooltip" />
</ToolTipService.ToolTip>
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:ChangePropertyAction TargetObject="{Binding ElementName=SearchBox}" PropertyName="Visibility" Value="Visible" />
<core:ChangePropertyAction TargetObject="{Binding ElementName=SearchButton}" PropertyName="Visibility" Value="Collapsed" />
<!-- TODO: make this work -->
<actions:SetupFocusAction TargetObject="{Binding ElementName=SearchBox}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Button>
<controls:TextBoxWithButton Grid.Column="2" x:Name="FilterBox" x:Uid="GroupFilter" ButtonSymbol="&#xE16E;" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="18" VerticalContentAlignment="Center" Width="400" Style="{StaticResource TextBoxWithButtonStyle}" IsButtonEnabled="False" />
<SearchBox Grid.Column="3" x:Uid="GroupSearch" x:Name="SearchBox" Padding="12" Width="350" Visibility="Collapsed" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" Margin="0,5,0,5" FontSize="15" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" Style="{StaticResource MainColorSearchBox}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="LostFocus">
<core:ChangePropertyAction TargetObject="{Binding ElementName=SearchBox}" PropertyName="Visibility" Value="Collapsed" />
<core:ChangePropertyAction TargetObject="{Binding ElementName=SearchButton}" PropertyName="Visibility" Value="Visible" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</SearchBox>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DragDropGroup">
@@ -363,23 +299,23 @@
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FilterGroup">
<VisualStateGroup x:Name="TopMenuGroup">
<VisualState x:Name="Small">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="AddEntryTextBlock" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterBox" Storyboard.TargetProperty="Visibility">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButtonLabel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Large">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="AddEntryTextBlock" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterBox" Storyboard.TargetProperty="Visibility">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButtonLabel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>

View File

@@ -1,11 +1,12 @@
using System;
using System.Linq;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Common;
using ModernKeePass.Events;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
// The Group Detail Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234229
@@ -29,22 +30,8 @@ namespace ModernKeePass.Views
{
InitializeComponent();
NavigationHelper = new NavigationHelper(this);
NavigationHelper.LoadState += navigationHelper_LoadState;
}
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param name="sender">
/// The source of the event; typically <see cref="Common.NavigationHelper"/>
/// </param>
/// <param name="e">Event data that provides both the navigation parameter passed to
/// <see cref="Frame.Navigate(Type, object)"/> when this page was initially requested and
/// a dictionary of state preserved by this page during an earlier
/// session. The state will be null the first time a page is visited.</param>
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e) {}
#region NavigationHelper registration
/// The methods provided in this section are simply used to allow
@@ -60,10 +47,15 @@ namespace ModernKeePass.Views
{
NavigationHelper.OnNavigatedTo(e);
if (e.Parameter is PasswordEventArgs)
DataContext = ((PasswordEventArgs) e.Parameter).RootGroup;
else if (e.Parameter is GroupVm)
DataContext = (GroupVm) e.Parameter;
var args = e.Parameter as PasswordEventArgs;
if (args != null)
DataContext = args.RootGroup;
else
{
var vm = e.Parameter as GroupVm;
if (vm != null)
DataContext = vm;
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
@@ -77,64 +69,35 @@ namespace ModernKeePass.Views
private void groups_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
GroupVm group;
switch (LeftListView.SelectedIndex)
var listView = sender as ListView;
switch (listView?.SelectedIndex)
{
case -1:
return;
case 0:
group = Model.AddNewGroup();
break;
default:
group = LeftListView.SelectedItem as GroupVm;
var group = listView?.SelectedItem as GroupVm;
Frame.Navigate(typeof(GroupDetailPage), group);
break;
}
Frame.Navigate(typeof(GroupDetailPage), group);
}
private void entries_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
EntryVm entry;
switch (GridView.SelectedIndex)
{
case -1:
return;
default:
entry = GridView.SelectedItem as EntryVm;
var entry = GridView.SelectedItem as EntryVm;
Frame.Navigate(typeof(EntryDetailPage), entry);
break;
}
Frame.Navigate(typeof(EntryDetailPage), entry);
}
private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
var resource = new ResourcesService();
var message = Model.IsRecycleOnDelete
? resource.GetResourceValue("GroupRecyclingConfirmation")
: resource.GetResourceValue("GroupDeletingConfirmation");
var text = Model.IsRecycleOnDelete ? resource.GetResourceValue("GroupRecycled") : resource.GetResourceValue("GroupDeleted");
MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message,
resource.GetResourceValue("EntityDeleteActionButton"),
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
{
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
Model.MarkForDelete();
if (Frame.CanGoBack) Frame.GoBack();
});
}
private void RestoreButton_Click(object sender, RoutedEventArgs e)
{
var resource = new ResourcesService();
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityRestoredTitle"),
resource.GetResourceValue("GroupRestored"));
if (Frame.CanGoBack) Frame.GoBack();
}
private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
{
// We need to synchronize the two lists (zoomed-in and zoomed-out) because the source is different
if (e.IsSourceZoomedInView == false)
if (!e.IsSourceZoomedInView)
{
e.DestinationItem.Item = e.SourceItem.Item;
}
@@ -143,6 +106,10 @@ namespace ModernKeePass.Views
{
Frame.Navigate(typeof(EntryDetailPage), Model.AddNewEntry());
}
private void CreateGroup_ButtonClick(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(GroupDetailPage), Model.AddNewGroup());
}
private void GridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
@@ -150,9 +117,26 @@ namespace ModernKeePass.Views
e.Data.RequestedOperation = DataPackageOperation.Move;
}
private void SearchBox_OnSuggestionsRequested(SearchBox sender, SearchBoxSuggestionsRequestedEventArgs args)
{
var imageUri = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appdata://Assets/ModernKeePass-SmallLogo.scale-80.png"));
var results = Model.SubEntries.Where(e => e.Name.IndexOf(args.QueryText, StringComparison.OrdinalIgnoreCase) >= 0).Take(5);
foreach (var result in results)
{
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Name, result.ParentGroup.Name, result.Id, imageUri, string.Empty);
}
}
private void SearchBox_OnResultSuggestionChosen(SearchBox sender, SearchBoxResultSuggestionChosenEventArgs args)
{
var entry = Model.SubEntries.FirstOrDefault(e => e.Id == args.Tag);
Frame.Navigate(typeof(EntryDetailPage), entry);
}
private void GroupDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
VisualStateManager.GoToState(this, e.NewSize.Width < 800 ? "Small" : "Large", true);
VisualStateManager.GoToState(TopMenu, e.NewSize.Width < 800 ? "Collapsed" : "Overflowed", true);
}
#endregion

View File

@@ -30,7 +30,7 @@
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="{StaticResource MenuGridLength}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
@@ -47,8 +47,7 @@
<Button x:Name="BackButton"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Visibility="Collapsed"
Height="40"
VerticalAlignment="Center"
Height="{StaticResource MenuSize}"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"

View File

@@ -1,4 +1,5 @@
using Windows.UI.Xaml.Controls;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.ViewModels;
@@ -23,6 +24,7 @@ namespace ModernKeePass.Views
private new void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
base.ListView_SelectionChanged(sender, e);
var selectedItem = Model.SelectedItem as MainMenuItemVm;
if (selectedItem == null) MenuFrame.Navigate(typeof(WelcomePage));
else selectedItem.Destination.Navigate(selectedItem.PageType, selectedItem.Parameter);
@@ -31,7 +33,8 @@ namespace ModernKeePass.Views
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
DataContext = new MainVm(Frame, MenuFrame);
var file = e.Parameter as StorageFile;
DataContext = new MainVm(Frame, MenuFrame, file);
}
}
}

View File

@@ -22,9 +22,10 @@
</TextBlock>
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="30,0,0,0">
<Run x:Uid="AboutHomepage" />
<Hyperlink NavigateUri="https://github.com/wismna/ModernKeePass">
<Run Text="https://github.com/wismna/ModernKeePass"/>
</Hyperlink></TextBlock>
<Hyperlink NavigateUri="https://wismna.github.io/ModernKeePass/" Foreground="{StaticResource MainColor}">
<Run Text="https://wismna.github.io/ModernKeePass/"/>
</Hyperlink>
</TextBlock>
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="10,0,0,0">
<Run x:Uid="AboutCreditsLabel" />
</TextBlock>

View File

@@ -4,27 +4,17 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:converters="using:ModernKeePass.Converters"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
mc:Ignorable="d">
<Page.DataContext>
<viewModels:DonateVm />
</Page.DataContext>
<Page.Resources>
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
<CollectionViewSource
x:Name="DonateItemsSource"
Source="{Binding Donations}" />
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="10,0,0,0">
<TextBlock x:Uid="DonateDesc" Style="{StaticResource BodyTextBlockStyle}" />
<ItemsControl ItemsSource="{Binding Source={StaticResource DonateItemsSource}}" Margin="0,10,0,10">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="DonateOptions" Content="{Binding FormattedPrice}" Checked="ToggleButton_OnChecked" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button x:Uid="DonateButton" Click="ButtonBase_OnClick" IsEnabled="{Binding SelectedItem, Converter={StaticResource NullToBooleanConverter}}" />
</StackPanel>
<Grid>
<ProgressRing x:Name="LoadingRing" IsActive="True" Width="50" Height="50" Foreground="{StaticResource MainColor}" />
<WebView Source="https://PayPal.Me/wismna">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="DOMContentLoaded">
<core:ChangePropertyAction TargetObject="{Binding ElementName=LoadingRing}" PropertyName="IsActive" Value="False" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</WebView>
</Grid>
</Page>

View File

@@ -1,12 +1,4 @@
using System;
using Windows.ApplicationModel.Store;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace ModernKeePass.Views
{
@@ -15,57 +7,9 @@ namespace ModernKeePass.Views
/// </summary>
public sealed partial class DonatePage
{
public DonateVm Model => DataContext as DonateVm;
public DonatePage()
{
InitializeComponent();
}
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
var source = sender as RadioButton;
Model.SelectedItem = source?.DataContext as ProductListing;
}
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var resource = new ResourcesService();
try
{
var result = await Model.Purchase();
switch ((LicenseService.PurchaseResult)result)
{
case LicenseService.PurchaseResult.Succeeded:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateSucceededTitle"), resource.GetResourceValue("DonateSucceededMessage"));
break;
case LicenseService.PurchaseResult.NothingToFulfill:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateNothingToFulfillTitle"), resource.GetResourceValue("DonateNothingToFulfillMessage"));
break;
case LicenseService.PurchaseResult.PurchasePending:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonatePurchasePendingTitle"), resource.GetResourceValue("DonatePurchasePendingMessage"));
break;
case LicenseService.PurchaseResult.PurchaseReverted:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonatePurchaseRevertedTitle"), resource.GetResourceValue("DonatePurchaseRevertedMessage"));
break;
case LicenseService.PurchaseResult.ServerError:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateServerErrorTitle"), resource.GetResourceValue("DonateServerErrorMessage"));
break;
case LicenseService.PurchaseResult.NotPurchased:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateNotPurchasedTitle"), resource.GetResourceValue("DonateNotPurchasedMessage"));
break;
// Should never happen because these are consumables
case LicenseService.PurchaseResult.AlreadyPurchased:
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateAlreadyPurchasedTitle"), resource.GetResourceValue("DonateAlreadyPurchasedMessage"));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
catch (Exception exception)
{
MessageDialogHelper.ShowErrorDialog(exception);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More