Adds some VM tests

New tooltip in Textbox with button control
New welcome page in Settings (shown when noting is selected)
Settings are now grouped
This commit is contained in:
BONNEVILLE Geoffroy
2017-11-27 15:26:36 +01:00
parent 42ac04b02c
commit fcbda1e33d
23 changed files with 214 additions and 67 deletions

View File

@@ -1,6 +1,5 @@
using System; using System;
using Windows.Storage; using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using ModernKeePass.Exceptions; using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces; using ModernKeePass.Interfaces;

View File

@@ -32,5 +32,18 @@ namespace ModernKeePass.Common
ToastNotificationManager.CreateToastNotifier().Show(toast); ToastNotificationManager.CreateToastNotifier().Show(toast);
} }
public static void ShowGenericToast(string title, string text)
{
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
var toastElements = notificationXml.GetElementsByTagName("text");
toastElements[0].AppendChild(notificationXml.CreateTextNode(title));
toastElements[1].AppendChild(notificationXml.CreateTextNode(text));
var toast = new ToastNotification(notificationXml)
{
ExpirationTime = DateTime.Now.AddSeconds(5)
};
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
} }
} }

View File

@@ -71,7 +71,11 @@ namespace ModernKeePass.Controls
{ {
ValidationChecking?.Invoke(this, new EventArgs()); ValidationChecking?.Invoke(this, new EventArgs());
if (UpdateKey) Model.UpdateKey(); if (UpdateKey)
{
Model.UpdateKey();
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup));
}
else else
{ {
var oldLabel = ButtonLabel; var oldLabel = ButtonLabel;

View File

@@ -6,18 +6,6 @@ namespace ModernKeePass.Controls
{ {
public class TextBoxWithButton : TextBox public class TextBoxWithButton : TextBox
{ {
/*public Symbol ButtonSymbol
{
get { return (Symbol)GetValue(ButtonSymbolProperty); }
set { SetValue(ButtonSymbolProperty, value); }
}
public static readonly DependencyProperty ButtonSymbolProperty =
DependencyProperty.Register(
"ButtonSymbol",
typeof(Symbol),
typeof(TextBoxWithButton),
new PropertyMetadata(Symbol.Delete, (o, args) => { }));*/
public string ButtonSymbol public string ButtonSymbol
{ {
get { return (string)GetValue(ButtonSymbolProperty); } get { return (string)GetValue(ButtonSymbolProperty); }
@@ -31,6 +19,18 @@ namespace ModernKeePass.Controls
new PropertyMetadata("", (o, args) => { })); new PropertyMetadata("", (o, args) => { }));
public event EventHandler<RoutedEventArgs> ButtonClick; public event EventHandler<RoutedEventArgs> ButtonClick;
public string ButtonTooltip
{
get { return (string)GetValue(ButtonTooltipProperty); }
set { SetValue(ButtonTooltipProperty, value); }
}
public static readonly DependencyProperty ButtonTooltipProperty =
DependencyProperty.Register(
"ButtonTooltip",
typeof(string),
typeof(TextBoxWithButton),
new PropertyMetadata(string.Empty, (o, args) => { }));
protected override void OnApplyTemplate() protected override void OnApplyTemplate()
{ {
base.OnApplyTemplate(); base.OnApplyTemplate();

View File

@@ -136,6 +136,9 @@
<Compile Include="Pages\SettingsPageFrames\SettingsSecurityPage.xaml.cs"> <Compile Include="Pages\SettingsPageFrames\SettingsSecurityPage.xaml.cs">
<DependentUpon>SettingsSecurityPage.xaml</DependentUpon> <DependentUpon>SettingsSecurityPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Pages\SettingsPageFrames\SettingsWelcomePage.xaml.cs">
<DependentUpon>SettingsWelcomePage.xaml</DependentUpon>
</Compile>
<Compile Include="TemplateSelectors\FirstItemDataTemplateSelector.cs" /> <Compile Include="TemplateSelectors\FirstItemDataTemplateSelector.cs" />
<Compile Include="Controls\ListViewWithDisable.cs" /> <Compile Include="Controls\ListViewWithDisable.cs" />
<Compile Include="Controls\CompositeKeyUserControl.xaml.cs"> <Compile Include="Controls\CompositeKeyUserControl.xaml.cs">
@@ -268,6 +271,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Pages\SettingsPageFrames\SettingsWelcomePage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\HamburgerButtonStyle.xaml"> <Page Include="Styles\HamburgerButtonStyle.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -69,17 +69,17 @@ namespace ModernKeePass.Pages.BasePages
{ {
// When this is a new page, select the first item automatically unless logical page // When this is a new page, select the first item automatically unless logical page
// navigation is being used (see the logical page navigation #region below.) // navigation is being used (see the logical page navigation #region below.)
if (!UsingLogicalPageNavigation() && ListViewSource.View != null) if (!UsingLogicalPageNavigation())
{ {
ListViewSource.View.MoveCurrentToFirst(); ListViewSource.View?.MoveCurrentToFirst();
} }
} }
else else
{ {
// Restore the previously saved state associated with this page // Restore the previously saved state associated with this page
if (e.PageState.ContainsKey("SelectedItem") && ListViewSource.View != null) if (e.PageState.ContainsKey("SelectedItem"))
{ {
ListViewSource.View.MoveCurrentTo(e.PageState["SelectedItem"]); ListViewSource.View?.MoveCurrentTo(e.PageState["SelectedItem"]);
} }
} }
} }

View File

@@ -428,7 +428,7 @@
</Style> </Style>
</StackPanel.Resources> </StackPanel.Resources>
<TextBlock TextWrapping="Wrap" Text="User name or login" FontSize="18"/> <TextBlock TextWrapping="Wrap" Text="User name or login" FontSize="18"/>
<local:TextBoxWithButton HorizontalAlignment="Left" Text="{Binding UserName, Mode=TwoWay}" Width="350" Height="32" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;"> <local:TextBoxWithButton HorizontalAlignment="Left" Text="{Binding UserName, Mode=TwoWay}" Width="350" Height="32" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;" ButtonTooltip="Copy">
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick"> <core:EventTriggerBehavior EventName="ButtonClick">
<actions:ClipboardAction Text="{Binding UserName}" /> <actions:ClipboardAction Text="{Binding UserName}" />
@@ -437,7 +437,7 @@
</local:TextBoxWithButton> </local:TextBoxWithButton>
<TextBlock TextWrapping="Wrap" Text="Password" FontSize="18"/> <TextBlock TextWrapping="Wrap" Text="Password" 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}" /> <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;"> <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">
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick"> <core:EventTriggerBehavior EventName="ButtonClick">
<actions:ClipboardAction Text="{Binding Password}" /> <actions:ClipboardAction Text="{Binding Password}" />
@@ -447,7 +447,7 @@
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushComplexityConverter}}" /> <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 HorizontalAlignment="Left" Margin="-3,0,0,0" Content="Show password" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" /> <CheckBox HorizontalAlignment="Left" Margin="-3,0,0,0" Content="Show password" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/> <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;" /> <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 TextWrapping="Wrap" Text="Notes" FontSize="18"/> <TextBlock TextWrapping="Wrap" Text="Notes" FontSize="18"/>
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" /> <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
<CheckBox FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" Content="Expiration date"/> <CheckBox FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" Content="Expiration date"/>
@@ -467,14 +467,12 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/> <ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="400"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Button Grid.Column="0" <Button Grid.Column="0"
x:Name="BackButton" x:Name="BackButton"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Height="50" Height="50"
Width="50" Width="50"
VerticalAlignment="Center"
AutomationProperties.Name="Back" AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton" AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button" AutomationProperties.ItemType="Navigation Button"

View File

@@ -270,7 +270,6 @@
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Height="50" Height="50"
Width="50" Width="50"
VerticalAlignment="Center"
AutomationProperties.Name="Back" AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton" AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button" AutomationProperties.ItemType="Navigation Button"

View File

@@ -32,7 +32,6 @@ namespace ModernKeePass.Pages
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
DataContext = new MainVm(Frame, MenuFrame); DataContext = new MainVm(Frame, MenuFrame);
//if (Model.SelectedItem == null) MenuFrame.Navigate(typeof(WelcomePage));
} }
} }
} }

