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:
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.