StarSim

StarSim.git
git clone git://git.lenczewski.org/StarSim.git
Log | Files | Refs | README | LICENSE

commit f08c32a6832ec37a5e3538cb75ce97b6b3949b1f
parent 2c26316ba6a9f6d475f7cf92d55bd74c0d2e9d78
Author: Mikolaj Lenczewski <33129490+EnderRifter@users.noreply.github.com>
Date:   Sun, 18 Aug 2019 21:56:17 +0200

All base coursework goals completed:
 - Finished implementing CRUD functionality.

Diffstat:
AStarSim/StarSimGui/Source/Comparers/BodyToSystemJoinComparer.cs | 29+++++++++++++++++++++++++++++
MStarSim/StarSimGui/StarSimGui.csproj | 2+-
MStarSim/StarSimGui/ViewModels/Database ViewModels/CreateSystemsViewModel.cs | 4++--
MStarSim/StarSimGui/ViewModels/Database ViewModels/CreateUsersViewModel.cs | 24++++++++----------------
MStarSim/StarSimGui/ViewModels/Database ViewModels/UpdateSystemsViewModel.cs | 437+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MStarSim/StarSimGui/ViewModels/Database ViewModels/UpdateUsersViewModel.cs | 267+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MStarSim/StarSimGui/Views/Database Views/CreateUsers.xaml | 2+-
MStarSim/StarSimGui/Views/Database Views/UpdateSystems.xaml | 42+++++++++++++++++++++++++++++++++++++++++-
MStarSim/StarSimGui/Views/Database Views/UpdateUsers.xaml | 21+++++++++++++++++++++
MStarSim/StarSimLib/Constants.cs | 9+++++++++
MStarSim/StarSimLib/StarSimLib.xml | 5+++++
11 files changed, 821 insertions(+), 21 deletions(-)