View File

@@ -10,11 +10,10 @@
x:Class="ModernKeePass.Pages.SettingsPage" x:Class="ModernKeePass.Pages.SettingsPage"
mc:Ignorable="d"> mc:Ignorable="d">
<Page.Resources> <Page.Resources>
<CollectionViewSource x:Name="MenuItemsSource" Source="{Binding MenuItems}" > <CollectionViewSource x:Name="MenuItemsSource" Source="{Binding MenuItems}" IsSourceGrouped="True" />
</CollectionViewSource>
</Page.Resources> </Page.Resources>
<Page.DataContext> <Page.DataContext>
<viewModels:SettingsVM /> <viewModels:SettingsVm />
</Page.DataContext> </Page.DataContext>
<Page.Background> <Page.Background>
@@ -74,9 +73,12 @@
<GroupStyle HidesIfEmpty="True"> <GroupStyle HidesIfEmpty="True">
<GroupStyle.HeaderTemplate> <GroupStyle.HeaderTemplate>
<DataTemplate> <DataTemplate>
<Grid Background="DarkGray" Margin="20,0,0,0"> <StackPanel Margin="20,0,0,0">
<TextBlock Text="{Binding Key}" />
<Grid Background="DarkGray">
<Border Height="1" Width="300" HorizontalAlignment="Stretch"/> <Border Height="1" Width="300" HorizontalAlignment="Stretch"/>
</Grid> </Grid>
</StackPanel>
</DataTemplate> </DataTemplate>
</GroupStyle.HeaderTemplate> </GroupStyle.HeaderTemplate>
</GroupStyle> </GroupStyle>

