using System.ComponentModel; using Microsoft.Win32; namespace UI_WinForms.Components; [DefaultEvent(nameof(LoadProject))] public partial class LoaderStart : UserControl { private bool areRecentProjectsVisible = false; public LoaderStart() { this.InitializeComponent(); } #region Recent Projects private static RegistryKey I18NCommanderKey => Registry.CurrentUser.OpenSubKey("Software", RegistryKeyPermissionCheck.ReadWriteSubTree)!.CreateSubKey("I18N Commander", RegistryKeyPermissionCheck.ReadWriteSubTree); /// /// Gets or sets the list of recent projects without any extras e.g. it does not prune the list of projects. /// private static List RecentProjects { get { using var regKey = LoaderStart.I18NCommanderKey; var recentProjectsValue = regKey.GetValue("recentProjects"); return recentProjectsValue switch { string[] list => new List(list), _ => new List(), }; } set { using var regKey = LoaderStart.I18NCommanderKey; regKey.SetValue("recentProjects", value.ToArray(), RegistryValueKind.MultiString); } } private static void UpdateRecentProjectsWithPruning(string latestUsedProjectPath) { var previousRecentList = LoaderStart.RecentProjects; // 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: previousRecentList.Insert(0, latestUsedProjectPath); // Prune the list: if (previousRecentList.Count > 6) previousRecentList = previousRecentList.Take(6).ToList(); LoaderStart.RecentProjects = previousRecentList; } #endregion private void buttonOpen_Click(object sender, EventArgs e) { if(this.DesignMode) return; if(this.areRecentProjectsVisible) { this.areRecentProjectsVisible = false; this.contextMenuRecentProjects.Close(); return; } var recentProjects = LoaderStart.RecentProjects; this.contextMenuRecentProjects.Items.Clear(); this.contextMenuRecentProjects.Items.Add("Browse for project...", Resources.Icons.icons8_browse_folder_512, (innerSender, args) => this.BrowseForProject()); foreach (var recentProject in recentProjects) { var fileInfo = new FileInfo(recentProject); // 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)); item.Tag = recentProject; } var button = (sender as Button)!; this.contextMenuRecentProjects.Show(button, 0, button.Height); this.areRecentProjectsVisible = true; } private void buttonNew_Click(object sender, EventArgs e) { if(this.DesignMode) return; 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; var destinationFilePath = saveDialog.FileName; // 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); LoaderStart.UpdateRecentProjectsWithPruning(destinationFilePath); this.OpenProject(destinationFilePath); } private void BrowseForProject() { 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; var projectFilePath = openDialog.FileName; LoaderStart.UpdateRecentProjectsWithPruning(projectFilePath); this.OpenProject(projectFilePath); } private void OpenRecentProject(object? sender) { if (sender is not ToolStripItem item) return; var path = (item.Tag as string)!; LoaderStart.UpdateRecentProjectsWithPruning(path); 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); } private void contextMenuRecentProjects_Closing(object sender, ToolStripDropDownClosingEventArgs e) { this.areRecentProjectsVisible = false; } [Category("Settings"), Description("When the user chooses a project to load.")] public event EventHandler? LoadProject; }