History list fully functional in Entry page

Viewing a historic entry disables controls on the page
Enhancements in the hamburger menu
This commit is contained in:
BONNEVILLE Geoffroy
2018-06-15 18:07:44 +02:00
parent 62c9719a77
commit 7e337c4a40
14 changed files with 101 additions and 63 deletions

View File

@@ -1,6 +1,7 @@
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace ModernKeePass.Controls
{
@@ -43,6 +44,17 @@ namespace ModernKeePass.Controls
typeof(TextBoxWithButton),
new PropertyMetadata(true, (o, args) => { }));
public FlyoutBase ButtonFlyout
{
get { return (FlyoutBase)GetValue(ButtonFlyoutProperty); }
set { SetValue(ButtonFlyoutProperty, value); }
}
public static readonly DependencyProperty ButtonFlyoutProperty =
DependencyProperty.Register(
"ButtonFlyout",
typeof(FlyoutBase),
typeof(TextBoxWithButton),
new PropertyMetadata(null, (o, args) => { }));
protected override void OnApplyTemplate()
{

View File

@@ -123,7 +123,6 @@
<Compile Include="Interfaces\IResourceService.cs" />
<Compile Include="Services\SingletonServiceBase.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\HistoryVm.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
<DependentUpon>DonatePage.xaml</DependentUpon>

View File

@@ -267,4 +267,7 @@
<data name="RecycleBinTitle" xml:space="preserve">
<value>Recycle Bin</value>
</data>
<data name="EntryCurrent" xml:space="preserve">
<value>Current</value>
</data>
</root>

View File

@@ -267,4 +267,7 @@
<data name="RecycleBinTitle" xml:space="preserve">
<value>Corbeille</value>
</data>
<data name="EntryCurrent" xml:space="preserve">
<value>Courante</value>
</data>
</root>

View File

@@ -16,13 +16,13 @@
<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

@@ -246,6 +246,9 @@
Content="{TemplateBinding ButtonSymbol}"
IsEnabled="{TemplateBinding IsButtonEnabled}"
VerticalAlignment="Stretch">
<Button.Flyout>
<Flyout Content="{TemplateBinding ButtonFlyout}" />
</Button.Flyout>
<ToolTipService.ToolTip>
<ToolTip Content="{TemplateBinding ButtonTooltip}" />
</ToolTipService.ToolTip>

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePassLib;
@@ -10,7 +11,7 @@ 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; }
@@ -19,7 +20,6 @@ namespace ModernKeePass.ViewModels
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 bool UpperCasePatternSelected { get; set; } = true;
public bool LowerCasePatternSelected { get; set; } = true;
public bool DigitsPatternSelected { get; set; } = true;
@@ -33,6 +33,10 @@ namespace ModernKeePass.ViewModels
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
{
@@ -73,6 +77,7 @@ namespace ModernKeePass.ViewModels
get { return GetEntryValue(PwDefs.UrlField); }
set { SetEntryValue(PwDefs.UrlField, value); }
}
public string Notes
{
get { return GetEntryValue(PwDefs.NotesField); }
@@ -102,7 +107,7 @@ namespace ModernKeePass.ViewModels
public bool IsEditMode
{
get { return _isEditMode; }
get { return IsSelected && _isEditMode; }
set
{
_isEditMode = value;
@@ -143,10 +148,13 @@ namespace ModernKeePass.ViewModels
{
get
{
var history = new List<EntryVm> {this};
foreach (var historyEntry in _pwEntry.History)
{
yield return new EntryVm(historyEntry, ParentGroup);
history.Add(new EntryVm(historyEntry, ParentGroup) {IsSelected = false});
}
return history;
}
}
@@ -154,6 +162,7 @@ namespace ModernKeePass.ViewModels
private readonly PwEntry _pwEntry;
private readonly IDatabaseService _database;
private readonly IResourceService _resource;
private bool _isEditMode;
private bool _isRevealPassword;
private double _passwordLength = 25;
@@ -166,11 +175,12 @@ namespace ModernKeePass.ViewModels
public EntryVm() { }
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance) { }
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance, new ResourcesService()) { }
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database)
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database, IResourceService resource)
{
_database = database;
_resource = resource;
_pwEntry = entry;
ParentGroup = parent;
}
@@ -254,5 +264,10 @@ namespace ModernKeePass.ViewModels
{
return _pwEntry;
}
public override string ToString()
{
return IsSelected ? _resource.GetResourceValue("EntryCurrent") : _pwEntry.LastModificationTime.ToString("g");
}
}
}

