2022-06-12 14:19:32 +00:00
using System.ComponentModel ;
2022-06-12 14:20:04 +00:00
using Microsoft.Win32 ;
2022-11-06 19:12:26 +00:00
using Version = Processor . Version ;
2022-06-06 20:06:41 +00:00
namespace UI_WinForms.Components ;
2022-06-12 14:19:32 +00:00
[DefaultEvent(nameof(LoadProject))]
2022-06-06 20:06:41 +00:00
public partial class LoaderStart : UserControl
{
private bool areRecentProjectsVisible = false ;
public LoaderStart ( )
{
this . InitializeComponent ( ) ;
2022-11-06 19:12:26 +00:00
this . labelVersion . Text = Version . Text ;
2022-06-06 20:06:41 +00:00
}
2022-06-07 18:46:39 +00:00
#region Recent Projects
2022-07-09 14:00:23 +00:00
private static RegistryKey I18NCommanderKey = > Registry . CurrentUser . OpenSubKey ( "Software" , RegistryKeyPermissionCheck . ReadWriteSubTree ) ! . CreateSubKey ( "I18N Commander" , RegistryKeyPermissionCheck . ReadWriteSubTree ) ;
2022-06-07 18:46:39 +00:00
/// <summary>
/// Gets or sets the list of recent projects without any extras e.g. it does not prune the list of projects.
/// </summary>
private static List < string > RecentProjects
2022-06-06 20:06:41 +00:00
{
get
{
2022-06-07 18:46:39 +00:00
using var regKey = LoaderStart . I18NCommanderKey ;
2022-06-06 20:06:41 +00:00
var recentProjectsValue = regKey . GetValue ( "recentProjects" ) ;
return recentProjectsValue switch
{
string [ ] list = > new List < string > ( list ) ,
_ = > new List < string > ( ) ,
} ;
}
set
{
2022-06-07 18:46:39 +00:00
using var regKey = LoaderStart . I18NCommanderKey ;
2022-06-12 14:16:16 +00:00
regKey . SetValue ( "recentProjects" , value . ToArray ( ) , RegistryValueKind . MultiString ) ;
2022-06-06 20:06:41 +00:00
}
}
2022-06-07 18:44:17 +00:00
private static void UpdateRecentProjectsWithPruning ( string latestUsedProjectPath )
{
var previousRecentList = LoaderStart . RecentProjects ;
2022-07-09 13:46:19 +00:00
// Check, if the latest project is identical to the next project we open. In that case, we don't add it to the list.
if ( previousRecentList . Any ( ) & & previousRecentList [ 0 ] = = latestUsedProjectPath )
return ;
// Add the next project to the list:
2022-06-07 18:44:17 +00:00
previousRecentList . Insert ( 0 , latestUsedProjectPath ) ;
2022-07-09 13:46:19 +00:00
// Prune the list:
2022-06-07 18:44:17 +00:00
if ( previousRecentList . Count > 6 )
previousRecentList = previousRecentList . Take ( 6 ) . ToList ( ) ;
LoaderStart . RecentProjects = previousRecentList ;
}
#endregion
2022-06-06 20:06:41 +00:00
private void buttonOpen_Click ( object sender , EventArgs e )
{
2022-07-10 18:30:28 +00:00
if ( this . DesignMode )
return ;
2022-06-06 20:06:41 +00:00
if ( this . areRecentProjectsVisible )
{
this . areRecentProjectsVisible = false ;
this . contextMenuRecentProjects . Close ( ) ;
return ;
}
2022-06-07 18:46:39 +00:00
var recentProjects = LoaderStart . RecentProjects ;
2022-06-06 20:06:41 +00:00
this . contextMenuRecentProjects . Items . Clear ( ) ;
2022-06-07 18:46:39 +00:00
this . contextMenuRecentProjects . Items . Add ( "Browse for project..." , Resources . Icons . icons8_browse_folder_512 , ( innerSender , args ) = > this . BrowseForProject ( ) ) ;
2022-06-06 20:06:41 +00:00
foreach ( var recentProject in recentProjects )
{
var fileInfo = new FileInfo ( recentProject ) ;
2022-07-09 14:16:06 +00:00
// Split the file's path into each folder's name:
var folderNames = fileInfo . DirectoryName ! . Split ( Path . DirectorySeparatorChar ) ;
// Render this entry:
var item = this . contextMenuRecentProjects . Items . Add ( $"{folderNames.Last()}: {fileInfo.Name}" , Resources . Icons . icons8_document_512 , ( innerSender , args ) = > this . OpenRecentProject ( innerSender ) ) ;
2022-06-06 20:06:41 +00:00
item . Tag = recentProject ;
}
var button = ( sender as Button ) ! ;
this . contextMenuRecentProjects . Show ( button , 0 , button . Height ) ;
this . areRecentProjectsVisible = true ;
}
2022-06-07 18:46:21 +00:00
private void buttonNew_Click ( object sender , EventArgs e )
2022-06-06 20:06:41 +00:00
{
2022-07-10 18:30:28 +00:00
if ( this . DesignMode )
return ;
2022-06-12 14:20:04 +00:00
var saveDialog = new SaveFileDialog
{
AddExtension = true ,
CheckPathExists = true ,
CheckFileExists = false ,
CreatePrompt = false ,
OverwritePrompt = true ,
DereferenceLinks = true ,
DefaultExt = ".i18nc" ,
Filter = "I18N Commander Files (*.i18nc)|*.i18nc" ,
RestoreDirectory = true ,
Title = "Create a new I18N Commander file" ,
} ;
var dialogResult = saveDialog . ShowDialog ( this ) ;
if ( dialogResult ! = DialogResult . OK )
return ;
2022-06-07 18:44:17 +00:00
2022-06-12 14:20:04 +00:00
var destinationFilePath = saveDialog . FileName ;
2022-07-09 19:02:08 +00:00
// When the user chose an existing file, we delete it:
// (note: the user already accepts overwriting the file)
if ( File . Exists ( destinationFilePath ) )
File . Delete ( destinationFilePath ) ;
2022-06-12 14:20:04 +00:00
LoaderStart . UpdateRecentProjectsWithPruning ( destinationFilePath ) ;
this . OpenProject ( destinationFilePath ) ;
2022-06-07 18:46:21 +00:00
}
2022-06-07 18:46:39 +00:00
private void BrowseForProject ( )
{
2022-06-12 14:20:04 +00:00
var openDialog = new OpenFileDialog
{
AddExtension = true ,
CheckPathExists = true ,
CheckFileExists = true ,
DereferenceLinks = true ,
DefaultExt = ".i18nc" ,
Filter = "I18N Commander Files (*.i18nc)|*.i18nc" ,
Multiselect = false ,
RestoreDirectory = true ,
Title = "Open an I18N Commander file" ,
} ;
var dialogResult = openDialog . ShowDialog ( this ) ;
if ( dialogResult ! = DialogResult . OK )
return ;
2022-06-07 18:46:39 +00:00
2022-06-12 14:20:04 +00:00
var projectFilePath = openDialog . FileName ;
LoaderStart . UpdateRecentProjectsWithPruning ( projectFilePath ) ;
this . OpenProject ( projectFilePath ) ;
2022-06-06 20:06:41 +00:00
}
2022-06-07 18:46:39 +00:00
private void OpenRecentProject ( object? sender )
2022-06-06 20:06:41 +00:00
{
2022-06-07 18:46:39 +00:00
if ( sender is not ToolStripItem item )
2022-06-06 20:06:41 +00:00
return ;
2022-06-07 18:46:39 +00:00
var path = ( item . Tag as string ) ! ;
2022-06-07 18:44:17 +00:00
LoaderStart . UpdateRecentProjectsWithPruning ( path ) ;
2022-06-12 14:20:04 +00:00
this . OpenProject ( path ) ;
}
private void OpenProject ( string path )
{
// Hint: the project file might or might not exist (new project vs. recent project)
this . LoadProject ? . Invoke ( this , path ) ;
2022-06-06 20:06:41 +00:00
}
private void contextMenuRecentProjects_Closing ( object sender , ToolStripDropDownClosingEventArgs e )
{
this . areRecentProjectsVisible = false ;
}
2022-06-12 14:19:32 +00:00
[Category("Settings"), Description("When the user chooses a project to load.")]
public event EventHandler < string > ? LoadProject ;
2022-06-06 20:06:41 +00:00
}