View File

@@ -1,4 +1,5 @@
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using ModernKeePass.Pages.SettingsPageFrames;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
// The Split Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234234 // The Split Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234234
@@ -11,7 +12,7 @@ namespace ModernKeePass.Pages
/// </summary> /// </summary>
public sealed partial class SettingsPage public sealed partial class SettingsPage
{ {
public new SettingsVM Model => (SettingsVM)DataContext; public new SettingsVm Model => (SettingsVm)DataContext;
public SettingsPage() public SettingsPage()
{ {
@@ -24,8 +25,7 @@ namespace ModernKeePass.Pages
{ {
ListView_SelectionChanged(sender, e); ListView_SelectionChanged(sender, e);
var selectedItem = Model.SelectedItem as ListMenuItemVm; var selectedItem = Model.SelectedItem as ListMenuItemVm;
if (selectedItem == null) return; MenuFrame?.Navigate(selectedItem == null ? typeof(SettingsWelcomePage) : selectedItem.PageType);
MenuFrame?.Navigate(selectedItem.PageType);
} }
} }
} }

View File

@@ -8,7 +8,12 @@
mc:Ignorable="d"> mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="Change database security options" /> <TextBlock FontSize="14" Text="Change database security options" Margin="5,0,0,0" />
<local:CompositeKeyUserControl UpdateKey="True" ButtonLabel="Update master key" /> <TextBlock TextWrapping="WrapWholeWords" Margin="5,0,0,0">
<Run Text="Here, you may change your database password, key file, or both. Just click on on" />
<Run Text="Update master key" FontWeight="SemiBold" />
<Run Text="when you're done. Please make sure to remember the password you choose here!" />
</TextBlock>
<local:CompositeKeyUserControl Margin="0,20,0,0" UpdateKey="True" ButtonLabel="Update master key" ValidationChecked="CompositeKeyUserControl_OnValidationChecked" />
</StackPanel> </StackPanel>
</Page> </Page>

View File