View File

@@ -45,6 +45,7 @@ namespace ModernKeePass.ViewModels
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !IsSelected && !ParentGroup.IsSelected;
/// <summary>
/// Is the Group the database Recycle Bin?
/// </summary>

View File

@@ -1,19 +0,0 @@
using System.Collections.Generic;
using ModernKeePass.Interfaces;
namespace ModernKeePass.ViewModels
{
public class HistoryVm: IHasSelectableObject
{
public IEnumerable<IPwEntity> History { get; }
public HistoryVm() { }
public HistoryVm(IEnumerable<IPwEntity> history)
{
History = history;
}
public ISelectableModel SelectedItem { get; set; }
}
}

View File

@@ -429,13 +429,13 @@
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<userControls:HamburgerMenuUserControl x:Uid="HistoryLeftListView" ItemsSource="{Binding History}" ResizeTarget="{Binding ElementName=LeftListViewColumn}" />
<StackPanel Grid.Column="1" Margin="20,0,0,0" >
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<userControls:HamburgerMenuUserControl x:Name="HamburgerMenu" x:Uid="HistoryLeftListView" ItemsSource="{Binding History}" ResizeTarget="{Binding ElementName=LeftListViewColumn}" SelectionChanged="HamburgerMenuUserControl_OnSelectionChanged" />
<StackPanel x:Name="StackPanel" Grid.Column="1" Margin="20,0,0,0">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0,20,0,0"/>
@@ -444,17 +444,17 @@
<Setter Property="Margin" Value="0,20,0,0"/>
</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" TextWrapping="Wrap" FontSize="18" />
<local:TextBoxWithButton HorizontalAlignment="Left" Text="{Binding UserName, Mode=TwoWay}" Width="350" Height="32" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE16F;" ButtonTooltip="Copy" IsEnabled="{Binding IsSelected}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick">
<actions:ClipboardAction Text="{Binding UserName}" />
</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" 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}" IsEnabled="{Binding IsSelected}" />
<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" IsEnabled="{Binding IsSelected}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick">
<actions:ClipboardAction Text="{Binding Password}" />
@@ -464,7 +464,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}}" />
<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 HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE111;" ButtonTooltip="Navigate to URL">
<local:TextBoxWithButton HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="&#xE111;" ButtonTooltip="Navigate to URL" IsEnabled="{Binding IsSelected}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ButtonClick">
<actions:NavigateToUrlAction Url="{Binding Url}" />
@@ -472,8 +472,8 @@
</interactivity:Interaction.Behaviors>
</local:TextBoxWithButton>
<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}" />
<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" FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />

View File

@@ -97,5 +97,21 @@ namespace ModernKeePass.Views
{
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
}
private void HamburgerMenuUserControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listView = sender as ListView;
EntryVm entry;
switch (listView?.SelectedIndex)
{
case -1:
return;
default:
entry = listView?.SelectedItem as EntryVm;
break;
}
StackPanel.DataContext = entry;
}
}
}

View File

@@ -116,7 +116,7 @@
<ColumnDefinition Width="50" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<userControls:HamburgerMenuUserControl x:Uid="GroupsLeftListView" ItemsSource="{Binding Groups}" DisplayMemberPath="Name" SelectionChanged="groups_SelectionChanged" ButtonClicked="CreateGroup_ButtonClick" ResizeTarget="{Binding ElementName=LeftListViewColumn}" IsButtonVisible="{Binding IsSelected}" />
<userControls:HamburgerMenuUserControl x:Uid="GroupsLeftListView" ItemsSource="{Binding Groups}" SelectionChanged="groups_SelectionChanged" ButtonClicked="CreateGroup_ButtonClick" ResizeTarget="{Binding ElementName=LeftListViewColumn}" IsButtonVisible="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" />
<TextBlock Grid.Column="1" x:Uid="ReorderEntriesLabel" Margin="20,20,0,0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource BodyTextBlockStyle}" />
<HyperlinkButton Grid.Column="1" VerticalAlignment="Top" Margin="40,10,0,0" Click="CreateEntry_ButtonClick" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" HorizontalAlignment="Right" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}">
<StackPanel Orientation="Horizontal">