diff --git a/StarSim/StarSimGui/Source/Comparers/BodyToSystemJoinComparer.cs b/StarSim/StarSimGui/Source/Comparers/BodyToSystemJoinComparer.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using StarSimLib.Models; + +namespace StarSimGui.Source.Comparers +{ + /// <summary> + /// Provides methods to compare two <see cref="BodyToSystemJoin"/> instances for equality. + /// </summary> + public class BodyToSystemJoinComparer : IEqualityComparer<BodyToSystemJoin> + { + /// <inheritdoc /> + public bool Equals(BodyToSystemJoin x, BodyToSystemJoin y) + { + if (x == null || y == null) + { + return false; + } + + return x.Id == y.Id && x.BodyId == y.BodyId && x.SystemId == y.SystemId; + } + + /// <inheritdoc /> + public int GetHashCode(BodyToSystemJoin obj) + { + return obj.GetHashCode(); + } + } +} +\ No newline at end of file diff --git a/StarSim/StarSimGui/StarSimGui.csproj b/StarSim/StarSimGui/StarSimGui.csproj @@ -162,7 +162,7 @@ <Generator>MSBuild:Compile</Generator> </None> <None Update="Simulator.db"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> <None Update="Views\MainWindow.xaml"> <Generator>MSBuild:Compile</Generator> diff --git a/StarSim/StarSimGui/ViewModels/Database ViewModels/CreateSystemsViewModel.cs b/StarSim/StarSimGui/ViewModels/Database ViewModels/CreateSystemsViewModel.cs @@ -145,9 +145,9 @@ namespace StarSimGui.ViewModels.Database_ViewModels /// </summary> private void ResetBodyCommandImpl() { - BodyName = ""; + BodyName = string.Empty; BodyMass = 0; - Feedback = ""; + Feedback = string.Empty; this.RaisePropertyChanged(nameof(Feedback)); } diff --git a/StarSim/StarSimGui/ViewModels/Database ViewModels/CreateUsersViewModel.cs b/StarSim/StarSimGui/ViewModels/Database ViewModels/CreateUsersViewModel.cs @@ -4,6 +4,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Windows.Input; using ReactiveUI; +using StarSimLib; using StarSimLib.Contexts; using StarSimLib.Cryptography; using StarSimLib.Models; @@ -41,15 +42,6 @@ namespace StarSimGui.ViewModels.Database_ViewModels private string username; /// <summary> - /// The list of accepted email providers. - /// </summary> - public static readonly string[] AcceptedEmailProviders = { - "gmail.com", - "hotmail.com", - "yahoo.com" - }; - - /// <summary> /// Initialises a new instance of the <see cref="CreateUsersViewModel"/> class. /// </summary> public CreateUsersViewModel() @@ -60,11 +52,11 @@ namespace StarSimGui.ViewModels.Database_ViewModels StringBuilder regexBuilder = new StringBuilder(@"\w[^@]@("); - for (int i = 0; i < AcceptedEmailProviders.Length; i++) + for (int i = 0; i < Constants.AcceptedEmailProviders.Length; i++) { regexBuilder.Append(i == 0 - ? $"{AcceptedEmailProviders[i].Replace(".", @"\.")}" - : $"|{AcceptedEmailProviders[i].Replace(".", @"\.")}"); + ? $"{Constants.AcceptedEmailProviders[i].Replace(".", @"\.")}" + : $"|{Constants.AcceptedEmailProviders[i].Replace(".", @"\.")}"); } regexBuilder.Append(")$"); @@ -246,10 +238,10 @@ namespace StarSimGui.ViewModels.Database_ViewModels /// </summary> private void ResetUserCommandImpl() { - Username = ""; - Password = ""; - Email = ""; - Feedback = ""; + Username = string.Empty; + Password = string.Empty; + Email = string.Empty; + Feedback = string.Empty; this.RaisePropertyChanged(nameof(Feedback)); } diff --git a/StarSim/StarSimGui/ViewModels/Database ViewModels/UpdateSystemsViewModel.cs b/StarSim/StarSimGui/ViewModels/Database ViewModels/UpdateSystemsViewModel.cs @@ -1,5 +1,12 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Input; +using DynamicData.Binding; +using ReactiveUI; +using StarSimGui.Source.Comparers; using StarSimLib.Contexts; +using StarSimLib.Models; namespace StarSimGui.ViewModels.Database_ViewModels { @@ -9,15 +16,142 @@ namespace StarSimGui.ViewModels.Database_ViewModels public class UpdateSystemsViewModel : ViewModelBase { /// <summary> + /// Caches an <see cref="IEqualityComparer{T}"/> for <see cref="BodyToSystemJoin"/> instances. + /// </summary> + private static readonly BodyToSystemJoinComparer joinComparer = new BodyToSystemJoinComparer(); + + /// <summary> /// The program database. /// </summary> private readonly SimulatorContext dbContext; /// <summary> + /// Backing field for the <see cref="Bodies"/> property. + /// </summary> + private IObservableCollection<Body> bodies; + + /// <summary> + /// Backing field for the <see cref="BodyMass"/> property. + /// </summary> + private double bodyMass; + + /// <summary> + /// Backing field for the <see cref="BodyName"/> property; + /// </summary> + private string bodyName; + + /// <summary> + /// Backing field for the <see cref="BodyToAdd"/> property. + /// </summary> + private Body bodyToAdd; + + /// <summary> + /// Backing field for the <see cref="BodyToRemove"/> property. + /// </summary> + private BodyToSystemJoin bodyToRemove; + + /// <summary> + /// Backing field for the <see cref="SelectedBody"/> property. + /// </summary> + private Body selectedBody; + + /// <summary> + /// Backing field for the <see cref="SelectedSystem"/> property. + /// </summary> + private StarSimLib.Models.System selectedSystem; + + /// <summary> + /// Backing field for the <see cref="SelectedSystemBodies"/> property. + /// </summary> + private IObservableCollection<BodyToSystemJoin> selectedSystemBodies; + + /// <summary> + /// Backing field for the <see cref="Systems"/> property. + /// </summary> + private IObservableCollection<StarSimLib.Models.System> systems; + + /// <summary> /// Initialises a new instance of the <see cref="UpdateSystemsViewModel"/> class. /// </summary> public UpdateSystemsViewModel() { + bodies = new ObservableCollectionExtended<Body>(); + + systems = new ObservableCollectionExtended<StarSimLib.Models.System>(); + + selectedSystemBodies = new ObservableCollectionExtended<BodyToSystemJoin>(); + + IObservable<bool> canUpdateBody = this.WhenAnyValue(x => x.SelectedBody, x => x.BodyName, x => x.BodyMass, + (body, name, mass) => + { + if (body == null) + { + return false; + } + + if (body.Name == name && Math.Abs(body.Mass - mass) < 1) + { + return false; + } + + if (!string.IsNullOrEmpty(name) && !string.IsNullOrWhiteSpace(name)) + { + return true; + } + + return false; + }); + + UpdateBodyCommand = ReactiveCommand.Create(UpdateBodyCommandImpl, canUpdateBody); + + IObservable<bool> canUpdateSystem = + this.WhenAnyValue(x => x.SelectedSystem, x => x.SelectedSystemBodies, + (system, bodies) => + { + if (system == null || bodies == null) + { + return false; + } + + if (!system.BodyToSystemJoins.SequenceEqual(SelectedSystemBodies, joinComparer)) + { + return true; + } + + return false; + }); + + UpdateSystemCommand = ReactiveCommand.Create(UpdateSystemCommandImpl, canUpdateSystem); + + IObservable<bool> canAddBody = this.WhenAnyValue(x => x.SelectedSystem, x => x.BodyToAdd, + (system, body) => + { + if (system == null || body == null) + { + return false; + } + + return system.BodyToSystemJoins.All(join => join.BodyId != body.Id); + }); + + AddBodyToSystemCommand = ReactiveCommand.Create(AddBodyToSystemCommandImpl, canAddBody); + + IObservable<bool> canRemoveBody = this.WhenAnyValue(x => x.SelectedSystem, x => x.BodyToRemove, + (system, body) => + { + if (system == null || body == null) + { + return false; + } + + return true; + }); + + RemoveBodyFromSystemCommand = ReactiveCommand.Create(RemoveBodyFromSystemCommandImpl, canRemoveBody); + + ResetBodyCommand = ReactiveCommand.Create(ResetBodyCommandImpl); + + ResetSystemCommand = ReactiveCommand.Create(ResetSystemCommandImpl); } /// <summary> @@ -27,6 +161,10 @@ namespace StarSimGui.ViewModels.Database_ViewModels public UpdateSystemsViewModel(in SimulatorContext context) : this() { dbContext = context; + + Bodies.Load(dbContext.Bodies); + + Systems.Load(dbContext.Systems); } /// <summary> @@ -35,6 +173,222 @@ namespace StarSimGui.ViewModels.Database_ViewModels public event Action DatabaseEdited; /// <summary> + /// Command invoked whenever the user wants to add a body to the currently edited system. + /// </summary> + public ICommand AddBodyToSystemCommand { get; } + + /// <summary> + /// The users held in the database. + /// </summary> + public IObservableCollection<Body> Bodies + { + get + { + return bodies; + } + set + { + bodies = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Provides feedback about the changes made to the body database. + /// </summary> + public string BodyFeedback { get; private set; } + + /// <summary> + /// The mass of the body to update. + /// </summary> + public double BodyMass + { + get + { + return bodyMass; + } + set + { + bodyMass = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// The name of the body to update. + /// </summary> + public string BodyName + { + get + { + return bodyName; + } + set + { + bodyName = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// The body to add to the currently edited system. + /// </summary> + public Body BodyToAdd + { + get + { + return bodyToAdd; + } + set + { + bodyToAdd = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// The body to remove from the currently edited system. + /// </summary> + public BodyToSystemJoin BodyToRemove + { + get + { + return bodyToRemove; + } + set + { + bodyToRemove = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Command invoked whenever the user wants to remove a body from the currently edited system. + /// </summary> + public ICommand RemoveBodyFromSystemCommand { get; } + + /// <summary> + /// Command invoked whenever the user wants to deselect the currently selected body. + /// </summary> + public ICommand ResetBodyCommand { get; } + + /// <summary> + /// Command invoked whenever the user wants to deselect the currently selected system. + /// </summary> + public ICommand ResetSystemCommand { get; } + + /// <summary> + /// The currently selected body. + /// </summary> + public Body SelectedBody + { + get + { + return selectedBody; + } + set + { + selectedBody = value; + this.RaisePropertyChanged(); + + if (value != null) + { + BodyName = value.Name; + BodyMass = value.Mass; + } + } + } + + /// <summary> + /// The currently selected system. + /// </summary> + public StarSimLib.Models.System SelectedSystem + { + get + { + return selectedSystem; + } + set + { + selectedSystem = value; + this.RaisePropertyChanged(); + + if (value != null) + { + SelectedSystemBodies.Load(value.BodyToSystemJoins); + } + } + } + + /// <summary> + /// The body to system joins of the selected system's bodies. + /// </summary> + public IObservableCollection<BodyToSystemJoin> SelectedSystemBodies + { + get + { + return selectedSystemBodies; + } + set + { + selectedSystemBodies = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Provides feedback about the changes made to the system database. + /// </summary> + public string SystemFeedback { get; private set; } + + /// <summary> + /// The users held in the database. + /// </summary> + public IObservableCollection<StarSimLib.Models.System> Systems + { + get + { + return systems; + } + set + { + systems = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Command invoked whenever the user wants to update the currently selected body in the database. + /// </summary> + public ICommand UpdateBodyCommand { get; } + + /// <summary> + /// Command invoked whenever the user wants to update the currently selected system in the database. + /// </summary> + public ICommand UpdateSystemCommand { get; } + + /// <summary> + /// Invoked whenever the user wants to add a body to the currently edited system. + /// </summary> + private void AddBodyToSystemCommandImpl() + { + if (SelectedSystemBodies.All(join => join.BodyId != BodyToAdd.Id)) + { + BodyToSystemJoin lastJoin = dbContext.BodyToSystemJoins.OrderBy(join => join.Id).Last(); + + BodyToSystemJoin addedBodyJoin = new BodyToSystemJoin(lastJoin.Id + 1, BodyToAdd.Id, SelectedSystem.Id); + + SelectedSystemBodies.Add(addedBodyJoin); + this.RaisePropertyChanged(nameof(SelectedSystemBodies)); + } + else + { + SystemFeedback = "Could not add selected body to system, as it already exists there."; + this.RaisePropertyChanged(nameof(SystemFeedback)); + } + } + + /// <summary> /// Invokes the <see cref="DatabaseEdited"/> event. /// </summary> private void OnDatabaseEdited() @@ -43,10 +397,93 @@ namespace StarSimGui.ViewModels.Database_ViewModels } /// <summary> + /// Invoked whenever the user wants to remove a body from the currently edited system. + /// </summary> + private void RemoveBodyFromSystemCommandImpl() + { + SelectedSystemBodies.Remove(BodyToRemove); + } + + /// <summary> + /// Invoked whenever the user wants to deselect the currently selected body. + /// </summary> + private void ResetBodyCommandImpl() + { + SelectedBody = null; + } + + /// <summary> + /// Invoked whenever the user wants to deselect the currently selected system. + /// </summary> + private void ResetSystemCommandImpl() + { + SelectedSystem = null; + SelectedSystemBodies.Clear(); + } + + /// <summary> + /// Invoked whenever the user wants to update the currently selected body in the database. + /// </summary> + private void UpdateBodyCommandImpl() + { + try + { + Body editedBody = dbContext.Bodies.First(body => body.Id == SelectedBody.Id); + + editedBody.Name = BodyName; + editedBody.Mass = BodyMass; + + BodyFeedback = "Body was successfully updated."; + this.RaisePropertyChanged(nameof(BodyFeedback)); + + SelectedBody = null; + + OnDatabaseEdited(); + } + catch (Exception) + { + BodyFeedback = "Body could not be updated."; + this.RaisePropertyChanged(nameof(BodyFeedback)); + } + } + + /// <summary> + /// Invoked whenever the user wants to update the currently selected system in the database. + /// </summary> + private void UpdateSystemCommandImpl() + { + try + { + dbContext.Systems.First(system => system.Id == SelectedSystem.Id).BodyToSystemJoins = + SelectedSystemBodies.ToList(); + + SystemFeedback = "System was successfully updated."; + this.RaisePropertyChanged(nameof(SystemFeedback)); + + SelectedSystem = null; + SelectedSystemBodies.Clear(); + + OnDatabaseEdited(); + } + catch (Exception) + { + SystemFeedback = "System could not be updated."; + this.RaisePropertyChanged(nameof(SystemFeedback)); + } + } + + /// <summary> /// Refreshed the database sources for this view model. /// </summary> internal void HandleDatabaseRefresh() { + Bodies.Load(dbContext.Bodies); + Systems.Load(dbContext.Systems); + + if (SelectedSystem?.BodyToSystemJoins != null) + { + SelectedSystemBodies.Load(SelectedSystem.BodyToSystemJoins); + } } } } \ No newline at end of file diff --git a/StarSim/StarSimGui/ViewModels/Database ViewModels/UpdateUsersViewModel.cs b/StarSim/StarSimGui/ViewModels/Database ViewModels/UpdateUsersViewModel.cs @@ -1,5 +1,14 @@ using System; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Input; +using DynamicData.Binding; +using ReactiveUI; +using StarSimLib; using StarSimLib.Contexts; +using StarSimLib.Cryptography; +using StarSimLib.Models; namespace StarSimGui.ViewModels.Database_ViewModels { @@ -14,10 +23,93 @@ namespace StarSimGui.ViewModels.Database_ViewModels private readonly SimulatorContext dbContext; /// <summary> + /// Backing field for the <see cref="Email"/> property. + /// </summary> + private string email; + + /// <summary> + /// Backing field for the <see cref="Password"/> property. + /// </summary> + private string password; + + /// <summary> + /// Backing field for the <see cref="Privileges"/> property. + /// </summary> + private UserPrivileges privileges; + + /// <summary> + /// Backing field for the <see cref="SelectedUser"/> property. + /// </summary> + private User selectedUser; + + /// <summary> + /// Backing field for the <see cref="Username"/> property. + /// </summary> + private string username; + + /// <summary> + /// Backing field for the <see cref="Users"/> property. + /// </summary> + private IObservableCollection<User> users; + + /// <summary> /// Initialises a new instance of the <see cref="UpdateUsersViewModel"/> class. /// </summary> public UpdateUsersViewModel() { + users = new ObservableCollectionExtended<User>(); + + #region Regex Pattern Builder + + StringBuilder regexBuilder = new StringBuilder(@"\w[^@]@("); + + for (int i = 0; i < Constants.AcceptedEmailProviders.Length; i++) + { + regexBuilder.Append(i == 0 + ? $"{Constants.AcceptedEmailProviders[i].Replace(".", @"\.")}" + : $"|{Constants.AcceptedEmailProviders[i].Replace(".", @"\.")}"); + } + + regexBuilder.Append(")$"); + + #endregion Regex Pattern Builder + + Regex emailValidationRegex = new Regex(regexBuilder.ToString(), RegexOptions.Compiled); + + IObservable<bool> canUpdate = this.WhenAnyValue(x => x.SelectedUser, x => x.Username, x => x.Email, x => x.Password, x => x.Privileges, + (user, username, email, password, privileges) => + { + if (user == null) + { + // we cannot edit a null user + return false; + } + + if (user.Username == username && user.Email == email && user.Privileges == privileges && password.Equals(string.Empty)) + { + // no changes were made, so cannot update user + return false; + } + + // we must have a valid password and username to create a user + if (!string.IsNullOrEmpty(username) && !string.IsNullOrWhiteSpace(username) || + !string.IsNullOrEmpty(password) && !string.IsNullOrWhiteSpace(password)) + { + // if the optional email is given, then it must match the email validation regex + if (!string.IsNullOrEmpty(email) && !string.IsNullOrWhiteSpace(email)) + { + return emailValidationRegex.IsMatch(email); + } + + return true; + } + + return false; + }); + + UpdateUserCommand = ReactiveCommand.Create(UpdateUserCommandImpl, canUpdate); + + ResetUserCommand = ReactiveCommand.Create(ResetUserCommandImpl); } /// <summary> @@ -27,6 +119,8 @@ namespace StarSimGui.ViewModels.Database_ViewModels public UpdateUsersViewModel(in SimulatorContext context) : this() { dbContext = context; + + Users.Load(dbContext.Users); } /// <summary> @@ -35,6 +129,131 @@ namespace StarSimGui.ViewModels.Database_ViewModels public event Action DatabaseEdited; /// <summary> + /// The email of the user to update. + /// </summary> + public string Email + { + get + { + return email; + } + set + { + email = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Provides feedback about the changes made to the database. + /// </summary> + public string Feedback { get; private set; } + + /// <summary> + /// The password of the user to update. + /// </summary> + public string Password + { + get + { + return password; + } + set + { + password = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// The possible <see cref="UserPrivileges"/> that a user can have. + /// </summary> + public UserPrivileges[] PossiblePrivileges + { + get { return new[] { UserPrivileges.Default, UserPrivileges.Publisher, UserPrivileges.Admin }; } + } + + /// <summary> + /// The privileges of the user to update. + /// </summary> + public UserPrivileges Privileges + { + get + { + return privileges; + } + set + { + privileges = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Command invoked whenever the user wants to reset the currently edited user. + /// </summary> + public ICommand ResetUserCommand { get; } + + /// <summary> + /// The currently selected user. + /// </summary> + public User SelectedUser + { + get + { + return selectedUser; + } + set + { + selectedUser = value; + + Username = value?.Username ?? string.Empty; + Email = value?.Email ?? string.Empty; + Password = string.Empty; + Privileges = value?.Privileges ?? 0; + + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// Command invoked whenever the user wants to update the currently selected user in the database. + /// </summary> + public ICommand UpdateUserCommand { get; } + + /// <summary> + /// The username of the user to update. + /// </summary> + public string Username + { + get + { + return username; + } + set + { + username = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> + /// The users held in the database. + /// </summary> + public IObservableCollection<User> Users + { + get + { + return users; + } + set + { + users = value; + this.RaisePropertyChanged(); + } + } + + /// <summary> /// Invokes the <see cref="DatabaseEdited"/> event. /// </summary> private void OnDatabaseEdited() @@ -43,10 +262,58 @@ namespace StarSimGui.ViewModels.Database_ViewModels } /// <summary> + /// Invoked whenever the user wants to reset the currently edited user. + /// </summary> + private void ResetUserCommandImpl() + { + SelectedUser = null; + Username = string.Empty; + Password = string.Empty; + Email = string.Empty; + Feedback = string.Empty; + this.RaisePropertyChanged(nameof(Feedback)); + } + + /// <summary> + /// Invoked whenever the user wants to update the currently selected user in the database. + /// </summary> + private void UpdateUserCommandImpl() + { + if (dbContext.Users.Any(user => user.Username.Equals(Username))) + { + Feedback = "User with the same username already exists in the database."; + this.RaisePropertyChanged(nameof(Feedback)); + } + + try + { + byte[] passwordBytes = CryptographyHelper.StringToBytes(Password); + byte[] passwordSalt = SelectedUser.PasswordSalt; + byte[] passwordHash = CryptographyHelper.GenerateHash(passwordBytes, passwordSalt); + + SelectedUser.Username = (Username == SelectedUser.Username) ? SelectedUser.Username : Username; + SelectedUser.Email = (Email == SelectedUser.Email) ? SelectedUser.Email : Email; + SelectedUser.PasswordHash = (passwordHash == SelectedUser.PasswordHash) ? SelectedUser.PasswordHash : passwordHash; + SelectedUser.Privileges = (Privileges == SelectedUser.Privileges) ? SelectedUser.Privileges : Privileges; + + Feedback = "User was successfully updated."; + this.RaisePropertyChanged(nameof(Feedback)); + + OnDatabaseEdited(); + } + catch (Exception) + { + Feedback = "User could not be updated."; + this.RaisePropertyChanged(nameof(Feedback)); + } + } + + /// <summary> /// Refreshed the database sources for this view model. /// </summary> internal void HandleDatabaseRefresh() { + Users.Load(dbContext.Users); } } } \ No newline at end of file diff --git a/StarSim/StarSimGui/Views/Database Views/CreateUsers.xaml b/StarSim/StarSimGui/Views/Database Views/CreateUsers.xaml @@ -21,7 +21,7 @@ <TextBlock HorizontalAlignment="Center">Password:</TextBlock> <TextBox HorizontalAlignment="Stretch" Text="{Binding Password, Mode=TwoWay}"></TextBox> <TextBlock HorizontalAlignment="Center">Privileges:</TextBlock> - <ListBox Items="{Binding PossiblePrivileges}" SelectedItem="{Binding Privileges, Mode=OneWayToSource}"></ListBox> + <ListBox Items="{Binding PossiblePrivileges}" SelectedItem="{Binding Privileges, Mode=TwoWay}"></ListBox> <TextBlock HorizontalAlignment="Center" Text="{Binding Feedback}"></TextBlock> <Button Command="{Binding CreateUserCommand}" Content="Create User" HorizontalAlignment="Stretch"></Button> <Button Command="{Binding ResetUserCommand}" Content="Reset User" HorizontalAlignment="Stretch"></Button> diff --git a/StarSim/StarSimGui/Views/Database Views/UpdateSystems.xaml b/StarSim/StarSimGui/Views/Database Views/UpdateSystems.xaml @@ -12,7 +12,47 @@ </Design.DataContext> <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2"> - <Grid ColumnDefinitions="*,*,*,*" RowDefinitions="*,*,*,*"> + <Grid ColumnDefinitions="*,*,*" RowDefinitions="*,*,*,*"> + <ListBox Items="{Binding Bodies}" SelectedItem="{Binding SelectedBody, Mode=TwoWay}" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="2"> + </ListBox> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="2" Grid.RowSpan="1"> + <StackPanel> + <TextBlock HorizontalAlignment="Center">Body Name:</TextBlock> + <TextBox HorizontalAlignment="Stretch" Text="{Binding BodyName, Mode=TwoWay}"></TextBox> + <TextBlock HorizontalAlignment="Center">Body Mass:</TextBlock> + <TextBox HorizontalAlignment="Stretch" Text="{Binding BodyMass, Mode=TwoWay}"></TextBox> + </StackPanel> + </Border> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="3" Grid.RowSpan="1"> + <StackPanel> + <TextBlock Text="{Binding BodyFeedback}" HorizontalAlignment="Center"></TextBlock> + <Button Command="{Binding UpdateBodyCommand}" Content="Update Body"></Button> + <Button Command="{Binding ResetBodyCommand}" Content="Deselect Body"></Button> + </StackPanel> + </Border> + <ListBox Items="{Binding Systems}" SelectedItem="{Binding SelectedSystem, Mode=TwoWay}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="0" Grid.RowSpan="2"> + </ListBox> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="2" Grid.RowSpan="1"> + <Grid ColumnDefinitions="*" RowDefinitions="*,*,*,*"> + <TextBlock HorizontalAlignment="Center" Grid.Column="0" Grid.Row="0" Grid.RowSpan="1">Bodies in System:</TextBlock> + <ListBox Items="{Binding SelectedSystemBodies}" SelectedItem="{Binding BodyToRemove, Mode=TwoWay}" Grid.Column="0" Grid.Row="1" Grid.RowSpan="2"></ListBox> + <Button Command="{Binding RemoveBodyFromSystemCommand}" Content="Remove Body" Grid.Column="0" Grid.Row="3" Grid.RowSpan="1"></Button> + </Grid> + </Border> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="2" Grid.ColumnSpan="1" Grid.Row="2" Grid.RowSpan="1"> + <Grid ColumnDefinitions="*" RowDefinitions="*,*,*,*"> + <TextBlock HorizontalAlignment="Center" Grid.Column="0" Grid.Row="0" Grid.RowSpan="1">Other Bodies:</TextBlock> + <ListBox Items="{Binding Bodies}" SelectedItem="{Binding BodyToAdd, Mode=TwoWay}" Grid.Column="0" Grid.Row="1" Grid.RowSpan="2"></ListBox> + <Button Command="{Binding AddBodyToSystemCommand}" Content="Add Body" Grid.Column="0" Grid.Row="3" Grid.RowSpan="1"></Button> + </Grid> + </Border> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="3" Grid.RowSpan="1"> + <StackPanel> + <TextBlock Text="{Binding SystemFeedback}" HorizontalAlignment="Center"></TextBlock> + <Button Command="{Binding UpdateSystemCommand}" Content="Update System"></Button> + <Button Command="{Binding ResetSystemCommand}" Content="Deselect System"></Button> + </StackPanel> + </Border> </Grid> </Border> </UserControl> \ No newline at end of file diff --git a/StarSim/StarSimGui/Views/Database Views/UpdateUsers.xaml b/StarSim/StarSimGui/Views/Database Views/UpdateUsers.xaml @@ -13,6 +13,27 @@ <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2"> <Grid ColumnDefinitions="*,*,*,*" RowDefinitions="*,*,*,*"> + <ListBox Items="{Binding Users}" SelectedItem="{Binding SelectedUser, Mode=TwoWay}" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="2"> + </ListBox> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Grid.RowSpan="2"> + <StackPanel> + <TextBlock HorizontalAlignment="Center">Username:</TextBlock> + <TextBox HorizontalAlignment="Stretch" Text="{Binding Username, Mode=TwoWay}"></TextBox> + <TextBlock HorizontalAlignment="Center">Email:</TextBlock> + <TextBox HorizontalAlignment="Stretch" Text="{Binding Email, Mode=TwoWay}"></TextBox> + <TextBlock HorizontalAlignment="Center">Password:</TextBlock> + <TextBox HorizontalAlignment="Stretch" Text="{Binding Password, Mode=TwoWay}"></TextBox> + <TextBlock HorizontalAlignment="Center">Privileges:</TextBlock> + <ListBox Items="{Binding PossiblePrivileges}" SelectedItem="{Binding Privileges, Mode=TwoWay}"></ListBox> + </StackPanel> + </Border> + <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="2" Margin="2" Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="2" Grid.RowSpan="2"> + <StackPanel> + <TextBlock Text="{Binding Feedback}"></TextBlock> + <Button Command="{Binding UpdateUserCommand}" Content="Update User"></Button> + <Button Command="{Binding ResetUserCommand}" Content="Deselect User"></Button> + </StackPanel> + </Border> </Grid> </Border> </UserControl> \ No newline at end of file diff --git a/StarSim/StarSimLib/Constants.cs b/StarSim/StarSimLib/Constants.cs @@ -95,6 +95,15 @@ namespace StarSimLib public const double ZoomStep = 0.05; /// <summary> + /// The list of accepted email providers. + /// </summary> + public static readonly string[] AcceptedEmailProviders = { + "gmail.com", + "hotmail.com", + "yahoo.com" + }; + + /// <summary> /// The <see cref="Octant"/> instance representing the rendered universe. /// </summary> public static readonly Octant UniverseOctant = new Octant(new Vector4(), UniverseSize); diff --git a/StarSim/StarSimLib/StarSimLib.xml b/StarSim/StarSimLib/StarSimLib.xml @@ -96,6 +96,11 @@ The amount by which the zoom level will be increased or decreased. </summary> </member> + <member name="F:StarSimLib.Constants.AcceptedEmailProviders"> + <summary> + The list of accepted email providers. + </summary> + </member> <member name="F:StarSimLib.Constants.UniverseOctant"> <summary> The <see cref="T:StarSimLib.Data_Structures.Octant"/> instance representing the rendered universe.