@@ -1,5 +1,8 @@
// 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
using ModernKeePass.Common;
using ModernKeePass.Events;
namespace ModernKeePass.Pages namespace ModernKeePass.Pages
{ {
/// <summary> /// <summary>
@@ -11,5 +14,10 @@ namespace ModernKeePass.Pages
{ {
InitializeComponent(); InitializeComponent();
} }
private void CompositeKeyUserControl_OnValidationChecked(object sender, PasswordEventArgs e)
{
ToastNotificationHelper.ShowGenericToast("Composite key", "Database successfully updated.");
}
} }
} }

View File

@@ -0,0 +1,14 @@
<Page
x:Class="ModernKeePass.Pages.SettingsPageFrames.SettingsWelcomePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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"
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock FontSize="24" VerticalAlignment="Center" Margin="10,-70,0,0" Text="Settings" />
<TextBlock VerticalAlignment="Center" FontSize="14" Margin="5,0,0,0" Text="Here, you may change the application or the database settings." />
<TextBlock VerticalAlignment="Center" FontSize="14" Margin="5,0,0,0" Text="Select a setting pane on the left to access the options." />
</StackPanel>
</Page>

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace ModernKeePass.Pages.SettingsPageFrames
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SettingsWelcomePage : Page
{
public SettingsWelcomePage()
{
this.InitializeComponent();
}
}
}

View File

@@ -222,7 +222,11 @@
Visibility="Collapsed" Visibility="Collapsed"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
Content="{TemplateBinding ButtonSymbol}" Content="{TemplateBinding ButtonSymbol}"
VerticalAlignment="Stretch"/> VerticalAlignment="Stretch">
<ToolTipService.ToolTip>
<ToolTip Content="{TemplateBinding ButtonTooltip}" />
</ToolTipService.ToolTip>
</Button>
</Grid> </Grid>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>

View File

@@ -1,7 +1,6 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Windows.UI.Text; using Windows.UI.Text;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -117,6 +116,7 @@ namespace ModernKeePass.ViewModels
var pwEntry = new PwEntry(true, true); var pwEntry = new PwEntry(true, true);
_pwGroup.AddEntry(pwEntry, true); _pwGroup.AddEntry(pwEntry, true);
var newEntry = new EntryVm(pwEntry, this) {IsEditMode = true}; var newEntry = new EntryVm(pwEntry, this) {IsEditMode = true};
newEntry.GeneratePassword();
Entries.Add(newEntry); Entries.Add(newEntry);
return newEntry; return newEntry;
} }

View File

@@ -11,7 +11,7 @@ namespace ModernKeePass.ViewModels
public string Title { get; set; } public string Title { get; set; }
public int Group { get; set; } = 0; public string Group { get; set; } = "_";
public Type PageType { get; set; } public Type PageType { get; set; }
public Symbol SymbolIcon { get; set; } public Symbol SymbolIcon { get; set; }
public bool IsEnabled { get; set; } = true; public bool IsEnabled { get; set; } = true;

View File

