diff --git a/HashingTool/App.xaml b/HashingTool/App.xaml index 8a1682141b6d8f7f0c4aa2abac0dee08a1d17e54..422c404afc0fed859e81a05023da91775028de36 100644 --- a/HashingTool/App.xaml +++ b/HashingTool/App.xaml @@ -1,8 +1,7 @@ <Application x:Class="HashingTool.App" - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - StartupUri="MainWindow.xaml"> - <Application.Resources> - - </Application.Resources> -</Application> + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> + <Application.Resources> + + </Application.Resources> +</Application> \ No newline at end of file diff --git a/HashingTool/App.xaml.cs b/HashingTool/App.xaml.cs index ac4ef4df381270703d7247843151fc1517f269db..543823a96fa610f8a6f2dfacb2468268529d98ab 100644 --- a/HashingTool/App.xaml.cs +++ b/HashingTool/App.xaml.cs @@ -41,14 +41,14 @@ namespace HashingTool /// </summary> public partial class App : Application { - //protected override void OnStartup(StartupEventArgs e) - //{ - // base.OnStartup(e); + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); - // var app = new MainWindow(); - // var context = new MainWindowViewModel(); - // app.DataContext = context; - // //app.Show(); - //} + var app = new MainWindow(); + var context = new ApplicationViewModel(); + app.DataContext = context; + app.Show(); + } } } diff --git a/HashingTool/HashingTool.csproj b/HashingTool/HashingTool.csproj index 787c6eb5c3894af8ba2009a61c4a89bbf26acb4c..7e8a498dbae3f94dce1afdc96d5ea665847d9c82 100644 --- a/HashingTool/HashingTool.csproj +++ b/HashingTool/HashingTool.csproj @@ -63,6 +63,8 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </ApplicationDefinition> + <Compile Include="Helper\BoolViewConverter.cs" /> + <Compile Include="Helper\IOService.cs" /> <Compile Include="Model\TestModel.cs" /> <Compile Include="Properties\Annotations.cs" /> <Compile Include="Properties\Version.cs"> @@ -77,6 +79,7 @@ <Compile Include="ViewModel\RelayCommand.cs" /> <Compile Include="ViewModel\HashComponentDataViewModel.cs" /> <Compile Include="ViewModel\VerifyInputDataViewModel.cs" /> + <Compile Include="ViewModel\XMLValidator.cs" /> <Compile Include="Views\HashComponentData.xaml.cs"> <DependentUpon>HashComponentData.xaml</DependentUpon> </Compile> @@ -145,6 +148,16 @@ <ItemGroup> <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" /> </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\VectoCommon\VectoHashing\VectoHashing.csproj"> + <Project>{B673E12F-D323-4C4C-8805-9915B2C72D3D}</Project> + <Name>VectoHashing</Name> + </ProjectReference> + <ProjectReference Include="..\VectoCore\VectoCore\VectoCore.csproj"> + <Project>{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}</Project> + <Name>VectoCore</Name> + </ProjectReference> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.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. diff --git a/HashingTool/MainWindow.xaml b/HashingTool/MainWindow.xaml index 6a0fc6c7d14a103c6f90db1567fbadda5df8fe63..a729040bad1c4f78ea9f6a2e6fe8b6065e4d2c71 100644 --- a/HashingTool/MainWindow.xaml +++ b/HashingTool/MainWindow.xaml @@ -4,7 +4,7 @@ xmlns:viewModel="clr-namespace:HashingTool.ViewModel" xmlns:views="clr-namespace:HashingTool.Views" x:Class="HashingTool.MainWindow" - Title="VECTO Hashing Tool" Height="243" Width="593"> + Title="VECTO Hashing Tool" Height="534" Width="665" ResizeMode="NoResize"> <Window.DataContext> <viewModel:ApplicationViewModel /> </Window.DataContext> @@ -18,11 +18,11 @@ <DataTemplate DataType="{x:Type viewModel:VerifyInputDataViewModel}"> <views:VerifyInputData /> </DataTemplate> - + </Window.Resources> <Grid Margin="10"> - - <ContentControl Content="{Binding CurrentViewModel}" /> - + + <ContentControl Content="{Binding CurrentViewModel}" /> + </Grid> </Window> \ No newline at end of file diff --git a/HashingTool/ViewModel/ApplicationViewModel.cs b/HashingTool/ViewModel/ApplicationViewModel.cs index a41df8218b5d8159f2e1f852e37c3cc4c4dafa01..01dae9915c8d99e37d6f3ad3b6a9f31a47c202a8 100644 --- a/HashingTool/ViewModel/ApplicationViewModel.cs +++ b/HashingTool/ViewModel/ApplicationViewModel.cs @@ -14,7 +14,7 @@ namespace HashingTool.ViewModel private IMainView _currentView; public static List<IMainView> AvailableViews; - + public ApplicationViewModel() { diff --git a/HashingTool/ViewModel/HashComponentDataViewModel.cs b/HashingTool/ViewModel/HashComponentDataViewModel.cs index cf51082babe5d5fc944f8f2a3d659797afa1ee18..0b84ba4644ab92ebc87f68d6a78615ddecff1016 100644 --- a/HashingTool/ViewModel/HashComponentDataViewModel.cs +++ b/HashingTool/ViewModel/HashComponentDataViewModel.cs @@ -1,17 +1,43 @@ using System; -using System.ComponentModel; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Windows; using System.Windows.Input; -using HashingTool.Model; +using System.Xml; +using System.Xml.Linq; +using System.Xml.Schema; +using HashingTool.Helper; +using TUGraz.VectoCore.Utils; +using TUGraz.VectoHashing; namespace HashingTool.ViewModel { public class HashComponentDataViewModel : ObservableObject, IMainView { private readonly ApplicationViewModel _applicationViewModel; + private bool? _componentDataValid; + private string _digestValue; + //private ObservableCollection<string> _xmlValidationErrors = new ObservableCollection<string>(); + private Stream _stream; + private XDocument _result; - public HashComponentDataViewModel() {} + private IOService _ioService = new WPFIoService(); + private RelayCommand _saveCommand; + private bool _busy; + private string _source; - public HashComponentDataViewModel(ApplicationViewModel applicationViewModel) + public HashComponentDataViewModel() + { + XMLValidationErrors = new ObservableCollection<string>(); + _saveCommand = new RelayCommand(SaveDocument, + () => !_busy && ComponentDataValid != null && ComponentDataValid.Value && _result != null); + _busy = false; + } + + public HashComponentDataViewModel(ApplicationViewModel applicationViewModel) : this() { _applicationViewModel = applicationViewModel; } @@ -25,5 +51,135 @@ namespace HashingTool.ViewModel { get { return ApplicationViewModel.HomeView; } } + + public string Source + { + get { return _source; } + private set { + if (_source == value) { + return; + } + _source = value; + RaisePropertyChanged("Source"); + } + } + + public bool? ComponentDataValid + { + get { return _componentDataValid; } + private set { + if (_componentDataValid == value) { + return; + } + _componentDataValid = value; + RaisePropertyChanged("ComponentDataValid"); + } + } + + public ObservableCollection<string> XMLValidationErrors { get; set; } + //{ + // get { return _xmlValidationErrors; } + // private set { + // _xmlValidationErrors = value; + // RaisePropertyChanged("XMLValidationErrors"); + // } + //} + + public string DigestValue + { + get { return _digestValue; } + set { + if (_digestValue == value) { + return; + } + _digestValue = value; + RaisePropertyChanged("DigestValue"); + } + } + + public ICommand SetComponentData + { + get { return new RelayCommand(HashComponentData, () => !_busy); } + } + + public ICommand SaveHashedDocument + { + get { return _saveCommand; } + } + + private void SaveDocument() + { + string filename; + var stream = _ioService.SaveData(null, ".xml", "VECTO XML file|*.xml", out filename); + if (stream == null) { + return; + } + using (var writer = new XmlTextWriter(stream, Encoding.UTF8) { + Formatting = Formatting.Indented, + Indentation = 4 + }) { + _result.WriteTo(writer); + writer.Flush(); + writer.Close(); + } + } + + private void HashComponentData() + { + string filename; + + var xml = _ioService.OpenFileDialog(null, ".xml", "VECTO XML file|*.xml", out filename); + if (xml == null) { + return; + } + + _busy = true; + ComponentDataValid = null; + XMLValidationErrors.Clear(); + DigestValue = ""; + Source = filename; + _stream = xml; + DoComputeHash(); + } + + private async void DoComputeHash() + { + try { + var h = VectoHash.Load(_stream); + + _result = h.AddHash(); + + using (MemoryStream ms = new MemoryStream()) { + using (XmlWriter xw = XmlWriter.Create(ms, new XmlWriterSettings { Indent = true })) { + _result.WriteTo(xw); + xw.Flush(); + } + ms.Flush(); + ms.Seek(0, SeekOrigin.Begin); + ComponentDataValid = true; + var validator = new XMLValidator(r => { ComponentDataValid = r; }, + (s, e) => { + Application.Current.Dispatcher.Invoke(() => XMLValidationErrors.Add( + string.Format("Validation {0} Line {2}: {1}", s == XmlSeverityType.Warning ? "WARNING" : "ERROR", + e.ValidationEventArgs == null + ? e.Exception.Message + + (e.Exception.InnerException != null ? Environment.NewLine + e.Exception.InnerException.Message : "") + : e.ValidationEventArgs.Message, + e.ValidationEventArgs == null ? 0 : e.ValidationEventArgs.Exception.LineNumber))); + }); + await validator.ValidateXML(ms); + } + if (ComponentDataValid != null && ComponentDataValid.Value) { + DigestValue = h.ComputeHash(); + } + _saveCommand.RaiseCanExecuteChanged(); + } catch (Exception e) { + ComponentDataValid = false; + DigestValue = ""; + XMLValidationErrors.Add(e.Message); + } finally { + _busy = false; + } + } } } diff --git a/HashingTool/ViewModel/RelayCommand.cs b/HashingTool/ViewModel/RelayCommand.cs index 75234d6b2cf99b19807c8be7c8bf5689b231d8ef..49df114bf52dd415f776f2750f58f3a92ea156d9 100644 --- a/HashingTool/ViewModel/RelayCommand.cs +++ b/HashingTool/ViewModel/RelayCommand.cs @@ -52,6 +52,12 @@ namespace HashingTool.ViewModel } } + public void RaiseCanExecuteChanged() + { + CommandManager.InvalidateRequerySuggested(); + } + + [DebuggerStepThrough] public Boolean CanExecute(Object parameter) { @@ -112,6 +118,11 @@ namespace HashingTool.ViewModel } } + public void RaiseCanExecuteChanged() + { + CommandManager.InvalidateRequerySuggested(); + } + [DebuggerStepThrough] public Boolean CanExecute(Object parameter) { diff --git a/HashingTool/Views/HashComponentData.xaml b/HashingTool/Views/HashComponentData.xaml index 76126261a069ed11193178c751fe15bec58670af..52cfc9a696c24de92c4af39fb03eedafb310b3f6 100644 --- a/HashingTool/Views/HashComponentData.xaml +++ b/HashingTool/Views/HashComponentData.xaml @@ -3,16 +3,31 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:ViewModel="clr-namespace:HashingTool.ViewModel" x:Class="HashingTool.Views.HashComponentData" + xmlns:ViewModel="clr-namespace:HashingTool.ViewModel" xmlns:Helper="clr-namespace:HashingTool.Helper" + x:Class="HashingTool.Views.HashComponentData" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300"> + d:DesignHeight="501.425" d:DesignWidth="548"> + <UserControl.Resources> + <Helper:BoolViewConverter x:Key="BoolViewConverter" /> + </UserControl.Resources> <UserControl.DataContext> <ViewModel:HashComponentDataViewModel /> </UserControl.DataContext> <Grid> - <Label HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" - Content="{Binding Name}" /> - <Button Content="Home" Command="{Binding ShowHomeViewCommand}" HorizontalAlignment="Left" Margin="201,194,0,0" VerticalAlignment="Top" Width="75"/> + <Label HorizontalAlignment="Center" Margin="10,10,0,0" VerticalAlignment="Top" + Content="{Binding Name}" FontWeight="Bold" FontSize="18" /> + <Button Content="Back" Command="{Binding ShowHomeViewCommand}" Margin="0,0,10,10" HorizontalAlignment="Right" + Width="75" Height="22" VerticalAlignment="Bottom" /> + <Button x:Name="btSelectComponentFile" Content="Browse ..." HorizontalAlignment="Left" Margin="300,79,0,0" + VerticalAlignment="Top" Width="75" Command="{Binding SetComponentData, Mode=OneWay}" /> + <TextBox x:Name="tbComponentFile" HorizontalAlignment="Left" Height="23" Margin="10,79,0,0" TextWrapping="Wrap" + VerticalAlignment="Top" Width="285" IsReadOnly="True" Text="{Binding Source, Mode=OneWay}" /> + <Label Content="{Binding ComponentDataValid, Converter={StaticResource BoolViewConverter}, Mode=OneWay}" + HorizontalAlignment="Left" Margin="10,141,0,0" VerticalAlignment="Top" Height="26" Width="154" /> + <Label Content="{Binding DigestValue}" HorizontalAlignment="Left" Margin="10,172,0,0" VerticalAlignment="Top" /> + <Button Content="Save" HorizontalAlignment="Right" Margin="0,0,90,10" Width="75" Height="22" + VerticalAlignment="Bottom" Command="{Binding SaveHashedDocument, Mode=OneWay}" /> + <ListBox HorizontalAlignment="Left" Height="214" Margin="71,230,0,0" VerticalAlignment="Top" Width="436" IsSynchronizedWithCurrentItem="False" ItemsSource="{Binding XMLValidationErrors}"/> </Grid> </UserControl> \ No newline at end of file diff --git a/HashingTool/Views/HashComponentData.xaml.cs b/HashingTool/Views/HashComponentData.xaml.cs index 74cb5248f5a3619c9f0ea9f64a9a44fe6d909868..290f80a68ff961623e99bf94bcef156fec4ff777 100644 --- a/HashingTool/Views/HashComponentData.xaml.cs +++ b/HashingTool/Views/HashComponentData.xaml.cs @@ -1,17 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using HashingTool.ViewModel; +using Microsoft.Win32; namespace HashingTool.Views { diff --git a/HashingTool/Views/HomeView.xaml b/HashingTool/Views/HomeView.xaml index 8509787982679b777cce800df80d0ee199b1ebdf..9b95c8bd72f4611a5c2dbebfd7fa9ee4727e43ac 100644 --- a/HashingTool/Views/HomeView.xaml +++ b/HashingTool/Views/HomeView.xaml @@ -1,26 +1,33 @@ <UserControl - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:viewModel="clr-namespace:HashingTool.ViewModel" x:Class="HashingTool.Views.HomeView" - mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300"> + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:viewModel="clr-namespace:HashingTool.ViewModel" x:Class="HashingTool.Views.HomeView" + mc:Ignorable="d" + d:DesignHeight="300" d:DesignWidth="300"> - <Grid> + <Grid x:Name="MainGrid"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="*" /> + </Grid.ColumnDefinitions> <Grid.DataContext> - <viewModel:HomeViewModel/> + <viewModel:HomeViewModel /> </Grid.DataContext> - <ItemsControl ItemsSource="{Binding MainViewModels}"> + <ItemsControl x:Name="ViewSelectionPanel" + ItemsSource="{Binding MainViewModels}" + Grid.Column="1"> <ItemsControl.ItemTemplate> <DataTemplate> - <Grid Margin="0,0,0,5"> - <Button Content="{Binding Name}" Margin="2,5" - Command="{Binding DataContext.ChangeViewCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" - CommandParameter="{Binding ''}" /> + <Grid Margin="0,30,0,5"> + <Button Content="{Binding Name}" Margin="2,5" Padding="15,10" + Command="{Binding DataContext.ChangeViewCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" + CommandParameter="{Binding ''}" /> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> -</UserControl> +</UserControl> \ No newline at end of file diff --git a/VECTO.sln.DotSettings b/VECTO.sln.DotSettings index 63179ca8314c9ff7e13fb4d58810a6d369ee0ba9..9ba0cdb648e793db7669b1480fe38451845d0fda 100644 --- a/VECTO.sln.DotSettings +++ b/VECTO.sln.DotSettings @@ -1,4 +1,5 @@ <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> + <s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=HashingTool_002EAnnotations/@EntryIndexedValue">True</s:Boolean> <s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">Default: Reformat Code</s:String> <s:String x:Key="/Default/CodeStyle/CodeFormatting/CommonFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">USE_TABS_ONLY</s:String> <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>