View File

@@ -10,21 +10,22 @@
xmlns:converters="using:ModernKeePass.Converters"
mc:Ignorable="d">
<UserControl.Resources>
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
<converters:IntToSymbolConverter x:Key="IntToSymbolConverter"/>
</UserControl.Resources>
<ListView
ItemsSource="{Binding ItemsSource, ElementName=UserControl}"
SelectionChanged="Selector_OnSelectionChanged"
SelectedItem="{Binding SelectedItem, ElementName=UserControl}"
IsSwipeEnabled="false"
IsSynchronizedWithCurrentItem="False"
RequestedTheme="Dark"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}">
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
<ListView.Resources>
<DataTemplate x:Name="IsSpecial">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Margin="8,0,0,0">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Margin="3,0,0,0">
<ToolTipService.ToolTip>
<ToolTip Content="{Binding Path={Binding DisplayMemberPath, ElementName=UserControl}}" />
</ToolTipService.ToolTip>
@@ -34,7 +35,7 @@
</DataTemplate>
<DataTemplate x:Name="IsNormal">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Margin="8,0,0,0">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Margin="3,0,0,0">
<ToolTipService.ToolTip>
<ToolTip Content="{Binding Path={Binding DisplayMemberPath, ElementName=UserControl}}" />
</ToolTipService.ToolTip>
@@ -46,14 +47,6 @@
<ListView.ItemTemplateSelector>
<templateSelectors:SelectableDataTemplateSelector FalseItem="{StaticResource IsNormal}" TrueItem="{StaticResource IsSpecial}" />
</ListView.ItemTemplateSelector>
<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>
<StackPanel Orientation="Horizontal">
@@ -76,7 +69,7 @@
</ListView.HeaderTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Visibility="{Binding IsButtonVisible, ElementName=UserControl, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<StackPanel Orientation="Vertical" Visibility="{Binding IsButtonVisible, ElementName=UserControl}">
<Border BorderBrush="White" BorderThickness="0,0,0,1" />
<Button Padding="0" Height="50" Margin="0" Style="{StaticResource NoBorderButtonStyle}" Background="Transparent" BorderThickness="0" Click="ButtonBase_OnClick">
<StackPanel Orientation="Horizontal" Margin="13,0,5,0">

View File

@@ -48,7 +48,7 @@ namespace ModernKeePass.Views.UserControls
"DisplayMemberPath",
typeof(string),
typeof(HamburgerMenuUserControl),
new PropertyMetadata("Name", (o, args) => { }));
new PropertyMetadata("Title", (o, args) => { }));
public object ResizeTarget
{
@@ -62,17 +62,17 @@ namespace ModernKeePass.Views.UserControls
typeof(HamburgerMenuUserControl),
new PropertyMetadata(null, (o, args) => { }));
public bool IsButtonVisible
public Visibility IsButtonVisible
{
get { return (bool)GetValue(IsButtonVisibleProperty); }
get { return (Visibility)GetValue(IsButtonVisibleProperty); }
set { SetValue(IsButtonVisibleProperty, value); }
}
public static readonly DependencyProperty IsButtonVisibleProperty =
DependencyProperty.Register(
"IsButtonVisible",
typeof(bool),
typeof(Visibility),
typeof(HamburgerMenuUserControl),
new PropertyMetadata(false, (o, args) => { }));
new PropertyMetadata(Visibility.Collapsed, (o, args) => { }));
public IEnumerable<IPwEntity> ItemsSource
{
@@ -87,6 +87,18 @@ namespace ModernKeePass.Views.UserControls
typeof(HamburgerMenuUserControl),
new PropertyMetadata(new List<IPwEntity>(), (o, args) => { }));
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
"SelectedItem",
typeof(object),
typeof(HamburgerMenuUserControl),
new PropertyMetadata(null, (o, args) => { }));
public event SelectionChangedEventHandler SelectionChanged;
public delegate void SelectionChangedEventHandler(object sender, SelectionChangedEventArgs e);
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)