@@ -12,12 +12,12 @@ namespace ModernKeePass.ViewModels
{ {
public class MainVm : NotifyPropertyChangedBase, IHasSelectableObject public class MainVm : NotifyPropertyChangedBase, IHasSelectableObject
{ {
private IOrderedEnumerable<IGrouping<int, MainMenuItemVm>> _mainMenuItems; private IOrderedEnumerable<IGrouping<string, MainMenuItemVm>> _mainMenuItems;
private MainMenuItemVm _selectedItem; private MainMenuItemVm _selectedItem;
public string Name { get; } = Package.Current.DisplayName; public string Name { get; } = Package.Current.DisplayName;
public IOrderedEnumerable<IGrouping<int, MainMenuItemVm>> MainMenuItems public IOrderedEnumerable<IGrouping<string, MainMenuItemVm>> MainMenuItems
{ {
get { return _mainMenuItems; } get { return _mainMenuItems; }
set { SetProperty(ref _mainMenuItems, value); } set { SetProperty(ref _mainMenuItems, value); }
@@ -86,7 +86,7 @@ namespace ModernKeePass.ViewModels
PageType = typeof(GroupDetailPage), PageType = typeof(GroupDetailPage),
Destination = referenceFrame, Destination = referenceFrame,
Parameter = database.RootGroup, Parameter = database.RootGroup,
Group = 1, Group = "Databases",
SymbolIcon = Symbol.ProtectedDocument SymbolIcon = Symbol.ProtectedDocument
}); });

View File

@@ -1,5 +1,4 @@
using System.ComponentModel; using Windows.Storage;
using Windows.Storage;
using Windows.Storage.AccessCache; using Windows.Storage.AccessCache;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using ModernKeePass.Common; using ModernKeePass.Common;
@@ -7,7 +6,7 @@ using ModernKeePass.Interfaces;
namespace ModernKeePass.ViewModels namespace ModernKeePass.ViewModels
{ {
public class OpenVm: INotifyPropertyChanged public class OpenVm: NotifyPropertyChangedBase
{ {
public bool ShowPasswordBox => _database?.Status == (int) DatabaseHelper.DatabaseStatus.Opening; public bool ShowPasswordBox => _database?.Status == (int) DatabaseHelper.DatabaseStatus.Opening;
@@ -24,18 +23,11 @@ namespace ModernKeePass.ViewModels
OpenFile(database.DatabaseFile); OpenFile(database.DatabaseFile);
} }
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void OpenFile(StorageFile file) public void OpenFile(StorageFile file)
{ {
_database.DatabaseFile = file; _database.DatabaseFile = file;
NotifyPropertyChanged("Name"); OnPropertyChanged("Name");
NotifyPropertyChanged("ShowPasswordBox"); OnPropertyChanged("ShowPasswordBox");
AddToRecentList(file); AddToRecentList(file);
} }

View File

@@ -7,11 +7,19 @@ using ModernKeePass.Pages;
namespace ModernKeePass.ViewModels namespace ModernKeePass.ViewModels
{ {
public class SettingsVM : NotifyPropertyChangedBase, IHasSelectableObject public class SettingsVm : NotifyPropertyChangedBase, IHasSelectableObject
{ {
private ListMenuItemVm _selectedItem; private ListMenuItemVm _selectedItem;
public ObservableCollection<ListMenuItemVm> MenuItems { get; set; } //public ObservableCollection<ListMenuItemVm> MenuItems { get; set; }
private IOrderedEnumerable<IGrouping<string, ListMenuItemVm>> _menuItems;
public IOrderedEnumerable<IGrouping<string, ListMenuItemVm>> MenuItems
{
get { return _menuItems; }
set { SetProperty(ref _menuItems, value); }
}
public ISelectableModel SelectedItem public ISelectableModel SelectedItem
{ {
get { return _selectedItem; } get { return _selectedItem; }
@@ -32,15 +40,17 @@ namespace ModernKeePass.ViewModels
} }
} }
public SettingsVM() public SettingsVm()
{ {
MenuItems = new ObservableCollection<ListMenuItemVm> var menuItems = new ObservableCollection<ListMenuItemVm>
{ {
new ListMenuItemVm { Title = "Database", SymbolIcon = Symbol.Setting, PageType = typeof(SettingsDatabasePage), IsSelected = true }, new ListMenuItemVm { Title = "General", Group = "Database", SymbolIcon = Symbol.Setting, PageType = typeof(SettingsDatabasePage), IsSelected = true },
new ListMenuItemVm { Title = "Security", SymbolIcon = Symbol.Permissions, PageType = typeof(SettingsSecurityPage) }, new ListMenuItemVm { Title = "Security", Group = "Database", SymbolIcon = Symbol.Permissions, PageType = typeof(SettingsSecurityPage) },
//new ListMenuItemVm { Title = "General", SymbolIcon = Symbol.Edit, PageType = typeof(SettingsGeneralPage) } //new ListMenuItemVm { Title = "General", SymbolIcon = Symbol.Edit, PageType = typeof(SettingsGeneralPage) }
}; };
SelectedItem = MenuItems.FirstOrDefault(m => m.IsSelected); SelectedItem = menuItems.FirstOrDefault(m => m.IsSelected);
MenuItems = from item in menuItems group item by item.Group into grp orderby grp.Key select grp;
} }
} }
} }

View File

@@ -35,7 +35,7 @@ namespace ModernKeePassApp.Test.Mock
public void Close() public void Close()
{ {
throw new NotImplementedException(); Status = 0;
} }
public void CreateRecycleBin() public void CreateRecycleBin()
@@ -45,7 +45,7 @@ namespace ModernKeePassApp.Test.Mock
public void Open(CompositeKey key, bool createNew) public void Open(CompositeKey key, bool createNew)
{ {
throw new NotImplementedException(); Status = 2;
} }
public void Save() public void Save()

View File

@@ -1,5 +1,7 @@
using System.Linq; using System;
using System.Linq;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.Storage.AccessCache;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
using ModernKeePassApp.Test.Mock; using ModernKeePassApp.Test.Mock;
@@ -28,13 +30,74 @@ namespace ModernKeePassApp.Test
database.Status = 1; database.Status = 1;
mainVm = new MainVm(null, null, database); mainVm = new MainVm(null, null, database);
Assert.IsNotNull(mainVm.SelectedItem); Assert.IsNotNull(mainVm.SelectedItem);
Assert.AreEqual("Open", ((MainMenuItemVm)mainVm.SelectedItem).Title); Assert.AreEqual("Open", ((MainMenuItemVm) mainVm.SelectedItem).Title);
database.Status = 2; database.Status = 2;
mainVm = new MainVm(null, null, database); mainVm = new MainVm(null, null, database);
Assert.IsNotNull(mainVm.SelectedItem); Assert.IsNotNull(mainVm.SelectedItem);
Assert.AreEqual(2, mainVm.MainMenuItems.Count()); Assert.AreEqual(2, mainVm.MainMenuItems.Count());
Assert.AreEqual("Save", ((MainMenuItemVm)mainVm.SelectedItem).Title); Assert.AreEqual("Save", ((MainMenuItemVm) mainVm.SelectedItem).Title);
}
[TestMethod]
public void TestCompositeKeyVm()
{
var database = new DatabaseHelperMock();
var compositeKeyVm = new CompositeKeyVm(database);
Assert.IsTrue(compositeKeyVm.OpenDatabase(false).GetAwaiter().GetResult());
compositeKeyVm.StatusType = 1;
compositeKeyVm.Password = "test";
Assert.AreEqual(0, compositeKeyVm.StatusType);
Assert.AreEqual(15.0, compositeKeyVm.PasswordComplexityIndicator);
}
[TestMethod]
public void TestOpenVm()
{
var database = new DatabaseHelperMock
{
Status = 1,
DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx")
.GetAwaiter().GetResult()
};
var openVm = new OpenVm(database);
Assert.IsTrue(openVm.ShowPasswordBox);
Assert.AreEqual("MockDatabase", openVm.Name);
}
/*[TestMethod]
public void TestNewVm()
{
}*/
[TestMethod]
public void TestRecentVm()
{
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
mru.Add(Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx")
.GetAwaiter().GetResult(), "MockDatabase");
var recentVm = new RecentVm();
Assert.IsTrue(recentVm.RecentItems.Count == 1);
recentVm.SelectedItem = recentVm.RecentItems.FirstOrDefault();
Assert.IsTrue(recentVm.SelectedItem.IsSelected);
mru.Clear();
}
/*[TestMethod]
public void TestSaveVm()
{
}*/
[TestMethod]
public void TestSettingsVm()
{
var settingsVm = new SettingsVm();
Assert.AreEqual(1, settingsVm.MenuItems.Count());
var firstGroup = settingsVm.MenuItems.FirstOrDefault();
Assert.AreEqual(2, firstGroup.Count());
Assert.IsNotNull(settingsVm.SelectedItem);
var selectedItem = (ListMenuItemVm) settingsVm.SelectedItem;
Assert.AreEqual("General", selectedItem.Title);
} }
} }
} }