2021-01-28 08:34:45 +00:00
using Newtonsoft.Json ;
2020-06-14 04:20:52 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing.IconLib ;
using System.IO ;
using System.Linq ;
using System.Text ;
using WindowsDisplayAPI.DisplayConfig ;
using NvAPIWrapper.Mosaic ;
using NvAPIWrapper.Native.Mosaic ;
using WindowsDisplayAPI ;
using System.Diagnostics ;
using System.Text.RegularExpressions ;
2020-10-10 02:18:30 +00:00
using NvAPIWrapper.Native.GPU ;
2021-06-12 21:44:36 +00:00
using DisplayMagicianShared.AMD ;
2021-06-22 09:05:24 +00:00
using DisplayMagicianShared.NVIDIA ;
2021-07-24 04:05:38 +00:00
using DisplayMagicianShared.Windows ;
2021-05-21 02:41:49 +00:00
using System.Windows.Forms ;
2020-10-04 11:18:22 +00:00
2020-12-20 07:42:04 +00:00
namespace DisplayMagicianShared
2020-06-14 04:20:52 +00:00
{
2021-03-28 07:25:01 +00:00
2020-07-21 07:50:41 +00:00
public static class ProfileRepository
2020-06-14 04:20:52 +00:00
{
#region Class Variables
// Common items to the class
2020-08-07 03:59:23 +00:00
private static List < ProfileItem > _allProfiles = new List < ProfileItem > ( ) ;
2021-03-06 04:43:07 +00:00
public static Dictionary < string , bool > _profileWarningLookup = new Dictionary < string , bool > ( ) ;
2020-08-07 03:59:23 +00:00
private static bool _profilesLoaded = false ;
2021-06-20 03:20:43 +00:00
public static Version _version = new Version ( 2 , 0 , 0 ) ;
2020-10-09 03:27:59 +00:00
private static ProfileItem _currentProfile ;
2021-03-07 04:11:46 +00:00
private static List < string > _connectedDisplayIdentifiers = new List < string > ( ) ;
2021-05-21 02:41:49 +00:00
private static bool notifiedEDIDErrorToUser = false ;
2021-06-19 22:45:45 +00:00
private static AMDLibrary AMDLibrary ;
2021-06-27 01:53:00 +00:00
//private static bool _isLoading = false;
2020-10-09 03:27:59 +00:00
2020-06-14 04:20:52 +00:00
// Other constants that are useful
2020-12-02 08:11:23 +00:00
public static string AppDataPath = System . IO . Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) , "DisplayMagician" ) ;
2020-10-06 10:49:10 +00:00
public static string AppIconPath = System . IO . Path . Combine ( AppDataPath , $"Icons" ) ;
2020-12-02 08:11:23 +00:00
public static string AppDisplayMagicianIconFilename = System . IO . Path . Combine ( AppIconPath , @"DisplayMagician.ico" ) ;
2021-01-28 09:20:00 +00:00
private static readonly string AppProfileStoragePath = System . IO . Path . Combine ( AppDataPath , $"Profiles" ) ;
private static readonly string _profileStorageJsonFileName = System . IO . Path . Combine ( AppProfileStoragePath , $"DisplayProfiles_{_version.ToString(2)}.json" ) ;
2020-10-09 03:27:59 +00:00
2020-06-14 04:20:52 +00:00
#endregion
#region Class Constructors
2020-07-21 07:50:41 +00:00
static ProfileRepository ( )
2020-06-14 04:20:52 +00:00
{
2020-07-24 01:11:42 +00:00
// Initialise the the NVIDIA NvAPIWrapper
try
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ProfileRepository: Initialising the NvAPIWrapper.NVIDIA library." ) ;
2020-07-24 01:11:42 +00:00
NvAPIWrapper . NVIDIA . Initialize ( ) ;
2021-06-14 09:42:16 +00:00
}
catch ( Exception ex )
{
SharedLogger . logger . Warn ( ex , $"ProfileRepository/ProfileRepository: Initialising NVIDIA NvAPIWrapper caused an exception." ) ;
}
2020-08-18 22:16:04 +00:00
2021-06-14 09:42:16 +00:00
// Initialise the the AMD ADLWrapper
try
{
SharedLogger . logger . Debug ( $"ProfileRepository/ProfileRepository: Initialising the AMD ADL library." ) ;
2021-06-19 22:45:45 +00:00
AMDLibrary = new AMDLibrary ( ) ;
2021-06-14 09:42:16 +00:00
}
catch ( Exception ex )
{
SharedLogger . logger . Warn ( ex , $"ProfileRepository/ProfileRepository: Initialising AMD ADL caused an exception." ) ;
}
try
{
2020-08-18 22:16:04 +00:00
// Create the Profile Storage Path if it doesn't exist so that it's avilable for all the program
if ( ! Directory . Exists ( AppProfileStoragePath ) )
{
2021-03-26 08:54:45 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ProfileRepository: Creating the Profiles storage folder {AppProfileStoragePath}." ) ;
2020-08-18 22:16:04 +00:00
Directory . CreateDirectory ( AppProfileStoragePath ) ;
}
2020-07-24 01:11:42 +00:00
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician doesn't have permissions to create the Profiles storage folder {AppProfileStoragePath}." ) ;
}
catch ( ArgumentException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the parent folder isn't there." ) ;
}
2020-07-24 01:11:42 +00:00
catch ( Exception ex )
{
2021-06-14 09:42:16 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/ProfileRepository: Exception creating the Profiles storage folder." ) ;
2020-07-24 01:11:42 +00:00
}
2020-06-14 04:20:52 +00:00
// Load the Profiles from storage
LoadProfiles ( ) ;
}
#endregion
#region Class Properties
public static List < ProfileItem > AllProfiles
{
get
{
2020-08-07 03:59:23 +00:00
if ( ! _profilesLoaded )
2020-06-14 04:20:52 +00:00
// Load the Profiles from storage if they need to be
LoadProfiles ( ) ;
return _allProfiles ;
}
}
2021-03-06 04:43:07 +00:00
public static Dictionary < string , bool > ProfileWarningLookup
2021-03-05 01:44:53 +00:00
{
get
{
if ( ! _profilesLoaded )
// Load the Profiles from storage if they need to be
LoadProfiles ( ) ;
2021-03-06 04:43:07 +00:00
return _profileWarningLookup ;
2021-03-05 01:44:53 +00:00
}
}
2020-06-14 04:20:52 +00:00
public static ProfileItem CurrentProfile
{
get
{
2020-10-09 03:27:59 +00:00
if ( _currentProfile = = null )
UpdateActiveProfile ( ) ;
2020-06-14 04:20:52 +00:00
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
{
2020-08-07 03:59:23 +00:00
if ( ! _profilesLoaded )
2020-06-15 09:57:46 +00:00
// Load the Profiles from storage if they need to be
LoadProfiles ( ) ;
2020-08-07 03:59:23 +00:00
2020-06-14 04:20:52 +00:00
return _allProfiles . Count ;
}
}
2021-03-07 04:11:46 +00:00
public static List < string > ConnectedDisplayIdentifiers
{
get
{
if ( _connectedDisplayIdentifiers . Count = = 0 )
// Load the Profiles from storage if they need to be
2021-07-24 04:05:38 +00:00
_connectedDisplayIdentifiers = GetAllConnectedDisplayIdentifiers ( ) ;
2021-03-07 04:11:46 +00:00
return _connectedDisplayIdentifiers ;
}
set
{
_connectedDisplayIdentifiers = value ;
}
}
2021-06-27 01:53:00 +00:00
public static bool ProfilesLoaded {
get
{
return _profilesLoaded ;
}
set
{
_profilesLoaded = value ;
}
}
2020-06-14 04:20:52 +00:00
#endregion
2021-03-07 04:11:46 +00:00
2020-06-14 04:20:52 +00:00
#region Class Methods
2020-08-19 06:55:50 +00:00
public static bool AddProfile ( ProfileItem profile )
2020-06-14 04:20:52 +00:00
{
2020-08-19 06:55:50 +00:00
if ( ! ( profile is ProfileItem ) )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/AddProfile: Adding profile {profile.Name} to our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Doublecheck if it already exists
// Because then we just update the one that already exists
2020-08-19 06:55:50 +00:00
if ( ! ContainsProfile ( profile ) )
2020-06-14 04:20:52 +00:00
{
// Add the Profile to the list of Profiles
2020-08-19 06:55:50 +00:00
_allProfiles . Add ( profile ) ;
2020-06-15 09:57:46 +00:00
2020-06-14 04:20:52 +00:00
// Generate the Profile Icon ready to be used
2020-08-19 06:55:50 +00:00
SaveProfileIconToCache ( profile ) ;
profile . PreSave ( ) ;
2020-06-14 04:20:52 +00:00
// Save the Profiles JSON as it's different
SaveProfiles ( ) ;
2020-08-19 06:55:50 +00:00
}
2020-06-14 04:20:52 +00:00
2021-03-05 01:44:53 +00:00
// Refresh the profiles to see whats valid
IsPossibleRefresh ( ) ;
2020-08-19 06:55:50 +00:00
//Doublecheck it's been added
if ( ContainsProfile ( profile ) )
{
2020-06-14 04:20:52 +00:00
return true ;
}
else
return false ;
}
2020-07-26 08:52:46 +00:00
2021-02-14 09:42:48 +00:00
public static bool RemoveProfile ( ProfileItem profile )
2020-06-14 04:20:52 +00:00
{
2021-02-14 09:42:48 +00:00
if ( ! ( profile is ProfileItem ) )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RemoveProfile: Removing profile {profile.Name} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Remove the Profile Icons from the Cache
2021-02-14 09:42:48 +00:00
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . UUID . Equals ( profile . UUID ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician doesn't have permissions to delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename}." ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-10 09:40:22 +00:00
catch ( ArgumentException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the parent folder isn't there." ) ;
}
2020-06-14 04:20:52 +00:00
}
// Remove the Profile from the list.
2021-02-14 09:42:48 +00:00
int numRemoved = _allProfiles . RemoveAll ( item = > item . UUID . Equals ( profile . UUID ) ) ;
2020-06-14 04:20:52 +00:00
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
2021-03-04 22:12:27 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
2021-02-14 09:42:48 +00:00
public static bool RemoveProfile ( string profileName )
2020-06-14 04:20:52 +00:00
{
2021-02-14 09:42:48 +00:00
if ( String . IsNullOrWhiteSpace ( profileName ) )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RemoveProfile2: Removing profile {profileName} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Remove the Profile Icons from the Cache
2021-02-14 09:42:48 +00:00
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . Name . Equals ( profileName ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician doesn't have permissions to delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename}." ) ;
}
catch ( ArgumentException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the parent folder isn't there." ) ;
2020-06-14 04:20:52 +00:00
}
}
// Remove the Profile from the list.
2021-02-14 09:42:48 +00:00
int numRemoved = _allProfiles . RemoveAll ( item = > item . Name . Equals ( profileName ) ) ;
2020-06-14 04:20:52 +00:00
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
2021-03-04 22:12:27 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
2021-02-14 09:42:48 +00:00
public static bool RemoveProfile ( uint profileId )
2020-06-14 04:20:52 +00:00
{
2021-02-14 09:42:48 +00:00
if ( profileId = = 0 )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RemoveProfile3: Removing profile wih profileId {profileId} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Remove the Profile Icons from the Cache
2021-02-14 09:42:48 +00:00
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . UUID . Equals ( profileId ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician doesn't have permissions to delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename}." ) ;
}
catch ( ArgumentException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the parent folder isn't there." ) ;
2020-06-14 04:20:52 +00:00
}
}
// Remove the Profile from the list.
2021-02-14 09:42:48 +00:00
int numRemoved = _allProfiles . RemoveAll ( item = > item . UUID . Equals ( profileId ) ) ;
2020-06-14 04:20:52 +00:00
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
2021-03-04 22:12:27 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
public static bool ContainsProfile ( ProfileItem Profile )
{
if ( ! ( Profile is ProfileItem ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile: Checking if our profile repository contains a profile called {Profile.Name}" ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( Profile . UUID ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile: Our profile repository does contain a profile called {Profile.Name}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile: Our profile repository doesn't contain a profile called {Profile.Name}" ) ;
2020-06-14 04:20:52 +00:00
return false ;
}
public static bool ContainsProfile ( string ProfileNameOrId )
{
if ( String . IsNullOrWhiteSpace ( ProfileNameOrId ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Checking if our profile repository contains a profile with UUID or Name {ProfileNameOrId}" ) ;
2020-06-15 09:57:46 +00:00
if ( ProfileItem . IsValidUUID ( ProfileNameOrId ) )
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Our profile repository does contain a profile with UUID {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
else
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . Name . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Our profile repository does contain a profile with Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Our profile repository doesn't contain a profile with a UUID or Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return false ;
}
2020-10-09 03:27:59 +00:00
public static bool ContainsCurrentProfile ( )
{
if ( ! ( _currentProfile is ProfileItem ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsCurrentProfile: Checking if our profile repository contains the display profile currently in use" ) ;
2020-10-09 03:27:59 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
2021-03-27 03:15:17 +00:00
// TODO - change for Equals
if ( testProfile . Equals ( _currentProfile ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsCurrentProfile: Our profile repository does contain the display profile currently in use" ) ;
2020-10-09 03:27:59 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-10-09 03:27:59 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsCurrentProfile: Our profile repository doesn't contain the display profile currently in use" ) ;
2020-10-09 03:27:59 +00:00
return false ;
}
2020-06-14 04:20:52 +00:00
public static ProfileItem GetProfile ( string ProfileNameOrId )
{
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Finding and returning {ProfileNameOrId} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
if ( String . IsNullOrWhiteSpace ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Error ( $"ProfileRepository/GetProfile: Profile to get was empty or only whitespace" ) ;
2020-06-14 04:20:52 +00:00
return null ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
2020-06-15 09:57:46 +00:00
if ( ProfileItem . IsValidUUID ( ProfileNameOrId ) )
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Returning profile with UUID {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return testProfile ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
else
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . Name . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Returning profile with Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return testProfile ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Didn't match any profiles with UUD or Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return null ;
}
public static bool RenameProfile ( ProfileItem profile , string renamedName )
{
if ( ! ( profile is ProfileItem ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Error ( $"ProfileRepository/RenameProfile: Profile to rename was empty or only whitespace" ) ;
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
}
SharedLogger . logger . Debug ( $"ProfileRepository/RenameProfile: Attempting to rename profile {profile.Name} to {renamedName}" ) ;
2020-06-14 04:20:52 +00:00
if ( ! IsValidFilename ( renamedName ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Error ( $"ProfileRepository/RenameProfile: The name the user wanted to renamed to profile to is not a valid filename" ) ;
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
profile . Name = GetValidFilename ( renamedName ) ;
2021-03-05 01:44:53 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
// If it's been added to the list of AllProfiles
// then we also need to reproduce the Icons
if ( ContainsProfile ( profile ) )
{
// Save the Profiles JSON as it's different now
SaveProfiles ( ) ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RenameProfile: The profile was successfully renamed from {profile.Name} to {renamedName}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/RenameProfile: The profile was not renamed from {profile.Name} to {renamedName}" ) ;
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
}
2021-03-04 22:12:27 +00:00
2020-06-14 04:20:52 +00:00
}
2021-03-26 08:54:45 +00:00
/ * public static void UpdateActiveProfile ( )
2020-06-14 04:20:52 +00:00
{
2020-06-15 09:57:46 +00:00
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now)." ) ;
2020-06-15 09:57:46 +00:00
ProfileItem activeProfile = new ProfileItem
2020-06-14 04:20:52 +00:00
{
Name = "Current Display Profile" ,
2020-12-20 07:42:04 +00:00
Paths = PathInfo . GetActivePaths ( ) . Select ( info = > new DisplayMagicianShared . Topology . Path ( info ) ) . ToArray ( )
2020-06-14 04:20:52 +00:00
} ;
2020-09-18 10:52:18 +00:00
activeProfile . ProfileIcon = new ProfileIcon ( activeProfile ) ;
activeProfile . ProfileBitmap = activeProfile . ProfileIcon . ToBitmap ( 256 , 256 ) ;
2020-08-19 06:55:50 +00:00
if ( _profilesLoaded & & _allProfiles . Count > 0 )
2020-06-15 09:57:46 +00:00
{
2020-08-07 03:59:23 +00:00
foreach ( ProfileItem loadedProfile in ProfileRepository . AllProfiles )
2020-06-15 09:57:46 +00:00
{
2020-10-09 03:27:59 +00:00
if ( activeProfile . Paths . SequenceEqual ( loadedProfile . Paths ) )
2020-08-07 03:59:23 +00:00
{
_currentProfile = loadedProfile ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The profile {loadedProfile.Name} is currently active (in use now)." ) ;
2020-08-07 03:59:23 +00:00
return ;
}
2020-06-15 09:57:46 +00:00
}
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The current profile is a new profile that doesn't already exist in the Profile Repository." ) ;
2020-06-15 09:57:46 +00:00
_currentProfile = activeProfile ;
2021-03-05 01:44:53 +00:00
//IsPossibleRefresh();
2021-03-26 08:54:45 +00:00
} * /
public static void UpdateActiveProfile ( )
{
2021-06-19 22:45:45 +00:00
2021-06-20 05:13:21 +00:00
ProfileItem activeProfile ;
2021-06-22 09:05:24 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now)." ) ;
2021-07-24 04:05:38 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: Attempting to access configuration through NVIDIA, then AMD, then Windows CCD interfaces, in that order." ) ;
if ( NVIDIALibrary . GetLibrary ( ) . IsInstalled )
{
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: NVIDIA NVAPI Driver is installed, so using that for this display profile." ) ;
NVIDIAProfileItem nvidiaProfile = new NVIDIAProfileItem
{
Name = "Current NVIDIA Display Profile" ,
//ProfileData = amdLibrary.GetActiveProfile(),
//Screens = amdLibrary.GenerateScreenPositions()
//ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers()
} ;
//activeProfile.ProfileIcon = new ProfileIcon(activeProfile);
//activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256);
nvidiaProfile . CreateProfileFromCurrentDisplaySettings ( ) ;
activeProfile = nvidiaProfile ;
}
else if ( AMDLibrary . GetLibrary ( ) . IsInstalled )
{
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: NVIDIA is not installed but the AMD ADL Driver IS installed, so using that for this display profile." ) ;
2021-06-26 09:54:11 +00:00
AMDProfileItem amdProfile = new AMDProfileItem
2021-06-20 05:13:21 +00:00
{
2021-07-24 04:05:38 +00:00
Name = "Current AMD Display Profile" ,
2021-06-26 09:54:11 +00:00
//ProfileData = amdLibrary.GetActiveProfile(),
//Screens = amdLibrary.GenerateScreenPositions()
2021-06-20 05:13:21 +00:00
//ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers()
2021-06-25 09:52:02 +00:00
} ;
//activeProfile.ProfileIcon = new ProfileIcon(activeProfile);
//activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256);
2021-06-26 09:54:11 +00:00
amdProfile . CreateProfileFromCurrentDisplaySettings ( ) ;
activeProfile = amdProfile ;
2021-06-19 22:45:45 +00:00
}
2021-06-25 09:52:02 +00:00
else {
2021-07-24 04:05:38 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: Neither NVIDIA NVAPI or AMD ADL Drivers are installed, so using the built in Windows CCD library interface for this display profile." ) ;
WinProfileItem winProfile = new WinProfileItem
2021-06-25 09:52:02 +00:00
{
2021-07-24 04:05:38 +00:00
Name = "Current Windows Display Profile" ,
//Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray(),
2021-06-25 09:52:02 +00:00
//ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers()
} ;
2021-06-19 22:45:45 +00:00
2021-07-24 04:05:38 +00:00
//WinProfile.ProfileIcon = new ProfileIcon(activeProfile);
//activeProfile.ProfileBitmap = activeProfile.ProfileIcon.ToBitmap(256, 256);
winProfile . CreateProfileFromCurrentDisplaySettings ( ) ;
activeProfile = winProfile ;
2021-06-25 09:52:02 +00:00
}
2021-03-26 08:54:45 +00:00
2021-06-25 09:52:02 +00:00
2020-06-14 04:20:52 +00:00
2021-03-26 08:54:45 +00:00
if ( _profilesLoaded & & _allProfiles . Count > 0 )
{
foreach ( ProfileItem loadedProfile in ProfileRepository . AllProfiles )
{
if ( activeProfile . Equals ( loadedProfile ) )
{
_currentProfile = loadedProfile ;
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The profile {loadedProfile.Name} is currently active (in use now)." ) ;
return ;
}
}
}
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The current profile is a new profile that doesn't already exist in the Profile Repository." ) ;
_currentProfile = activeProfile ;
//IsPossibleRefresh();
}
2020-06-14 04:20:52 +00:00
public static ProfileItem GetActiveProfile ( )
{
if ( ! ( _currentProfile is ProfileItem ) )
return null ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GetActiveProfile: Retrieving the currently active profile." ) ;
2020-06-14 04:20:52 +00:00
return _currentProfile ;
}
public static bool IsActiveProfile ( ProfileItem profile )
{
if ( ! ( _currentProfile is ProfileItem ) )
return false ;
if ( ! ( profile is ProfileItem ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/IsActiveProfile: Checking whether the profile {profile.Name} is the currently active profile." ) ;
2021-03-26 08:54:45 +00:00
if ( profile . Equals ( _currentProfile ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/IsActiveProfile: The profile {profile.Name} is the currently active profile." ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/IsActiveProfile: The profile {profile.Name} is not the currently active profile." ) ;
2020-06-14 04:20:52 +00:00
return false ;
}
2020-10-10 04:50:27 +00:00
2020-06-14 04:20:52 +00:00
private static bool LoadProfiles ( )
{
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: Loading profiles from {_profileStorageJsonFileName} into the Profile Repository" ) ;
2020-06-14 04:20:52 +00:00
if ( File . Exists ( _profileStorageJsonFileName ) )
{
2021-02-20 09:03:19 +00:00
string json = "" ;
try
{
json = File . ReadAllText ( _profileStorageJsonFileName , Encoding . Unicode ) ;
}
catch ( Exception ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/LoadProfiles: Tried to read the JSON file {_profileStorageJsonFileName} to memory but File.ReadAllTextthrew an exception." ) ;
}
2020-06-14 04:20:52 +00:00
if ( ! string . IsNullOrWhiteSpace ( json ) )
{
2021-02-14 09:42:48 +00:00
try
2020-06-14 04:20:52 +00:00
{
_allProfiles = JsonConvert . DeserializeObject < List < ProfileItem > > ( json , new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling . Ignore ,
NullValueHandling = NullValueHandling . Ignore ,
DefaultValueHandling = DefaultValueHandling . Include ,
2020-06-15 09:57:46 +00:00
TypeNameHandling = TypeNameHandling . Auto ,
ObjectCreationHandling = ObjectCreationHandling . Replace
2020-06-14 04:20:52 +00:00
} ) ;
}
2021-02-14 09:42:48 +00:00
catch ( Exception ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/LoadProfiles: Tried to parse the JSON in the {_profileStorageJsonFileName} but the JsonConvert threw an exception." ) ;
2020-06-14 04:20:52 +00:00
}
2021-06-22 09:05:24 +00:00
ProfileItem myCurrentProfile = new NVIDIAProfileItem
2020-06-14 04:20:52 +00:00
{
Name = "Current Display Profile" ,
2020-12-20 07:42:04 +00:00
Paths = PathInfo . GetActivePaths ( ) . Select ( info = > new DisplayMagicianShared . Topology . Path ( info ) ) . ToArray ( )
2020-06-14 04:20:52 +00:00
} ;
_currentProfile = myCurrentProfile ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: Finding the current profile in the Profile Repository" ) ;
2021-06-27 01:53:00 +00:00
// Go through all the profiles and set up the needed structures (such as the Screens list)
// and check if the current profile is used
2020-06-15 09:57:46 +00:00
foreach ( ProfileItem loadedProfile in _allProfiles )
2020-06-14 04:20:52 +00:00
{
2021-06-27 01:53:00 +00:00
if ( loadedProfile . Driver . Equals ( "AMD" ) )
{
AMDProfileItem amdLoadedProfile = ( AMDProfileItem ) loadedProfile ;
amdLoadedProfile . PerformPostLoadingTasks ( ) ;
}
2020-06-14 04:20:52 +00:00
if ( ProfileRepository . IsActiveProfile ( loadedProfile ) )
_currentProfile = loadedProfile ;
}
2020-10-26 01:30:00 +00:00
// Sort the profiles alphabetically
_allProfiles . Sort ( ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-15 07:33:46 +00:00
else
{
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: The {_profileStorageJsonFileName} profile JSON file exists but is empty! So we're going to treat it as if it didn't exist." ) ;
UpdateActiveProfile ( ) ;
}
2021-02-10 09:40:22 +00:00
}
else
2020-06-14 04:20:52 +00:00
{
// If we get here, then we don't have any profiles saved!
// So we gotta start from scratch
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: Couldn't find the {_profileStorageJsonFileName} profile JSON file that contains the Profiles" ) ;
UpdateActiveProfile ( ) ;
2020-06-14 04:20:52 +00:00
}
2020-08-07 03:59:23 +00:00
_profilesLoaded = true ;
2021-03-07 04:11:46 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
public static bool SaveProfiles ( )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Attempting to save the profiles repository to the {AppProfileStoragePath}." ) ;
2020-06-14 04:20:52 +00:00
2020-08-18 22:16:04 +00:00
if ( ! Directory . Exists ( AppProfileStoragePath ) )
2020-06-14 04:20:52 +00:00
{
try
{
2020-08-18 22:16:04 +00:00
Directory . CreateDirectory ( AppProfileStoragePath ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician doesn't have permissions to create the Profiles storage folder {AppProfileStoragePath}." ) ;
}
catch ( ArgumentException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the parent folder isn't there." ) ;
2020-06-14 04:20:52 +00:00
}
}
2021-02-15 07:33:46 +00:00
else
{
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Profiles folder {AppProfileStoragePath} exists." ) ;
}
2020-06-14 04:20:52 +00:00
try
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Converting the objects to JSON format." ) ;
2020-06-14 04:20:52 +00:00
var json = JsonConvert . SerializeObject ( _allProfiles , Formatting . Indented , new JsonSerializerSettings
{
NullValueHandling = NullValueHandling . Include ,
DefaultValueHandling = DefaultValueHandling . Populate ,
TypeNameHandling = TypeNameHandling . Auto
} ) ;
if ( ! string . IsNullOrWhiteSpace ( json ) )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Saving the profile repository to the {_profileStorageJsonFileName}." ) ;
2020-06-14 04:20:52 +00:00
File . WriteAllText ( _profileStorageJsonFileName , json , Encoding . Unicode ) ;
return true ;
}
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/SaveProfiles: Unable to save the profile repository to the {_profileStorageJsonFileName}." ) ;
2020-06-14 04:20:52 +00:00
}
return false ;
}
private static void SaveProfileIconToCache ( ProfileItem profile )
{
// Work out the name of the Profile we'll save.
2020-10-06 10:49:10 +00:00
profile . SavedProfileIconCacheFilename = System . IO . Path . Combine ( AppProfileStoragePath , string . Concat ( @"profile-" , profile . UUID , @".ico" ) ) ;
2020-06-14 04:20:52 +00:00
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfileIconToCache: Attempting to save the profile icon {profile.SavedProfileIconCacheFilename} to the {AppProfileStoragePath} folder" ) ;
2020-06-14 04:20:52 +00:00
MultiIcon ProfileIcon ;
try
{
ProfileIcon = profile . ProfileIcon . ToIcon ( ) ;
ProfileIcon . Save ( profile . SavedProfileIconCacheFilename , MultiIconFormat . ICO ) ;
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/SaveProfileIconToCache: Exception saving the profile icon {profile.SavedProfileIconCacheFilename} to the {AppProfileStoragePath} folder. Using the default DisplayMagician icon instead" ) ;
2020-12-02 08:11:23 +00:00
// If we fail to create an icon based on the Profile, then we use the standard DisplayMagician profile one.
2020-06-14 04:20:52 +00:00
// Which is created on program startup.
2020-12-02 08:11:23 +00:00
File . Copy ( AppDisplayMagicianIconFilename , profile . SavedProfileIconCacheFilename ) ;
2020-06-14 04:20:52 +00:00
}
}
2021-03-04 21:34:51 +00:00
public static void IsPossibleRefresh ( )
2021-02-28 08:24:12 +00:00
{
// We need to refresh the cached answer
// Get the list of connected devices
2021-07-24 04:05:38 +00:00
ConnectedDisplayIdentifiers = GetAllConnectedDisplayIdentifiers ( ) ;
2021-03-07 04:11:46 +00:00
2021-02-28 08:24:12 +00:00
if ( _profilesLoaded & & _allProfiles . Count > 0 )
{
2021-03-05 01:44:53 +00:00
2021-02-28 08:24:12 +00:00
foreach ( ProfileItem loadedProfile in AllProfiles )
2021-03-07 04:11:46 +00:00
loadedProfile . RefreshPossbility ( ) ;
2021-02-28 08:24:12 +00:00
}
}
2020-10-06 10:49:10 +00:00
2021-07-24 04:05:38 +00:00
public static List < string > GetAllConnectedDisplayIdentifiers ( )
2020-06-14 04:20:52 +00:00
{
2021-07-24 04:05:38 +00:00
if ( NVIDIALibrary . GetLibrary ( ) . IsInstalled )
2021-06-07 09:41:48 +00:00
{
2021-07-24 04:05:38 +00:00
return NVIDIALibrary . GetLibrary ( ) . GetAllConnectedDisplayIdentifiers ( ) ;
2020-10-10 04:50:27 +00:00
}
2021-07-24 04:05:38 +00:00
else if ( AMDLibrary . GetLibrary ( ) . IsInstalled )
2021-02-07 01:42:17 +00:00
{
2021-07-24 04:05:38 +00:00
return AMDLibrary . GetLibrary ( ) . GetAllConnectedDisplayIdentifiers ( ) ;
2021-02-07 01:42:17 +00:00
}
2021-07-24 04:05:38 +00:00
else
2020-10-10 04:50:27 +00:00
{
2021-07-24 04:05:38 +00:00
return WinLibrary . GetLibrary ( ) . GetAllConnectedDisplayIdentifiers ( ) ;
2020-10-06 07:59:59 +00:00
}
}
2020-10-02 05:10:34 +00:00
2021-07-24 04:05:38 +00:00
public static List < string > GetCurrentDisplayIdentifiers ( )
2020-10-06 07:59:59 +00:00
{
2021-07-24 04:05:38 +00:00
if ( NVIDIALibrary . GetLibrary ( ) . IsInstalled )
2020-10-06 07:59:59 +00:00
{
2021-07-24 04:05:38 +00:00
return NVIDIALibrary . GetLibrary ( ) . GetCurrentDisplayIdentifiers ( ) ;
2020-10-10 02:18:30 +00:00
}
2021-07-24 04:05:38 +00:00
else if ( AMDLibrary . GetLibrary ( ) . IsInstalled )
2021-02-07 01:42:17 +00:00
{
2021-07-24 04:05:38 +00:00
return AMDLibrary . GetLibrary ( ) . GetCurrentDisplayIdentifiers ( ) ;
2021-02-07 01:42:17 +00:00
}
2020-10-06 07:59:59 +00:00
else
2020-10-02 05:10:34 +00:00
{
2021-07-24 04:05:38 +00:00
return WinLibrary . GetLibrary ( ) . GetCurrentDisplayIdentifiers ( ) ;
2020-10-02 05:10:34 +00:00
}
2021-07-24 04:05:38 +00:00
}
2020-10-06 07:59:59 +00:00
2021-03-26 10:55:35 +00:00
2020-10-02 05:10:34 +00:00
2021-07-24 04:05:38 +00:00
/ * public static bool ApplyNVIDIAGridTopology ( NVIDIAProfileItem profile )
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyNVIDIAGridTopology: Attempting to apply NVIDIA Grid Topology" ) ;
2020-10-04 10:01:03 +00:00
2021-06-22 09:05:24 +00:00
if ( ! ( profile is NVIDIAProfileItem ) )
2020-10-04 10:01:03 +00:00
return false ;
2020-10-02 05:10:34 +00:00
try
{
var surroundTopologies =
2020-10-07 08:32:12 +00:00
profile . Paths . SelectMany ( paths = > paths . TargetDisplays )
2020-10-02 05:10:34 +00:00
. Select ( target = > target . SurroundTopology )
. Where ( topology = > topology ! = null )
. Select ( topology = > topology . ToGridTopology ( ) )
. ToArray ( ) ;
if ( surroundTopologies . Length = = 0 )
{
2020-10-07 08:58:05 +00:00
// The profile we're changing to does not use NVIDIA Surround
// So we need to set the Grid Topologies to individual screens
// in preparation for the PathInfo step later
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyNVIDIAGridTopology: Changing NVIDIA Grid Topology to individual screens so that we can move them to their final positions in a subsequent step" ) ;
2020-10-02 05:10:34 +00:00
var currentTopologies = GridTopology . GetGridTopologies ( ) ;
if ( currentTopologies . Any ( topology = > topology . Rows * topology . Columns > 1 ) )
{
surroundTopologies =
GridTopology . GetGridTopologies ( )
. SelectMany ( topology = > topology . Displays )
. Select ( displays = > new GridTopology ( 1 , 1 , new [ ] { displays } ) )
. ToArray ( ) ;
2020-10-07 08:32:12 +00:00
GridTopology . SetGridTopologies ( surroundTopologies , SetDisplayTopologyFlag . MaximizePerformance ) ;
2020-10-02 05:10:34 +00:00
}
2020-10-04 10:01:03 +00:00
} else if ( surroundTopologies . Length > 0 )
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyNVIDIAGridTopology: Changing NVIDIA Grid Topology to a surround screen so that we can move it to its final positions in a subsequent step" ) ;
2020-10-04 10:01:03 +00:00
// This profile is an NVIDIA Surround profile
2020-10-02 05:10:34 +00:00
GridTopology . SetGridTopologies ( surroundTopologies , SetDisplayTopologyFlag . MaximizePerformance ) ;
}
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyNVIDIAGridTopology: NVIDIA Grid Topology successfully changed" ) ;
2020-10-04 10:01:03 +00:00
return true ;
2020-10-02 05:10:34 +00:00
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/ApplyNVIDIAGridTopology: Exception attempting to apply a change to the NVIDIA Grid Topology." ) ;
2020-10-04 10:01:03 +00:00
return false ;
2020-10-02 05:10:34 +00:00
}
}
2021-06-22 09:05:24 +00:00
public static bool ApplyWindowsDisplayPathInfo ( NVIDIAProfileItem profile )
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyWindowsDisplayPathInfo: Moving display screens to where they are supposed to be with this display profile" ) ;
2020-10-04 10:01:03 +00:00
if ( ! ( profile is ProfileItem ) )
return false ;
2020-10-02 05:10:34 +00:00
2020-10-04 10:01:03 +00:00
try
2020-10-02 05:10:34 +00:00
{
2020-10-07 08:32:12 +00:00
var pathInfos = profile . Paths . Select ( paths = > paths . ToPathInfo ( ) ) . Where ( info = > info ! = null ) . ToArray ( ) ;
2020-10-07 07:08:36 +00:00
PathInfo . ApplyPathInfos ( pathInfos , true , true , true ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyWindowsDisplayPathInfo: Successfully moved display screens to where they are supposed to be" ) ;
2020-10-04 10:01:03 +00:00
return true ;
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/ApplyWindowsDisplayPathInfo: Exception attempting to move the display screens to where they are supposed to be in this display profile." ) ;
2020-10-04 10:01:03 +00:00
return false ;
2020-10-02 05:10:34 +00:00
}
2021-07-24 04:05:38 +00:00
} * /
2020-07-23 06:31:00 +00:00
2020-06-14 04:20:52 +00:00
public static bool IsValidFilename ( string testName )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/IsValidFilename: Checking whether {testName} is a valid filename" ) ;
2020-10-06 10:49:10 +00:00
string strTheseAreInvalidFileNameChars = new string ( System . IO . Path . GetInvalidFileNameChars ( ) ) ;
2020-06-14 04:20:52 +00:00
Regex regInvalidFileName = new Regex ( "[" + Regex . Escape ( strTheseAreInvalidFileNameChars ) + "]" ) ;
2021-02-15 07:33:46 +00:00
if ( regInvalidFileName . IsMatch ( testName ) ) {
SharedLogger . logger . Trace ( $"ProfileRepository/IsValidFilename: {testName} is a valid filename" ) ;
return false ;
}
else
{
SharedLogger . logger . Debug ( $"ProfileRepository/IsValidFilename: {testName} isn't a valid filename as it contains one of these characters [" + Regex . Escape ( strTheseAreInvalidFileNameChars ) + "]" ) ;
return true ;
}
2020-06-14 04:20:52 +00:00
}
public static string GetValidFilename ( string uncheckedFilename )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/GetValidFilename: Modifying filename {uncheckedFilename} to be a valid filename for this filesystem" ) ;
2020-10-06 10:49:10 +00:00
string invalid = new string ( System . IO . Path . GetInvalidFileNameChars ( ) ) + new string ( System . IO . Path . GetInvalidPathChars ( ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( char c in invalid )
{
uncheckedFilename = uncheckedFilename . Replace ( c . ToString ( ) , "" ) ;
}
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/GetValidFilename: Modified filename {uncheckedFilename} so it is a valid filename for this filesystem" ) ;
2020-06-14 04:20:52 +00:00
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 ) { }
}
}
2020-10-06 07:59:59 +00:00