diff --git a/HeliosPlus.Shared/Helios.cs b/HeliosPlus.Shared/Helios.cs index 24f0268..4e0c55a 100644 --- a/HeliosPlus.Shared/Helios.cs +++ b/HeliosPlus.Shared/Helios.cs @@ -60,7 +60,7 @@ namespace HeliosPlus.Shared if (profile != null) { - args.Add($"-p \"{profile.Id}\""); + args.Add($"-p \"{profile.UUID}\""); } if (!string.IsNullOrWhiteSpace(programAddress)) @@ -108,7 +108,7 @@ namespace HeliosPlus.Shared if (profile != null) { - args.Add($"-p \"{profile.Id}\""); + args.Add($"-p \"{profile.UUID}\""); } if (steamAppId > 0) diff --git a/HeliosPlus.Shared/HeliosPlus.Shared.csproj b/HeliosPlus.Shared/HeliosPlus.Shared.csproj index 711ecc8..d0d2acf 100644 --- a/HeliosPlus.Shared/HeliosPlus.Shared.csproj +++ b/HeliosPlus.Shared/HeliosPlus.Shared.csproj @@ -40,6 +40,11 @@ + + True + True + Resources.resx + @@ -54,6 +59,7 @@ + @@ -73,6 +79,10 @@ + + ResXFileCodeGenerator + Resources.Designer.cs + ResXFileCodeGenerator Language.Designer.cs diff --git a/HeliosPlus.Shared/ProfileItem.cs b/HeliosPlus.Shared/ProfileItem.cs index af0c720..14879e1 100644 --- a/HeliosPlus.Shared/ProfileItem.cs +++ b/HeliosPlus.Shared/ProfileItem.cs @@ -15,12 +15,12 @@ using HeliosPlus.Shared.Topology; using System.Drawing; using System.Drawing.Imaging; using WindowsDisplayAPI; +using System.Text.RegularExpressions; namespace HeliosPlus.Shared { public class ProfileItem { - private static ProfileItem _currentProfile; private static List _allSavedProfiles = new List(); private ProfileIcon _profileIcon; private Bitmap _profileBitmap, _profileShortcutBitmap; @@ -29,6 +29,11 @@ namespace HeliosPlus.Shared internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeliosPlus"); + private string _uuid; + private Version _version; + private bool _isActive = false; + private bool _isPossible = false; + #region JsonConverterBitmap internal class CustomBitmapConverter : JsonConverter @@ -104,14 +109,22 @@ namespace HeliosPlus.Shared public static Version Version = new Version(2, 1); - public string Id { get; set; } = Guid.NewGuid().ToString("B"); + #region Instance Properties - [JsonIgnore] - public bool IsActive + public string UUID { get { - return _currentProfile.Equals(this); + if (String.IsNullOrWhiteSpace(_uuid)) + _uuid = Guid.NewGuid().ToString("B"); + return _uuid; + } + set + { + string uuidV4Regex = @"/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i"; + Match match = Regex.Match(value, uuidV4Regex, RegexOptions.IgnoreCase); + if (match.Success) + _uuid = value; } } @@ -152,34 +165,6 @@ namespace HeliosPlus.Shared public ProfileViewport[] Viewports { get; set; } = new ProfileViewport[0]; - public static string SavedProfilesFilePath - { - get => System.IO.Path.Combine(AppDataPath, $"Profiles\\DisplayProfiles_{Version.ToString(2)}.json"); - } - - public static string SavedProfilesPath - { - get => System.IO.Path.Combine(AppDataPath, $"Profiles"); - } - - public static List AllSavedProfiles - { - get - { - if (_allSavedProfiles.Count == 0) - { - ProfileItem.LoadAllProfiles(); - } - return _allSavedProfiles; - } - } - - public static ProfileItem CurrentProfile - { - get => _currentProfile; - } - - public ProfileIcon ProfileIcon { get @@ -199,8 +184,7 @@ namespace HeliosPlus.Shared } - public string SavedProfileCacheFilename { get; set; } - + public string SavedProfileIconCacheFilename { get; set; } [JsonConverter(typeof(CustomBitmapConverter))] public Bitmap ProfileBitmap @@ -242,82 +226,7 @@ namespace HeliosPlus.Shared } - public static List LoadAllProfiles() - { - - if (File.Exists(SavedProfilesFilePath)) - { - var json = File.ReadAllText(SavedProfilesFilePath, Encoding.Unicode); - - if (!string.IsNullOrWhiteSpace(json)) - { - List profiles = new List(); - try - { - //var profiles = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - profiles = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings - { - MissingMemberHandling = MissingMemberHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore, - DefaultValueHandling = DefaultValueHandling.Include, - TypeNameHandling = TypeNameHandling.Auto - }); - } - catch (Exception ex) - { - // ignored - Console.WriteLine("Unable to deserialize profile: " + ex.Message); - } - - - //Convert array to list - //List profilesList = profiles.ToList(); - - // Find which entry is being used now, and save that info in a class variable - ProfileItem myCurrentProfile = new ProfileItem - { - Name = "Current Display Profile", - Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() - }; - - _currentProfile = myCurrentProfile; - - foreach (ProfileItem loadedProfile in profiles) - { - // Save a profile Icon to the profile - loadedProfile.ProfileIcon = new ProfileIcon(loadedProfile); - loadedProfile.ProfileBitmap = loadedProfile.ProfileIcon.ToBitmap(128,128); - - if (loadedProfile.IsActive) { - _currentProfile = loadedProfile; - } - - } - - _allSavedProfiles = profiles; - - return _allSavedProfiles; - } - } - - // If we get here, then we don't have any profiles saved! - // So we gotta start from scratch - // Create a new profile based on our current display settings - _currentProfile = new ProfileItem - { - Name = "Current Display Profile", - Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() - }; - - // Save a profile Icon to the profile - _currentProfile.ProfileIcon = new ProfileIcon(_currentProfile); - _currentProfile.ProfileBitmap = _currentProfile.ProfileIcon.ToBitmap(128, 128); - - // Create a new empty list of all our display profiles as we don't have any saved! - _allSavedProfiles = new List(); - - return _allSavedProfiles; - } + #endregion public static bool IsValidName(string testName) { @@ -334,89 +243,33 @@ namespace HeliosPlus.Shared public static bool IsValidId(string testId) { - foreach (ProfileItem loadedProfile in _allSavedProfiles) - { - if (loadedProfile.Id == testId) - { - return false; - } - } - - return true; - } - - - public static void UpdateCurrentProfile() - { - _currentProfile = new ProfileItem - { - Name = "Current Display Profile", - Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() - }; - } - - public static bool SaveAllProfiles() - { - if (SaveAllProfiles(_allSavedProfiles)) + string uuidV4Regex = @"/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i"; + Match match = Regex.Match(testId, uuidV4Regex, RegexOptions.IgnoreCase); + if (match.Success) return true; - return false; + else + return false; } - public static bool SaveAllProfiles(List profilesToSave) + + public bool CopyTo(ProfileItem profile, bool overwriteId = false) { + if (!(profile is ProfileItem)) + return false; - if (!Directory.Exists(SavedProfilesPath)) - { - try - { - Directory.CreateDirectory(SavedProfilesPath); - } - catch (Exception ex) - { - Console.WriteLine("Unable to create Profile folder " + SavedProfilesPath + ": " + ex.Message); - } - } + if (overwriteId) + profile.UUID = UUID; - - // Now we loop over the profiles and save their images for later - foreach (ProfileItem profileToSave in profilesToSave) - { - profileToSave.SaveProfileImageToCache(); - } - - try - { - var json = JsonConvert.SerializeObject(profilesToSave, Formatting.Indented, new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Include, - DefaultValueHandling = DefaultValueHandling.Populate, - TypeNameHandling = TypeNameHandling.Auto - - }); - - - if (!string.IsNullOrWhiteSpace(json)) - { - var dir = System.IO.Path.GetDirectoryName(SavedProfilesPath); - - if (dir != null) - { - Directory.CreateDirectory(dir); - File.WriteAllText(SavedProfilesFilePath, json, Encoding.Unicode); - - return true; - } - } - } - catch (Exception ex) - { - Console.WriteLine("Unable to serialize profile: " + ex.Message); - } - - // Overwrite the list of saved profiles as the new lot we received. - _allSavedProfiles = profilesToSave; - - return false; + // Copy all our profile data over to the other profile + profile.Name = Name; + profile.UUID = UUID; + profile.Name = Name; + profile.Viewports = Viewports; + profile.ProfileIcon = ProfileIcon; + profile.SavedProfileIconCacheFilename = SavedProfileIconCacheFilename; + profile.ProfileBitmap = ProfileBitmap; + profile.ProfileTightestBitmap = ProfileTightestBitmap; + return true; } @@ -481,22 +334,7 @@ namespace HeliosPlus.Shared return uncheckedFilename; } - public bool SaveProfileImageToCache() - { - this.SavedProfileCacheFilename = Path.Combine(SavedProfilesPath, GetValidFilename(String.Concat(this.Name + @".png"))); - try - { - this.ProfileBitmap.Save(this.SavedProfileCacheFilename, ImageFormat.Png); - return true; - } - catch (Exception ex) - { - Console.WriteLine("Unable to create profile image in cache using " + this.SavedProfileCacheFilename + ": " + ex.Message); - return false; - } - } - - private void _applyTopos() + public void ApplyTopos() { Debug.Print("_applyTopos()"); try @@ -533,7 +371,7 @@ namespace HeliosPlus.Shared } } - private void _applyPathInfos() + public void ApplyPathInfos() { Debug.Print("_applyPathInfos()"); if (!IsPossible) @@ -550,8 +388,8 @@ namespace HeliosPlus.Shared { var dict = new Dictionary() { - { "Applying_Topos", _applyTopos }, - { "Applying_Paths", _applyPathInfos } + { "Applying_Topos", ApplyTopos }, + { "Applying_Paths", ApplyPathInfos } }; return dict; } @@ -572,41 +410,6 @@ namespace HeliosPlus.Shared return list; } - public bool Apply() - { - try - { - - Debug.Print("Begin profile change"); - Thread.Sleep(2000); - _applyTopos(); - - Debug.Print("Finished setting topologies"); - Debug.Print("Sleep"); - Thread.Sleep(18000); - Debug.Print("Awake"); - - _applyPathInfos(); - - Debug.Print("Applying pathInfos"); - Debug.Print("Sleep"); - Thread.Sleep(10000); - Debug.Print("Awake"); - - UpdateCurrentProfile(); - - return true; - } - catch (Exception ex) - { - UpdateCurrentProfile(); - Console.WriteLine($"Profile: Problem applying the '{Name}' Display Profile: {ex.Message}"); - MessageBox.Show($"Problem applying the '{Name}' Display Profile! \n(ex.Message)", $"Problem applying '{Name}' Profile", MessageBoxButtons.OK, MessageBoxIcon.Error); - - return false; - } - } - } // Custom comparer for the Profile class diff --git a/HeliosPlus.Shared/ProfileRepository.cs b/HeliosPlus.Shared/ProfileRepository.cs new file mode 100644 index 0000000..8247225 --- /dev/null +++ b/HeliosPlus.Shared/ProfileRepository.cs @@ -0,0 +1,583 @@ +using HeliosPlus.Shared; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Drawing.IconLib; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using WindowsDisplayAPI.DisplayConfig; +using HeliosPlus.Shared.Resources; +using Newtonsoft.Json; +using NvAPIWrapper.Mosaic; +using NvAPIWrapper.Native.Mosaic; +using HeliosPlus.Shared.Topology; +using System.Drawing; +using System.Drawing.Imaging; +using WindowsDisplayAPI; +using System.Diagnostics; +using System.Threading; +using System.Windows.Forms; +using System.Text.RegularExpressions; +using System.Resources; + +namespace HeliosPlus.Shared +{ + + public class ProfileRepository + { + #region Class Variables + // Common items to the class + private static List _allProfiles = new List(); + public static Version Version = new Version(1, 0, 0); + // Other constants that are useful + public static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeliosPlus"); + public static string AppIconPath = Path.Combine(AppDataPath, $"Icons"); + public static string AppHeliosPlusIconFilename = Path.Combine(AppIconPath, @"HeliosPlus.ico"); + private static string _profileStorageJsonPath = Path.Combine(AppDataPath, $"Profiles"); + private static string _profileStorageJsonFileName = Path.Combine(_profileStorageJsonPath, $"DisplayProfiles_{Version.ToString(2)}.json"); + private static uint _lastProfileId; + private static ProfileItem _currentProfile; + private static List _availableDisplays; + private static List _unavailableDisplays; + + #endregion + + #region Instance Variables + // Individual items per class instance + #endregion + + + #region Class Constructors + public ProfileRepository() + { + // Load the Profiles from storage + LoadProfiles(); + } + + public ProfileRepository(ProfileItem Profile) : this() + { + if (Profile is ProfileItem) + AddProfile(Profile); + } + #endregion + + #region Class Properties + public static List AllProfiles + { + get + { + if (_allProfiles == null) + // Load the Profiles from storage if they need to be + LoadProfiles(); + return _allProfiles; + } + } + + public static ProfileItem CurrentProfile + { + get + { + UpdateActiveProfile(); + return _currentProfile; + } + set + { + if (value is ProfileItem) + { + _currentProfile = value; + // And if we have the _originalBitmap we can also save the Bitmap overlay, but only if the ProfileToUse is set + //if (_originalBitmap is Bitmap) + // _shortcutBitmap = ToBitmapOverlay(_originalBitmap, ProfileToUse.ProfileTightestBitmap, 256, 256); + } + } + } + + public static int ProfileCount + { + get + { + return _allProfiles.Count; + } + } + + #endregion + + #region Class Methods + public static bool AddProfile(ProfileItem Profile) + { + if (!(Profile is ProfileItem)) + return false; + + // Doublecheck if it already exists + // Because then we just update the one that already exists + if (ContainsProfile(Profile)) + { + // We update the existing Profile with the data over + ProfileItem ProfileToUpdate = GetProfile(Profile.UUID); + Profile.CopyTo(ProfileToUpdate); + } + else + { + // Add the Profile to the list of Profiles + _allProfiles.Add(Profile); + } + + //Doublecheck it's been added + if (ContainsProfile(Profile)) + { + // Generate the Profile Icon ready to be used + SaveProfileIconToCache(Profile); + + // Save the Profiles JSON as it's different + SaveProfiles(); + + return true; + } + else + return false; + + } + + public static bool RemoveProfile(ProfileItem Profile) + { + if (!(Profile is ProfileItem)) + return false; + + // Remove the Profile Icons from the Cache + List ProfilesToRemove = _allProfiles.FindAll(item => item.UUID.Equals(Profile.UUID)); + foreach (ProfileItem ProfileToRemove in ProfilesToRemove) + { + try + { + File.Delete(ProfileToRemove.SavedProfileIconCacheFilename); + } + catch + { + // TODO check and report + } + } + + // Remove the Profile from the list. + int numRemoved = _allProfiles.RemoveAll(item => item.UUID.Equals(Profile.UUID)); + + if (numRemoved == 1) + { + SaveProfiles(); + return true; + } + else if (numRemoved == 0) + return false; + else + throw new ProfileRepositoryException(); + } + + + public static bool RemoveProfile(string ProfileName) + { + if (String.IsNullOrWhiteSpace(ProfileName)) + return false; + + // Remove the Profile Icons from the Cache + List ProfilesToRemove = _allProfiles.FindAll(item => item.Name.Equals(ProfileName)); + foreach (ProfileItem ProfileToRemove in ProfilesToRemove) + { + try + { + File.Delete(ProfileToRemove.SavedProfileIconCacheFilename); + } + catch + { + // TODO check and report + } + } + + // Remove the Profile from the list. + int numRemoved = _allProfiles.RemoveAll(item => item.Name.Equals(ProfileName)); + + if (numRemoved == 1) + { + SaveProfiles(); + return true; + } + else if (numRemoved == 0) + return false; + else + throw new ProfileRepositoryException(); + + } + + public static bool RemoveProfile(uint ProfileId) + { + if (ProfileId == 0) + return false; + + // Remove the Profile Icons from the Cache + List ProfilesToRemove = _allProfiles.FindAll(item => item.UUID.Equals(ProfileId)); + foreach (ProfileItem ProfileToRemove in ProfilesToRemove) + { + try + { + File.Delete(ProfileToRemove.SavedProfileIconCacheFilename); + } + catch + { + // TODO check and report + } + } + + // Remove the Profile from the list. + int numRemoved = _allProfiles.RemoveAll(item => item.UUID.Equals(ProfileId)); + + if (numRemoved == 1) + { + SaveProfiles(); + return true; + } + else if (numRemoved == 0) + return false; + else + throw new ProfileRepositoryException(); + } + + + public static bool ContainsProfile(ProfileItem Profile) + { + if (!(Profile is ProfileItem)) + return false; + + foreach (ProfileItem testProfile in _allProfiles) + { + if (testProfile.UUID.Equals(Profile.UUID)) + return true; + } + + return false; + } + + public static bool ContainsProfile(string ProfileNameOrId) + { + if (String.IsNullOrWhiteSpace(ProfileNameOrId)) + return false; + + if (ProfileItem.IsValidId(ProfileNameOrId)) + foreach (ProfileItem testProfile in _allProfiles) + { + if (testProfile.UUID.Equals(ProfileNameOrId)) + return true; + } + else + foreach (ProfileItem testProfile in _allProfiles) + { + if (testProfile.Name.Equals(ProfileNameOrId)) + return true; + } + + return false; + + } + + public static ProfileItem GetProfile(string ProfileNameOrId) + { + if (String.IsNullOrWhiteSpace(ProfileNameOrId)) + return null; + + if (ProfileItem.IsValidId(ProfileNameOrId)) + foreach (ProfileItem testProfile in _allProfiles) + { + if (testProfile.UUID.Equals(ProfileNameOrId)) + return testProfile; + } + else + foreach (ProfileItem testProfile in _allProfiles) + { + if (testProfile.Name.Equals(ProfileNameOrId)) + return testProfile; + } + + return null; + } + + public static bool RenameProfile(ProfileItem profile, string renamedName) + { + if (!(profile is ProfileItem)) + return false; + + if (!IsValidFilename(renamedName)) + return false; + + profile.Name = GetValidFilename(renamedName); + + // If it's been added to the list of AllProfiles + // then we also need to reproduce the Icons + if (ContainsProfile(profile)) + { + + + // rename the old Profile Icon to the new name + string newSavedProfileIconCacheFilename = Path.Combine(_profileStorageJsonPath, String.Concat(@"profile-", GetValidFilename(profile.Name).ToLower(CultureInfo.InvariantCulture), @".ico")); + File.Move(profile.SavedProfileIconCacheFilename, newSavedProfileIconCacheFilename); + + // Then update the profile too + profile.SavedProfileIconCacheFilename = newSavedProfileIconCacheFilename; + + // Save the Profiles JSON as it's different now + SaveProfiles(); + + return true; + } + else + return false; + + } + + + public static void UpdateActiveProfile() + { + _currentProfile = new ProfileItem + { + Name = "Current Display Profile", + Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray(), + ProfileIcon = new ProfileIcon(_currentProfile), + ProfileBitmap = _currentProfile.ProfileIcon.ToBitmap(256, 256) + }; + + } + + + public static ProfileItem GetActiveProfile() + { + UpdateActiveProfile(); + + if (!(_currentProfile is ProfileItem)) + return null; + return _currentProfile; + } + + public static bool IsActiveProfile(ProfileItem profile) + { + UpdateActiveProfile(); + + if (!(_currentProfile is ProfileItem)) + return false; + + if (!(profile is ProfileItem)) + return false; + + if (profile.Equals(_currentProfile)) + return true; + + return false; + } + + private static bool LoadProfiles() + { + + if (File.Exists(_profileStorageJsonFileName)) + { + var json = File.ReadAllText(_profileStorageJsonFileName, Encoding.Unicode); + + if (!string.IsNullOrWhiteSpace(json)) + { + List profiles = new List(); + try + { + _allProfiles = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings + { + MissingMemberHandling = MissingMemberHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Include, + TypeNameHandling = TypeNameHandling.Auto + }); + } + catch (Exception ex) + { + // ignored + Console.WriteLine($"Unable to load Profiles from JSON file {_profileStorageJsonFileName}: " + ex.Message); + } + + ProfileItem myCurrentProfile = new ProfileItem + { + Name = "Current Display Profile", + Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() + }; + + _currentProfile = myCurrentProfile; + + // Lookup all the Profile Names in the Saved Profiles + foreach (ProfileItem loadedProfile in profiles) + { + // Save a profile Icon to the profile + loadedProfile.ProfileIcon = new ProfileIcon(loadedProfile); + loadedProfile.ProfileBitmap = loadedProfile.ProfileIcon.ToBitmap(128, 128); + + if (ProfileRepository.IsActiveProfile(loadedProfile)) + _currentProfile = loadedProfile; + + } + } + } else + { + // If we get here, then we don't have any profiles saved! + // So we gotta start from scratch + // Create a new profile based on our current display settings + ProfileItem myCurrentProfile = new ProfileItem + { + Name = "Current Display Profile", + Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() + }; + + _currentProfile = myCurrentProfile; + + // Save a profile Icon to the profile + _currentProfile.ProfileIcon = new ProfileIcon(_currentProfile); + _currentProfile.ProfileBitmap = _currentProfile.ProfileIcon.ToBitmap(256, 256); + } + return true; + } + + public static bool SaveProfiles() + { + + if (!Directory.Exists(_profileStorageJsonPath)) + { + try + { + Directory.CreateDirectory(_profileStorageJsonPath); + } + catch (Exception ex) + { + Console.WriteLine($"Unable to create Profile folder {_profileStorageJsonPath}: " + ex.Message); + + } + } + + try + { + var json = JsonConvert.SerializeObject(_allProfiles, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Include, + DefaultValueHandling = DefaultValueHandling.Populate, + TypeNameHandling = TypeNameHandling.Auto + + }); + + + if (!string.IsNullOrWhiteSpace(json)) + { + File.WriteAllText(_profileStorageJsonFileName, json, Encoding.Unicode); + return true; + } + } + catch (Exception ex) + { + Console.WriteLine($"Unable to save Profile JSON file {_profileStorageJsonFileName}: " + ex.Message); + } + + return false; + } + + private static void SaveProfileIconToCache(ProfileItem profile) + { + + // Work out the name of the Profile we'll save. + profile.SavedProfileIconCacheFilename = Path.Combine(_profileStorageJsonPath, String.Concat(@"profile-", GetValidFilename(profile.Name).ToLower(CultureInfo.InvariantCulture), @".ico")); + + MultiIcon ProfileIcon; + try + { + ProfileIcon = profile.ProfileIcon.ToIcon(); + ProfileIcon.Save(profile.SavedProfileIconCacheFilename, MultiIconFormat.ICO); + } + catch (Exception ex) + { + // If we fail to create an icon based on the Profile, then we use the standard HeliosPlus profile one. + // Which is created on program startup. + File.Copy(AppHeliosPlusIconFilename, profile.SavedProfileIconCacheFilename); + + } + } + + public static void UpdateCurrentProfile() + { + _currentProfile = new ProfileItem + { + Name = "Current Display Profile", + Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray() + }; + } + + public static bool ApplyProfile(ProfileItem profile) + { + try + { + + Debug.Print("Begin profile change"); + Thread.Sleep(2000); + profile.ApplyTopos(); + + Debug.Print("Finished setting topologies"); + Debug.Print("Sleep"); + Thread.Sleep(18000); + Debug.Print("Awake"); + + profile.ApplyPathInfos(); + + Debug.Print("Applying pathInfos"); + Debug.Print("Sleep"); + Thread.Sleep(10000); + Debug.Print("Awake"); + + UpdateCurrentProfile(); + + return true; + } + catch (Exception ex) + { + UpdateCurrentProfile(); + Console.WriteLine($"Profile: Problem applying the '{profile.Name}' Display Profile: {ex.Message}"); + MessageBox.Show($"Problem applying the '{profile.Name}' Display Profile! \n(ex.Message)", $"Problem applying '{profile.Name}' Profile", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + } + + public static bool IsValidFilename(string testName) + { + string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidFileNameChars()); + Regex regInvalidFileName = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]"); + + if (regInvalidFileName.IsMatch(testName)) { return false; }; + + return true; + } + + public static string GetValidFilename(string uncheckedFilename) + { + string invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); + foreach (char c in invalid) + { + uncheckedFilename = uncheckedFilename.Replace(c.ToString(), ""); + } + return uncheckedFilename; + } + + #endregion + + } + + + [global::System.Serializable] + public class ProfileRepositoryException : Exception + { + public ProfileRepositoryException() { } + public ProfileRepositoryException(string message) : base(message) { } + public ProfileRepositoryException(string message, Exception inner) : base(message, inner) { } + protected ProfileRepositoryException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } + + +} diff --git a/HeliosPlus.Shared/Properties/Resources.Designer.cs b/HeliosPlus.Shared/Properties/Resources.Designer.cs new file mode 100644 index 0000000..cfee2eb --- /dev/null +++ b/HeliosPlus.Shared/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace HeliosPlus.Shared.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeliosPlus.Shared.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/HeliosPlus.Shared/Properties/Resources.resx b/HeliosPlus.Shared/Properties/Resources.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/HeliosPlus.Shared/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/HeliosPlus/HeliosPlus.csproj b/HeliosPlus/HeliosPlus.csproj index e9a7aaa..9962dab 100644 --- a/HeliosPlus/HeliosPlus.csproj +++ b/HeliosPlus/HeliosPlus.csproj @@ -149,7 +149,7 @@ Designer - ResXFileCodeGenerator + PublicResXFileCodeGenerator Resources.Designer.cs Designer @@ -235,7 +235,6 @@ - diff --git a/HeliosPlus/Program.cs b/HeliosPlus/Program.cs index 53bd113..92d125f 100644 --- a/HeliosPlus/Program.cs +++ b/HeliosPlus/Program.cs @@ -18,6 +18,7 @@ using HeliosPlus.Shared; using HeliosPlus.UIForms; using System.Net.NetworkInformation; using System.Text.RegularExpressions; +using System.Drawing; namespace HeliosPlus { public enum SupportedGameLibrary @@ -31,15 +32,21 @@ namespace HeliosPlus { { internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeliosPlus"); + public static string AppIconPath = Path.Combine(Program.AppDataPath, $"Icons"); + public static string AppHeliosPlusIconFilename = Path.Combine(AppIconPath, @"HeliosPlus.ico"); + public static string AppOriginIconFilename = Path.Combine(AppIconPath, @"Origin.ico"); + public static string AppSteamIconFilename = Path.Combine(AppIconPath, @"Steam.ico"); + public static string AppUplayIconFilename = Path.Combine(AppIconPath, @"Steam.ico"); + public static string AppEpicIconFilename = Path.Combine(AppIconPath, @"Epic.ico"); //internal static string ShortcutIconCachePath; internal static ProfileItem GetProfile(string profileName) { // Create an array of display profiles we have - var profiles = ProfileItem.LoadAllProfiles().ToArray(); + var profiles = ProfileRepository.AllProfiles.ToArray(); // Check if the user supplied a --profile option using the profiles' ID - var profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.Id.Equals(profileName, StringComparison.InvariantCultureIgnoreCase)) : -1; + var profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.UUID.Equals(profileName, StringComparison.InvariantCultureIgnoreCase)) : -1; // If the profileID wasn't there, maybe they used the profile name? if (profileIndex == -1) { @@ -52,10 +59,9 @@ namespace HeliosPlus { internal static bool GoProfile(ProfileItem profile) { - if (profile.IsActive) - { + // If we're already on the wanted profile then no need to change! + if (ProfileRepository.IsActiveProfile(profile)) return true; - } var instanceStatus = IPCService.GetInstance().Status; @@ -68,7 +74,7 @@ namespace HeliosPlus { { Task.Factory.StartNew(() => { - if (!profile.Apply()) + if (!(ProfileRepository.ApplyProfile(profile))) { failed = true; } @@ -97,7 +103,7 @@ namespace HeliosPlus { // Get the status of the thing IPCService.GetInstance().Status = InstanceStatus.User; // Load all the profiles from JSON - ProfileItem.LoadAllProfiles().ToArray(); + //ProfileRepository.AllProfiles // Start up the DisplayProfileForm directly new DisplayProfileForm(profile).ShowDialog(); // Then we close down as we're only here to edit one profile @@ -122,33 +128,6 @@ namespace HeliosPlus { Console.WriteLine(@"Copyright © Terry MacDonald 2020-{DateTime.Today.Year}"); Console.WriteLine(@"Based on Helios Display Management - Copyright © Soroush Falahati 2017-2020"); - /*// Figure out where the shortcut's will go - ShortcutIconCachePath = Path.Combine(AppDataPath, @"ShortcutIconCache"); - - // Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program - if (!Directory.Exists(AppDataPath)) - { - try - { - Directory.CreateDirectory(ShortcutIconCachePath); - } - catch - { - } - } - - // Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program - if (!Directory.Exists(ShortcutIconCachePath)) - { - try - { - Directory.CreateDirectory(ShortcutIconCachePath); - } - catch - { - } - }*/ - var app = new CommandLineApplication(); //app.Name = "HeliosDM+"; @@ -253,6 +232,66 @@ namespace HeliosPlus { } + // Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program + if (!Directory.Exists(AppIconPath)) + { + try + { + Directory.CreateDirectory(AppIconPath); + } + catch + { + // TODO + } + } + + try + { + // Save a copy of the HeliosPlus Icon, and all the game library ones in preparation for future use + if (!File.Exists(AppHeliosPlusIconFilename)) + { + Icon heliosIcon = (Icon)Properties.Resources.HeliosPlus; + using (FileStream fs = new FileStream(AppHeliosPlusIconFilename, FileMode.Create)) + heliosIcon.Save(fs); + } + + // Save a copy of the Steam Icon, and all the game library ones in preparation for future use + if (!File.Exists(AppSteamIconFilename)) + { + Icon heliosIcon = (Icon)Properties.Resources.Steam; + using (FileStream fs = new FileStream(AppSteamIconFilename, FileMode.Create)) + heliosIcon.Save(fs); + } + + // Save a copy of the Uplay Icon, and all the game library ones in preparation for future use + if (!File.Exists(AppUplayIconFilename)) + { + Icon heliosIcon = (Icon)Properties.Resources.Uplay; + using (FileStream fs = new FileStream(AppUplayIconFilename, FileMode.Create)) + heliosIcon.Save(fs); + } + + // Save a copy of the Epic Icon, and all the game library ones in preparation for future use + if (!File.Exists(AppEpicIconFilename)) + { + Icon heliosIcon = (Icon)Properties.Resources.Epic; + using (FileStream fs = new FileStream(AppEpicIconFilename, FileMode.Create)) + heliosIcon.Save(fs); + } + + // Save a copy of the Origin Icon, and all the game library ones in preparation for future use + if (!File.Exists(AppOriginIconFilename)) + { + Icon heliosIcon = (Icon)Properties.Resources.Origin; + using (FileStream fs = new FileStream(AppOriginIconFilename, FileMode.Create)) + heliosIcon.Save(fs); + } + } + catch + { + // TODO + } + IPCService.GetInstance().Status = InstanceStatus.User; Application.Run(new UIForms.MainForm()); @@ -270,7 +309,7 @@ namespace HeliosPlus { private static void SwitchToExecutable(ProfileItem profile, string executableToRun, string processToMonitor, uint timeout, string executableArguments) { - var rollbackProfile = ProfileItem.CurrentProfile; + var rollbackProfile = ProfileRepository.CurrentProfile; if (!profile.IsPossible) { @@ -361,7 +400,8 @@ namespace HeliosPlus { IPCService.GetInstance().Status = InstanceStatus.Busy; - if (!rollbackProfile.IsActive) + // Change back to the original profile if it is different + if (!ProfileRepository.IsActiveProfile(rollbackProfile)) { if (!GoProfile(rollbackProfile)) { @@ -383,7 +423,7 @@ namespace HeliosPlus { } // Save the profile we're on now - var rollbackProfile = ProfileItem.CurrentProfile; + var rollbackProfile = ProfileRepository.CurrentProfile; // Check that the profile we've been asked to change to will actually work if (!profile.IsPossible) @@ -502,7 +542,8 @@ namespace HeliosPlus { IPCService.GetInstance().Status = InstanceStatus.Busy; - if (!rollbackProfile.IsActive) + // Change back to the original profile if it is different + if (!ProfileRepository.IsActiveProfile(rollbackProfile)) { if (!GoProfile(rollbackProfile)) { @@ -515,7 +556,7 @@ namespace HeliosPlus { private static void SwitchToUplayGame(ProfileItem profile, string uplayGameIdToRun, uint timeout, string uplayGameArguments) { - var rollbackProfile = ProfileItem.CurrentProfile; + var rollbackProfile = ProfileRepository.CurrentProfile; if (!profile.IsPossible) { @@ -629,7 +670,8 @@ namespace HeliosPlus { IPCService.GetInstance().Status = InstanceStatus.Busy; - if (!rollbackProfile.IsActive) + // Change back to the original profile if it is different + if (!ProfileRepository.IsActiveProfile(rollbackProfile)) { if (!GoProfile(rollbackProfile)) { @@ -643,7 +685,7 @@ namespace HeliosPlus { // ReSharper disable once CyclomaticComplexity private static void SwitchToProfile(ProfileItem profile) { - var rollbackProfile = ProfileItem.CurrentProfile; + var rollbackProfile = ProfileRepository.CurrentProfile; if ( IPCClient.QueryAll() diff --git a/HeliosPlus/Properties/Resources.Designer.cs b/HeliosPlus/Properties/Resources.Designer.cs index f0f0e9f..96ddb49 100644 --- a/HeliosPlus/Properties/Resources.Designer.cs +++ b/HeliosPlus/Properties/Resources.Designer.cs @@ -22,7 +22,7 @@ namespace HeliosPlus.Properties { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { + public class Resources { private static global::System.Resources.ResourceManager resourceMan; @@ -36,7 +36,7 @@ namespace HeliosPlus.Properties { /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { + public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeliosPlus.Properties.Resources", typeof(Resources).Assembly); @@ -51,7 +51,7 @@ namespace HeliosPlus.Properties { /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { + public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -63,7 +63,7 @@ namespace HeliosPlus.Properties { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon Epic { + public static System.Drawing.Icon Epic { get { object obj = ResourceManager.GetObject("Epic", resourceCulture); return ((System.Drawing.Icon)(obj)); @@ -73,7 +73,7 @@ namespace HeliosPlus.Properties { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon HeliosPlus { + public static System.Drawing.Icon HeliosPlus { get { object obj = ResourceManager.GetObject("HeliosPlus", resourceCulture); return ((System.Drawing.Icon)(obj)); @@ -83,7 +83,7 @@ namespace HeliosPlus.Properties { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon Origin { + public static System.Drawing.Icon Origin { get { object obj = ResourceManager.GetObject("Origin", resourceCulture); return ((System.Drawing.Icon)(obj)); @@ -93,7 +93,7 @@ namespace HeliosPlus.Properties { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon Steam { + public static System.Drawing.Icon Steam { get { object obj = ResourceManager.GetObject("Steam", resourceCulture); return ((System.Drawing.Icon)(obj)); @@ -103,7 +103,7 @@ namespace HeliosPlus.Properties { /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// - internal static System.Drawing.Icon Uplay { + public static System.Drawing.Icon Uplay { get { object obj = ResourceManager.GetObject("Uplay", resourceCulture); return ((System.Drawing.Icon)(obj)); diff --git a/HeliosPlus/Resources/HeliosPlus.png b/HeliosPlus/Resources/HeliosPlus.png deleted file mode 100644 index 5c64421..0000000 Binary files a/HeliosPlus/Resources/HeliosPlus.png and /dev/null differ diff --git a/HeliosPlus/ShortcutItem.cs b/HeliosPlus/ShortcutItem.cs index bc84a2d..c96aebe 100644 --- a/HeliosPlus/ShortcutItem.cs +++ b/HeliosPlus/ShortcutItem.cs @@ -102,7 +102,7 @@ namespace HeliosPlus _profileName = value; // We try to find and set the ProfileTouse - foreach (ProfileItem profileToTest in ProfileItem.AllSavedProfiles) + foreach (ProfileItem profileToTest in ProfileRepository.AllProfiles) { if (profileToTest.Name.Equals(_profileName)) _profileToUse = profileToTest; diff --git a/HeliosPlus/ShortcutRepository.cs b/HeliosPlus/ShortcutRepository.cs index 7208a4b..045b269 100644 --- a/HeliosPlus/ShortcutRepository.cs +++ b/HeliosPlus/ShortcutRepository.cs @@ -329,7 +329,7 @@ namespace HeliosPlus // Lookup all the Profile Names in the Saved Profiles foreach (ShortcutItem updatedShortcut in _allShortcuts) { - foreach (ProfileItem profile in ProfileItem.AllSavedProfiles) + foreach (ProfileItem profile in ProfileRepository.AllProfiles) { if (profile.Name.Equals(updatedShortcut.ProfileName)) diff --git a/HeliosPlus/UIForms/DisplayProfileForm.cs b/HeliosPlus/UIForms/DisplayProfileForm.cs index 396a616..3eb5055 100644 --- a/HeliosPlus/UIForms/DisplayProfileForm.cs +++ b/HeliosPlus/UIForms/DisplayProfileForm.cs @@ -81,31 +81,16 @@ namespace HeliosPlus.UIForms private void Delete_Click(object sender, EventArgs e) { - _inDialog = true; if (MessageBox.Show($"Are you sure you want to delete the '{_selectedProfile.Name}' Display Profile?", $"Delete '{_selectedProfile.Name}' Display Profile?", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No) return; - ProfileItem profileToDelete = _selectedProfile; - string profileToDeleteFilename = _selectedProfile.SavedProfileCacheFilename; - // remove the profile from the imagelistview int currentIlvIndex = ilv_saved_profiles.SelectedItems[0].Index; ilv_saved_profiles.Items.RemoveAt(currentIlvIndex); - // remove the profile from the saved profiles list - _savedProfiles.Remove(profileToDelete); - - // delete the profile image used in the image listview - // we'll delete the old PNG that we no longer need - try - { - File.Delete(profileToDeleteFilename); - } - catch (Exception ex) - { - // TODO write error to console - // TODO specify the correct the exceptions - } + // Remove the Profile + ProfileRepository.RemoveProfile(_selectedProfile); + _selectedProfile = null; // If the imageview isn't empty if (ilv_saved_profiles.Items.Count > 0) @@ -132,13 +117,10 @@ namespace HeliosPlus.UIForms { // We now only have an unsaved current profile, and no saved ones // So we need to change the mode - ChangeSelectedProfile(ProfileItem.CurrentProfile); + ChangeSelectedProfile(ProfileRepository.CurrentProfile); } - // Then save the profiles so we always have it updated - // Generating the imagelistview images automatically as we save. - ProfileItem.SaveAllProfiles(_savedProfiles); } private void RefreshDisplayProfileUI() @@ -166,7 +148,7 @@ namespace HeliosPlus.UIForms ilv_saved_profiles.Items.Add(newItem, _profileAdaptor); } - if (ProfileItem.CurrentProfile.Equals(loadedProfile)) + if (ProfileRepository.CurrentProfile.Equals(loadedProfile)) { // We have already saved the selected profile! // so we need to show the selected profile @@ -179,7 +161,7 @@ namespace HeliosPlus.UIForms // found a matching profile, then we need to show the current // Profile if (!foundCurrentProfileInLoadedProfiles) - ChangeSelectedProfile(ProfileItem.CurrentProfile); + ChangeSelectedProfile(ProfileRepository.CurrentProfile); // Check if we were loading a profile to edit // If so, select that instead of all that other stuff above! @@ -192,7 +174,7 @@ namespace HeliosPlus.UIForms // If there are no profiles at all then we are starting from scratch! // Show the profile in the DV window // Use the current profile name in the label and the save name - ChangeSelectedProfile(ProfileItem.CurrentProfile); + ChangeSelectedProfile(ProfileRepository.CurrentProfile); } // Restart updating the saved_profiles listview @@ -213,7 +195,7 @@ namespace HeliosPlus.UIForms // and the app will automatically recognise that things have changed. // Reload the profiles in case we swapped to another program to change it - ProfileItem.UpdateCurrentProfile(); + ProfileRepository.UpdateCurrentProfile(); // Refresh the Profile UI RefreshDisplayProfileUI(); } @@ -221,9 +203,9 @@ namespace HeliosPlus.UIForms private void DisplayProfileForm_Load(object sender, EventArgs e) { // Load all the profiles to prepare things - _savedProfiles = (List)ProfileItem.LoadAllProfiles(); + _savedProfiles = ProfileRepository.AllProfiles; // Update the Current Profile - ProfileItem.UpdateCurrentProfile(); + ProfileRepository.UpdateCurrentProfile(); // Refresh the Profile UI RefreshDisplayProfileUI(); } @@ -241,7 +223,7 @@ namespace HeliosPlus.UIForms // And update the save/rename textbox txt_profile_save_name.Text = _selectedProfile.Name; - if (_selectedProfile.Equals(ProfileItem.CurrentProfile)) + if (_selectedProfile.Equals(ProfileRepository.CurrentProfile)) { if (_savedProfiles.Contains(_selectedProfile)) { @@ -305,7 +287,7 @@ namespace HeliosPlus.UIForms } // Check we're not already using the name - foreach (ProfileItem savedProfile in ProfileItem.AllSavedProfiles) + foreach (ProfileItem savedProfile in ProfileRepository.AllProfiles) { //if (String.Equals(txt_profile_save_name.Text, savedProfile.Name, StringComparison.InvariantCultureIgnoreCase)) if (savedProfile.Name.Equals(txt_profile_save_name.Text)) @@ -322,7 +304,7 @@ namespace HeliosPlus.UIForms // We're in 'save' mode! // Check we're not already saving this profile - foreach (ProfileItem savedProfile in ProfileItem.AllSavedProfiles) + foreach (ProfileItem savedProfile in ProfileRepository.AllProfiles) { //if (String.Equals(txt_profile_save_name.Text, savedProfile.Name, StringComparison.InvariantCultureIgnoreCase)) if (savedProfile.Equals(_selectedProfile)) @@ -337,11 +319,10 @@ namespace HeliosPlus.UIForms // Update the name just to make sure we record it if the user changed it _selectedProfile.Name = txt_profile_save_name.Text; - // Add the current profile to the list of profiles so it gets saved later - _savedProfiles.Add(_selectedProfile); + // Add the current profile to the list of profiles so it gets saved + ProfileRepository.AddProfile(_selectedProfile); // Also update the imagelistview so that we can see the new profile we just saved - //_selectedProfile.SaveProfileImageToCache(); // Load the currentProfile image into the imagelistview //ImageListViewItem newItem = new ImageListViewItem(_selectedProfile.SavedProfileCacheFilename, _selectedProfile.Name); @@ -361,7 +342,6 @@ namespace HeliosPlus.UIForms // Lets save the old names for usage next string oldProfileName = _selectedProfile.Name; - string oldProfileCacheFilename = _selectedProfile.SavedProfileCacheFilename; // Lets rename the entry in the imagelistview to the new name foreach (ImageListViewItem myItem in ilv_saved_profiles.Items) @@ -372,30 +352,15 @@ namespace HeliosPlus.UIForms } } // Lets rename the selectedProfile to the new name - _selectedProfile.Name = txt_profile_save_name.Text; + ProfileRepository.RenameProfile(_selectedProfile, txt_profile_save_name.Text); // Lets update the rest of the profile screen too lbl_profile_shown.Text = txt_profile_save_name.Text; - - // Then we'll delete the old PNG that we renamed from so we don't get a buildup of them! - // as a new one will be created when we save later - try - { - File.Delete(oldProfileCacheFilename); - } - catch(Exception ex) - { - // TODO write error to console - // TODO specify the correct the exceptions - } + } ChangeSelectedProfile(_selectedProfile); - // Then save the profiles so we always have it updated - // Generating the imagelistview images automatically as we save. - ProfileItem.SaveAllProfiles(_savedProfiles); - // now update the profiles image listview //ilv_saved_profiles.Refresh(); @@ -416,7 +381,7 @@ namespace HeliosPlus.UIForms private void btn_view_current_Click(object sender, EventArgs e) { // Reload the profiles in case we swapped to another program to change it - ProfileItem.UpdateCurrentProfile(); + ProfileRepository.UpdateCurrentProfile(); // Refresh the Profile UI RefreshDisplayProfileUI(); } diff --git a/HeliosPlus/UIForms/ProfileAdaptor.cs b/HeliosPlus/UIForms/ProfileAdaptor.cs index 5eb930d..38ffb7a 100644 --- a/HeliosPlus/UIForms/ProfileAdaptor.cs +++ b/HeliosPlus/UIForms/ProfileAdaptor.cs @@ -47,7 +47,7 @@ namespace HeliosPlus.UIForms ProfileItem profileToUse = null; - foreach (ProfileItem profileToTest in ProfileItem.AllSavedProfiles) + foreach (ProfileItem profileToTest in ProfileRepository.AllProfiles) { if (profileToTest.Name == profileName) { @@ -58,7 +58,7 @@ namespace HeliosPlus.UIForms if (profileToUse == null) { - profileToUse = ProfileItem.CurrentProfile; + profileToUse = ProfileRepository.CurrentProfile; } Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(() => { return false; }); @@ -141,7 +141,7 @@ namespace HeliosPlus.UIForms string profileName = (string)key; ProfileItem profileToUse = null; - foreach (ProfileItem profileToTest in ProfileItem.AllSavedProfiles) + foreach (ProfileItem profileToTest in ProfileRepository.AllProfiles) { if (profileToTest.Name == profileName) { @@ -152,7 +152,7 @@ namespace HeliosPlus.UIForms if (profileToUse == null) { - profileToUse = ProfileItem.CurrentProfile; + profileToUse = ProfileRepository.CurrentProfile; } // Get file info diff --git a/HeliosPlus/UIForms/ShortcutForm.cs b/HeliosPlus/UIForms/ShortcutForm.cs index 5d95001..928299f 100644 --- a/HeliosPlus/UIForms/ShortcutForm.cs +++ b/HeliosPlus/UIForms/ShortcutForm.cs @@ -603,12 +603,12 @@ namespace HeliosPlus.UIForms { // Load all the profiles to prepare things - _loadedProfiles = (List)ProfileItem.LoadAllProfiles(); + _loadedProfiles = ProfileRepository.AllProfiles; bool foundCurrentProfileInLoadedProfiles = false; foreach (ProfileItem loadedProfile in _loadedProfiles) { - if (ProfileItem.CurrentProfile.Equals(loadedProfile)) + if (ProfileRepository.CurrentProfile.Equals(loadedProfile)) { // We have already saved the selected profile! // so we need to show the selected profile @@ -844,7 +844,7 @@ namespace HeliosPlus.UIForms // We also need to load the saved profile name to show the user lbl_profile_shown.Text = _profileToUse.Name; - if (_profileToUse.Equals(ProfileItem.CurrentProfile)) + if (_profileToUse.Equals(ProfileRepository.CurrentProfile)) { lbl_profile_shown_subtitle.Text = "(Current Display Profile in use)"; } @@ -900,7 +900,7 @@ namespace HeliosPlus.UIForms // found a matching profile, then we need to show the current // Profile if (!foundCurrentProfileInLoadedProfiles) - ChangeSelectedProfile(ProfileItem.CurrentProfile); + ChangeSelectedProfile(ProfileRepository.CurrentProfile); // Check if we were loading a profile to edit // If so, select that instead of all that other stuff above! diff --git a/HeliosPlus/Validators.cs b/HeliosPlus/Validators.cs index 1dc1232..59302ff 100644 --- a/HeliosPlus/Validators.cs +++ b/HeliosPlus/Validators.cs @@ -23,9 +23,9 @@ namespace HeliosPlus var profile = optionProfile.Value(); // Create an array of display profiles we have - var profiles = ProfileItem.LoadAllProfiles().ToArray(); + var profiles = ProfileRepository.AllProfiles.ToArray(); // Check if the user supplied a --profile option using the profiles' ID - var profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.Id.Equals(profile, StringComparison.InvariantCultureIgnoreCase)) : -1; + var profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.UUID.Equals(profile, StringComparison.InvariantCultureIgnoreCase)) : -1; // If the profileID wasn't there, maybe they used the profile name? if (profileIndex == -1) { @@ -38,7 +38,7 @@ namespace HeliosPlus return new ValidationResult($"Couldn't find Profile Name or ID supplied via command line: '{optionProfile.LongName}'. Please check the Profile Name or ID you supplied on the command line is correct."); } - Console.WriteLine($"Using Profile: '{profiles[profileIndex].Name}' (ID:{profiles[profileIndex].Id})"); + Console.WriteLine($"Using Profile: '{profiles[profileIndex].Name}' (ID:{profiles[profileIndex].UUID})"); return ValidationResult.Success; } }