2020-05-03 08:39:35 +00:00
using System ;
using System.IO ;
using System.Collections.Generic ;
using System.Linq ;
using System.Reflection ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
using HeliosPlus.Resources ;
using HeliosPlus.Shared ;
2020-05-09 13:02:07 +00:00
using System.Drawing ;
using System.Drawing.Drawing2D ;
using System.Globalization ;
2020-05-10 10:47:18 +00:00
using Manina.Windows.Forms ;
using System.Text.RegularExpressions ;
2020-05-03 08:39:35 +00:00
namespace HeliosPlus.UIForms
{
internal partial class DisplayProfileForm : Form
{
private const string GroupActive = "active" ;
private const string GroupCurrent = "current" ;
private const string GroupSaved = "saved" ;
2020-05-09 13:02:07 +00:00
private Profile _selectedProfile ;
private List < Profile > _savedProfiles = new List < Profile > ( ) ;
private string _saveOrRenameMode = "save" ;
2020-05-15 03:41:01 +00:00
private static bool _inDialog = false ;
2020-05-12 10:46:23 +00:00
2020-05-03 08:39:35 +00:00
public DisplayProfileForm ( )
{
InitializeComponent ( ) ;
2020-05-11 11:11:26 +00:00
this . AcceptButton = this . btn_save_or_rename ;
2020-05-03 08:39:35 +00:00
}
private void Apply_Click ( object sender , EventArgs e )
{
2020-05-13 11:04:18 +00:00
if ( ! _selectedProfile . IsPossible )
2020-05-03 08:39:35 +00:00
{
2020-05-13 11:04:18 +00:00
MessageBox . Show ( this , Language . This_profile_is_currently_impossible_to_apply ,
Language . Apply_Profile ,
MessageBoxButtons . OK , MessageBoxIcon . Warning ) ;
2020-05-03 08:39:35 +00:00
2020-05-13 11:04:18 +00:00
return ;
}
2020-05-03 08:39:35 +00:00
2020-05-13 11:04:18 +00:00
if (
new SplashForm (
( ) = >
{
Task . Factory . StartNew ( ( ) = > _selectedProfile . Apply ( ) , TaskCreationOptions . LongRunning ) ;
} , 3 , 30 ) . ShowDialog ( this ) ! =
DialogResult . Cancel )
{
// nothing to do
Console . WriteLine ( "Applying profile " + _selectedProfile . Name ) ;
}
2020-05-03 08:39:35 +00:00
2020-05-13 11:04:18 +00:00
Activate ( ) ;
2020-05-03 08:39:35 +00:00
}
private void Exit_Click ( object sender , EventArgs e )
{
this . Close ( ) ;
}
private void Delete_Click ( object sender , EventArgs e )
{
2020-05-15 03:41:01 +00:00
_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 ;
2020-05-12 10:46:23 +00:00
Profile 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
2020-05-03 08:39:35 +00:00
{
2020-05-12 10:46:23 +00:00
File . Delete ( profileToDeleteFilename ) ;
}
catch ( Exception ex )
{
// TODO write error to console
// TODO specify the correct the exceptions
}
2020-05-03 08:39:35 +00:00
2020-05-12 10:46:23 +00:00
// If the imageview isn't empty
if ( ilv_saved_profiles . Items . Count > 0 )
{
// set the new selected profile as the next one in the imagelistview
// or the new end one if we deleted the last one before
int ilvItemToSelect = currentIlvIndex ;
if ( ilv_saved_profiles . Items . Count < currentIlvIndex + 1 )
ilvItemToSelect = ilv_saved_profiles . Items . Count - 1 ;
// Set the nearest profile image as selected
ilv_saved_profiles . Items [ ilvItemToSelect ] . Selected = true ;
// select the
foreach ( Profile newSelectedProfile in _savedProfiles )
2020-05-03 08:39:35 +00:00
{
2020-05-12 10:46:23 +00:00
if ( newSelectedProfile . Name . Equals ( ilv_saved_profiles . Items [ ilvItemToSelect ] . Text ) )
{
ChangeSelectedProfile ( newSelectedProfile ) ;
}
2020-05-03 08:39:35 +00:00
}
2020-05-12 10:46:23 +00:00
}
else
{
// We now only have an unsaved current profile, and no saved ones
// So we need to change the mode
ChangeSelectedProfile ( Profile . CurrentProfile ) ;
2020-05-03 08:39:35 +00:00
2020-05-12 10:46:23 +00:00
}
// Then save the profiles so we always have it updated
// Generating the imagelistview images automatically as we save.
Profile . SaveAllProfiles ( _savedProfiles ) ;
2020-05-03 08:39:35 +00:00
}
2020-05-15 03:41:01 +00:00
private void RefreshDisplayProfileUI ( )
2020-05-03 08:39:35 +00:00
{
2020-05-15 03:41:01 +00:00
if ( ! _inDialog )
2020-05-03 08:39:35 +00:00
{
2020-05-15 03:41:01 +00:00
// Temporarily stop updating the saved_profiles listview
ilv_saved_profiles . SuspendLayout ( ) ;
2020-05-03 08:39:35 +00:00
2020-05-15 03:41:01 +00:00
if ( _savedProfiles . Count > 0 )
2020-05-03 08:39:35 +00:00
{
2020-05-15 03:41:01 +00:00
ImageListViewItem newItem = null ;
bool foundCurrentProfileInLoadedProfiles = false ;
foreach ( Profile loadedProfile in _savedProfiles )
{
bool thisLoadedProfileIsAlreadyHere = ( from item in ilv_saved_profiles . Items where item . Text = = loadedProfile . Name select item . Text ) . Any ( ) ;
if ( ! thisLoadedProfileIsAlreadyHere )
{
loadedProfile . SaveProfileImageToCache ( ) ;
newItem = new ImageListViewItem ( loadedProfile . SavedProfileCacheFilename , loadedProfile . Name ) ;
ilv_saved_profiles . Items . Add ( newItem ) ;
}
if ( Profile . CurrentProfile . Equals ( loadedProfile ) )
{
// We have already saved the selected profile!
// so we need to show the selected profile
ChangeSelectedProfile ( loadedProfile ) ;
foundCurrentProfileInLoadedProfiles = true ;
}
}
// If we get to the end of the loaded profiles and haven't
// found a matching profile, then we need to show the current
// Profile
if ( ! foundCurrentProfileInLoadedProfiles )
ChangeSelectedProfile ( Profile . CurrentProfile ) ;
}
else
{
// 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 ( Profile . CurrentProfile ) ;
2020-05-03 08:39:35 +00:00
}
2020-05-15 03:41:01 +00:00
// Restart updating the saved_profiles listview
ilv_saved_profiles . ResumeLayout ( ) ;
}
else
// Otherwise turn off the dialog mode we were just in
_inDialog = false ;
2020-05-03 08:39:35 +00:00
}
2020-05-15 03:41:01 +00:00
private void DisplayProfileForm_Activated ( object sender , EventArgs e )
2020-05-03 08:39:35 +00:00
{
2020-05-15 03:41:01 +00:00
// We handle the UI updating in DisplayProfileForm_Activated so that
// the app will check for changes to the current profile when the
// user clicks back to this app. This is designed to allow people to
// alter their Windows Display settings then come back to our app
// and the app will automatically recognise that things have changed.
2020-05-03 08:39:35 +00:00
// Reload the profiles in case we swapped to another program to change it
2020-05-15 03:41:01 +00:00
Profile . UpdateCurrentProfile ( ) ;
// Refresh the Profile UI
RefreshDisplayProfileUI ( ) ;
2020-05-03 08:39:35 +00:00
}
2020-05-15 03:41:01 +00:00
private void DisplayProfileForm_Load ( object sender , EventArgs e )
2020-05-03 08:39:35 +00:00
{
2020-05-15 03:41:01 +00:00
// Load all the profiles to prepare things
2020-05-10 10:47:18 +00:00
_savedProfiles = ( List < Profile > ) Profile . LoadAllProfiles ( ) ;
2020-05-15 03:41:01 +00:00
// Update the Current Profile
Profile . UpdateCurrentProfile ( ) ;
// Refresh the Profile UI
RefreshDisplayProfileUI ( ) ;
2020-05-03 08:39:35 +00:00
}
2020-05-10 10:47:18 +00:00
private void ChangeSelectedProfile ( Profile profile )
2020-05-09 13:02:07 +00:00
{
2020-05-10 10:47:18 +00:00
// And we need to update the actual selected profile too!
_selectedProfile = profile ;
2020-05-11 11:11:26 +00:00
// We also need to load the saved profile name to show the user
lbl_profile_shown . Text = _selectedProfile . Name ;
// And update the save/rename textbox
txt_profile_save_name . Text = _selectedProfile . Name ;
2020-05-15 03:41:01 +00:00
if ( _selectedProfile . Equals ( Profile . CurrentProfile ) )
2020-05-11 11:11:26 +00:00
{
if ( _savedProfiles . Contains ( _selectedProfile ) )
{
_saveOrRenameMode = "rename" ;
btn_save_or_rename . Text = "Rename To" ;
2020-05-14 10:38:31 +00:00
lbl_profile_shown_subtitle . Text = "(Current Display Profile in use)" ;
2020-05-11 11:11:26 +00:00
}
else
{
_saveOrRenameMode = "save" ;
btn_save_or_rename . Text = "Save As" ;
2020-05-14 10:38:31 +00:00
lbl_profile_shown_subtitle . Text = "(Current Display Profile in use - UNSAVED)" ;
2020-05-11 11:11:26 +00:00
}
btn_apply . Visible = false ;
}
else
{
_saveOrRenameMode = "rename" ;
btn_save_or_rename . Text = "Rename To" ;
if ( ! _selectedProfile . IsPossible )
{
lbl_profile_shown_subtitle . Text = "(Display Profile is not valid so cannot be used)" ;
btn_apply . Visible = false ;
}
else
{
lbl_profile_shown_subtitle . Text = "" ;
btn_apply . Visible = true ;
}
}
2020-05-15 03:41:01 +00:00
// Refresh the image list view
RefreshImageListView ( profile ) ;
2020-05-10 10:47:18 +00:00
// And finally show the profile in the display view
dv_profile . Profile = profile ;
dv_profile . Refresh ( ) ;
2020-05-15 03:41:01 +00:00
2020-05-10 10:47:18 +00:00
}
2020-05-09 13:02:07 +00:00
2020-05-15 03:41:01 +00:00
private void RefreshImageListView ( Profile profile )
{
ilv_saved_profiles . ClearSelection ( ) ;
IEnumerable < ImageListViewItem > matchingImageListViewItems = ( from item in ilv_saved_profiles . Items where item . Text = = profile . Name select item ) ;
if ( matchingImageListViewItems . Any ( ) )
{
matchingImageListViewItems . First ( ) . Selected = true ;
matchingImageListViewItems . First ( ) . Focused = true ;
}
}
2020-05-10 10:47:18 +00:00
private 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 ;
}
2020-05-09 13:02:07 +00:00
2020-05-10 10:47:18 +00:00
private void btn_save_as_Click ( object sender , EventArgs e )
2020-05-09 13:02:07 +00:00
{
2020-05-10 10:47:18 +00:00
// Check the name is valid
if ( ! IsValidFilename ( txt_profile_save_name . Text ) )
{
MessageBox . Show ( "The profile name cannot contain the following characters:" + Path . GetInvalidFileNameChars ( ) , "Invalid characters in profile name" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
}
2020-05-11 11:11:26 +00:00
// Check we're not already using the name
foreach ( Profile savedProfile in Profile . AllSavedProfiles )
2020-05-10 10:47:18 +00:00
{
2020-05-11 11:11:26 +00:00
//if (String.Equals(txt_profile_save_name.Text, savedProfile.Name, StringComparison.InvariantCultureIgnoreCase))
if ( savedProfile . Name . Equals ( txt_profile_save_name . Text ) )
2020-05-10 10:47:18 +00:00
{
2020-05-11 11:11:26 +00:00
MessageBox . Show ( "Sorry, each saved display profile needs a unique name." , "Profile name already exists" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
2020-05-10 10:47:18 +00:00
}
2020-05-11 11:11:26 +00:00
}
// If we're saving the current profile as a new item
// then we'll be in "save" mode
if ( _saveOrRenameMode = = "save" )
{
2020-05-10 10:47:18 +00:00
// We're in 'save' mode!
2020-05-12 10:46:23 +00:00
// Check we're not already saving this profile
foreach ( Profile savedProfile in Profile . AllSavedProfiles )
{
//if (String.Equals(txt_profile_save_name.Text, savedProfile.Name, StringComparison.InvariantCultureIgnoreCase))
if ( savedProfile . Equals ( _selectedProfile ) )
{
MessageBox . Show ( $"Sorry, this display profile was already saved as '{savedProfile.Name}'." , "Profile already saved" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
}
}
2020-05-11 11:11:26 +00:00
// So we've already passed the check that says this profile is unique
2020-05-12 10:46:23 +00:00
// Update the name just to make sure we record it if the user changed it
_selectedProfile . Name = txt_profile_save_name . Text ;
2020-05-11 11:11:26 +00:00
// Add the current profile to the list of profiles so it gets saved later
2020-05-10 10:47:18 +00:00
_savedProfiles . Add ( _selectedProfile ) ;
2020-05-11 11:11:26 +00:00
2020-05-12 10:46:23 +00:00
// Also update the imagelistview so that we can see the new profile we just saved
_selectedProfile . SaveProfileImageToCache ( ) ;
2020-05-10 10:47:18 +00:00
// Load the currentProfile image into the imagelistview
ImageListViewItem newItem = new ImageListViewItem ( _selectedProfile . SavedProfileCacheFilename , _selectedProfile . Name ) ;
newItem . Selected = true ;
2020-05-12 10:46:23 +00:00
ilv_saved_profiles . Items . Add ( newItem ) ;
2020-05-10 10:47:18 +00:00
}
else
{
// We're in 'rename' mode!
2020-05-12 10:46:23 +00:00
// Check the name is the same, and if so do nothing
if ( _selectedProfile . Name . Equals ( txt_profile_save_name . Text ) )
{
return ;
}
2020-05-11 11:11:26 +00:00
// Lets save the old names for usage next
2020-05-10 10:47:18 +00:00
string oldProfileName = _selectedProfile . Name ;
2020-05-11 11:11:26 +00:00
string oldProfileCacheFilename = _selectedProfile . SavedProfileCacheFilename ;
// Lets rename the entry in the imagelistview to the new name
2020-05-10 10:47:18 +00:00
foreach ( ImageListViewItem myItem in ilv_saved_profiles . Items )
{
if ( myItem . Text = = oldProfileName )
{
myItem . Text = txt_profile_save_name . Text ;
}
}
2020-05-11 11:11:26 +00:00
// Lets rename the selectedProfile to the new name
_selectedProfile . Name = 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
2020-05-10 10:47:18 +00:00
{
2020-05-11 11:11:26 +00:00
File . Delete ( oldProfileCacheFilename ) ;
}
catch ( Exception ex )
{
// TODO write error to console
// TODO specify the correct the exceptions
2020-05-10 10:47:18 +00:00
}
}
2020-05-12 10:46:23 +00:00
ChangeSelectedProfile ( _selectedProfile ) ;
2020-05-11 11:11:26 +00:00
// Then save the profiles so we always have it updated
// Generating the imagelistview images automatically as we save.
Profile . SaveAllProfiles ( _savedProfiles ) ;
2020-05-10 10:47:18 +00:00
// now update the profiles image listview
//ilv_saved_profiles.Refresh();
2020-05-09 13:02:07 +00:00
}
2020-05-10 10:47:18 +00:00
private void ilv_saved_profiles_ItemClick ( object sender , ItemClickEventArgs e )
2020-05-09 13:02:07 +00:00
{
foreach ( Profile savedProfile in _savedProfiles )
{
2020-05-10 10:47:18 +00:00
if ( savedProfile . Name = = e . Item . Text )
2020-05-09 13:02:07 +00:00
{
2020-05-10 10:47:18 +00:00
ChangeSelectedProfile ( savedProfile ) ;
2020-05-09 13:02:07 +00:00
}
}
2020-05-10 10:47:18 +00:00
}
2020-05-09 13:02:07 +00:00
2020-05-10 10:47:18 +00:00
private void btn_view_current_Click ( object sender , EventArgs e )
{
2020-05-15 03:41:01 +00:00
// Reload the profiles in case we swapped to another program to change it
Profile . UpdateCurrentProfile ( ) ;
// Refresh the Profile UI
RefreshDisplayProfileUI ( ) ;
2020-05-09 13:02:07 +00:00
}
2020-05-11 11:11:26 +00:00
private void txt_profile_save_name_KeyDown ( object sender , KeyEventArgs e )
{
if ( e . KeyCode . Equals ( Keys . Enter ) )
{
MessageBox . Show ( "Click works!" , "Click works" , MessageBoxButtons . OK , MessageBoxIcon . Information ) ;
}
}
2020-05-03 08:39:35 +00:00
}
}