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
2023-01-22 18:35:57 +00:00
// Opens the recent projects dropdown menu.
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 ) ;
2023-01-22 18:35:57 +00:00
// Distinguish between I18N Commander projects and JSON imports:
if ( fileInfo . Extension = = ".i18nc" )
{
// Render this entry:
var item = this . contextMenuRecentProjects . Items . Add ( $"{folderNames.Last()}: {fileInfo.Name}" , Resources . Icons . icons8_document_512 , ( innerSender , args ) = > this . OpenRecentProject ( innerSender , LoaderAction . LOAD_PROJECT ) ) ;
item . Tag = recentProject ;
}
else if ( fileInfo . Extension = = ".json" )
{
// Render this entry:
var item = this . contextMenuRecentProjects . Items . Add ( $"{folderNames.Last()}: {fileInfo.Name}" , Resources . Icons . icons8_git , ( innerSender , args ) = > this . OpenRecentProject ( innerSender , LoaderAction . IMPORT_JSON ) ) ;
item . Tag = recentProject ;
}
2022-06-06 20:06:41 +00:00
}
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 ) ;
2023-01-22 18:35:57 +00:00
this . OpenProject ( LoaderAction . CREATE_NEW_PROJECT , 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" ,
2023-01-22 18:35:57 +00:00
// I18N Commander files (*.i18nc) or JSON files (*.json):
Filter = "I18N Commander Files (*.i18nc)|*.i18nc|JSON Files (*.json)|*.json" ,
2022-06-12 14:20:04 +00:00
Multiselect = false ,
RestoreDirectory = true ,
2023-01-22 18:35:57 +00:00
Title = "Open an I18N Commander file or Import a JSON file" ,
2022-06-12 14:20:04 +00:00
} ;
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 ) ;
2023-01-22 18:35:57 +00:00
// Check, if the user chose an I18N Commander file or a JSON file:
if ( projectFilePath . ToLowerInvariant ( ) . EndsWith ( ".i18nc" , StringComparison . InvariantCulture ) )
this . OpenProject ( LoaderAction . LOAD_PROJECT , projectFilePath ) ;
else if ( projectFilePath . ToLowerInvariant ( ) . EndsWith ( ".json" , StringComparison . InvariantCulture ) )
this . OpenProject ( LoaderAction . IMPORT_JSON , projectFilePath ) ;
2022-06-06 20:06:41 +00:00
}
2023-01-22 18:35:57 +00:00
private void OpenRecentProject ( object? sender , LoaderAction action )
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 ) ;
2023-01-22 18:35:57 +00:00
this . OpenProject ( action , path ) ;
2022-06-12 14:20:04 +00:00
}
2023-01-22 18:35:57 +00:00
private void OpenProject ( LoaderAction action , string path )
2022-06-12 14:20:04 +00:00
{
// Hint: the project file might or might not exist (new project vs. recent project)
2023-01-22 18:35:57 +00:00
this . LoadProject ? . Invoke ( this , new LoaderResult ( action , 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.")]
2023-01-22 18:35:57 +00:00
public event EventHandler < LoaderResult > ? LoadProject ;
public readonly record struct LoaderResult ( LoaderAction Action , string DataFile ) ;
public enum LoaderAction
{
NONE ,
LOAD_PROJECT ,
CREATE_NEW_PROJECT ,
IMPORT_JSON ,
}
2022-06-06 20:06:41 +00:00
}