using BookmarkManager; using FizzyLauncher.Models; using FizzyLauncher.Text.Json; using RyzStudio.Windows.Forms; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; using System.Threading.Tasks; using System.Windows.Forms; namespace FizzyLauncher { public partial class MainForm : Form { //[DllImport("user32.dll")] //protected static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk); //[DllImport("user32.dll")] //protected static extern bool UnregisterHotKey(IntPtr hWnd, int id); public enum AppMode { Clear = 0, Open, New } //public enum LoadFileType //{ // None = 0, // Jsnx, // Ryz //} //protected BackgroundWorker loadFileThread = null; //protected bool isBusy = false; protected OptionsForm optionsForm = null; protected AppMode appMode = AppMode.Clear; protected string sessionFilename = null; protected string sessionPassword = null; protected bool isBusy = false; //protected LoadFileType loadFileType = LoadFileType.None; //protected bool usePassword = false; //protected const int MOD_ALT = 0x1; //protected const int MOD_CONTROL = 0x2; //protected const int MOD_SHIFT = 0x4; //protected const int MOD_WIN = 0x8; //protected const int WM_HOTKEY = 0x312; //protected const int WM_QUERYENDSESSION = 0x0011; //protected string sessionFilename = null; //protected bool requestExit = false; public MainForm() { InitializeComponent(); //tileContainer1.OnColumnSizeChanged += tileContainer1_OnSizeChanged; this.AutoScaleMode = AutoScaleMode.None; this.StartPosition = FormStartPosition.WindowsDefaultLocation; this.ClientSize = new System.Drawing.Size(300, 580); //this.Visible = false; ApplicationMode = AppMode.Clear; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); //ThreadControl.SetVisible(this, false); ThreadControl.SetSize(this, 300, 580); } protected async override void OnShown(EventArgs e) { base.OnShown(e); //ThreadControl.SetVisible(this, false); //string jsonfigFilename = Path.ChangeExtension(Application.ExecutablePath, "jsonfig"); //if (File.Exists(jsonfigFilename)) //{ // await loadFile(jsonfigFilename); //} //else //{ // this.CurrentSession = new LauncherSession(); // ThreadControl.SetVisible(this, true); //} } protected override void OnClosing(CancelEventArgs e) { base.OnClosing(e); // if (this.CurrentSession == null) this.CurrentSession = new LauncherSession(); // if (this.CurrentSession.HideOnClose && !requestExit) // { // this.Visible = !this.Visible; // e.Cancel = true; // return; // } // requestExit = false; // if (string.IsNullOrWhiteSpace(sessionFilename)) // { // // do nothing // } // else // { // if (this.CurrentSession.AutoSave == LauncherSession.AutoSaveOption.Prompt) // { // DialogResult dr = MessageBox.Show("Save existing session?", "Exit", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); // if (dr == DialogResult.Yes) // { // bool rv = saveFile(sessionFilename, false); // if (!rv) // { // e.Cancel = true; // } // } // else if (dr == DialogResult.No) // { // // do nothing // } // else if (dr == DialogResult.Cancel) // { // e.Cancel = true; // } // } // else if (this.CurrentSession.AutoSave == LauncherSession.AutoSaveOption.Yes) // { // saveFile(sessionFilename, false); // } // } // if (this.CurrentSession.HotKey != null) // { // if (this.CurrentSession.HotKey.KeyCode != Keys.None) // { //#if !DEBUG // UnregisterHotKey((IntPtr)Handle, 1); //#endif // } // } } public LauncherSession CurrentSession { get; set; } = null; public bool IsBusy { get => isBusy; set { treeView1.Enabled = !value; } } protected AppMode ApplicationMode { get => appMode; set { appMode = value; switch (value) { case AppMode.Clear: ThreadControl.SetText(this, AppResource.app_name); ThreadControl.SetEnable(closeToolStripMenuItem, false); ThreadControl.SetEnable(saveToolStripMenuItem, false); ThreadControl.SetEnable(saveAsToolStripMenuItem, false); ThreadControl.SetEnable(expandAllToolStripMenuItem, false); ThreadControl.SetEnable(collapseAllToolStripMenuItem, false); //ThreadControl.SetEnable(toolStrip1, closeFileMenuItem, false); //this.AllowSave = false; //ThreadControl.SetEnable(toolStrip1, saveAsFileMenuItem, false); //ThreadControl.SetEnable(toolStrip1, findEditMenuItem, false); //ThreadControl.SetEnable(toolStrip1, expandAllViewMenuItem, false); //ThreadControl.SetEnable(toolStrip1, collapseAllViewMenuItem, false); //ThreadControl.SetEnable(toolStrip1, optionsToolMenuItem, false); break; case AppMode.Open: ThreadControl.SetEnable(closeToolStripMenuItem, true); ThreadControl.SetEnable(saveToolStripMenuItem, true); ThreadControl.SetEnable(saveAsToolStripMenuItem, true); ThreadControl.SetEnable(expandAllToolStripMenuItem, true); ThreadControl.SetEnable(collapseAllToolStripMenuItem, true); //ThreadControl.SetEnable(toolStrip1, closeFileMenuItem, true); //this.AllowSave = true; //ThreadControl.SetEnable(toolStrip1, saveAsFileMenuItem, true); //ThreadControl.SetEnable(toolStrip1, findEditMenuItem, true); //ThreadControl.SetEnable(toolStrip1, expandAllViewMenuItem, true); //ThreadControl.SetEnable(toolStrip1, collapseAllViewMenuItem, true); //ThreadControl.SetEnable(toolStrip1, optionsToolMenuItem, true); break; case AppMode.New: ThreadControl.SetText(this, AppResource.app_name); ThreadControl.SetEnable(closeToolStripMenuItem, true); ThreadControl.SetEnable(saveToolStripMenuItem, false); ThreadControl.SetEnable(saveAsToolStripMenuItem, true); ThreadControl.SetEnable(expandAllToolStripMenuItem, true); ThreadControl.SetEnable(collapseAllToolStripMenuItem, true); //ThreadControl.SetEnable(toolStrip1, closeFileMenuItem, true); //this.AllowSave = true; //ThreadControl.SetEnable(toolStrip1, saveAsFileMenuItem, true); //ThreadControl.SetEnable(toolStrip1, findEditMenuItem, true); //ThreadControl.SetEnable(toolStrip1, expandAllViewMenuItem, true); //ThreadControl.SetEnable(toolStrip1, collapseAllViewMenuItem, true); //ThreadControl.SetEnable(toolStrip1, optionsToolMenuItem, true); break; } } } //public void Clear(int columnCount) //{ // //tileContainer1.Clear(); // //tileContainer1.Add(columnCount); // sessionFilename = null; //} //protected async Task collapseWindow(int width, int increment = 6) //{ // await Task.Run(() => // { // while (this.Width > width) // { // ThreadControl.SetWidth(this, (this.Width - increment)); // Application.DoEvents(); // } // ThreadControl.SetWidth(this, width); // }); //} //protected async Task expandWindow(int width, int increment = 8) //{ // await Task.Run(() => // { // while (this.Width < width) // { // ThreadControl.SetWidth(this, (this.Width + increment)); // Application.DoEvents(); // } // ThreadControl.SetWidth(this, width); // }); //} // protected void invalidateHotKey() // { //#if !DEBUG // if (this.InvokeRequired) // { // this.Invoke(new MethodInvoker(() => // { // UnregisterHotKey((IntPtr)Handle, 1); // })); // } // else // { // UnregisterHotKey((IntPtr)Handle, 1); // } //#endif // if (this.CurrentSession.HotKey != null) // { // if (this.CurrentSession.HotKey.KeyCode != Keys.None) // { //#if !DEBUG // if (this.InvokeRequired) // { // this.Invoke(new MethodInvoker(() => // { // RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.HotKey.ModifierCode, this.CurrentSession.HotKey.Key); // })); // } // else // { // RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.HotKey.ModifierCode, this.CurrentSession.HotKey.Key); // } //#endif // } // } // } //protected void newSession() //{ //NewForm form = new NewForm(this); //form.ShowDialog(); //} //protected async Task loadFile(string filename) //{ // await Task.Run(() => // { // if (isBusy) // { // return; // } // if (string.IsNullOrWhiteSpace(filename)) // { // return; // } // if (!File.Exists(filename)) // { // return; // } // string sourceCode = null; // try // { // sessionFilename = filename; // sourceCode = File.ReadAllText(sessionFilename); // } // catch (Exception exc) // { // MessageBox.Show(exc.Message, "Load session"); // return; // } // if (string.IsNullOrWhiteSpace(sourceCode)) // { // return; // } // // load options // var options = new JsonSerializerOptions(); // options.Converters.Add(new JsonPointConverter()); // options.Converters.Add(new JsonSizeConverter()); // try // { // this.CurrentSession = JsonSerializer.Deserialize(sourceCode, options); // } // catch (Exception exc) // { // MessageBox.Show("Unable to read session", "Load session"); // return; // } // if (this.CurrentSession == null) // { // this.CurrentSession = new LauncherSession(); // } // // load tiles // //tileContainer1.Load(this.CurrentSession.Groups); // // reposition // if (!this.CurrentSession.StartPosition.IsEmpty) ThreadControl.SetLocation(this, this.CurrentSession.StartPosition); // // // ThreadControl.SetTopMost(this, this.CurrentSession.AlwaysOnTop); // ThreadControl.SetVisible(this, true); // ThreadControl.SetChecked(collapseAllToolStripMenuItem, this.CurrentSession.EnableAnimation); // ThreadControl.SetChecked(expandAllToolStripMenuItem, this.CurrentSession.EnableBigIconInFolder); // //ThreadControl.SetClientHeight(this, this.CurrentSession.DefaultHeight); // ThreadControl.SetFocus(this); // // hotkey // invalidateHotKey(); // }); //} //protected bool saveFile(string filename, bool showNotices = true) //{ //if (isBusy) //{ // return false; //} //if (string.IsNullOrWhiteSpace(filename)) //{ // return false; //} //if (tileContainer1.GroupCount <= 0) //{ // return true; //} //isBusy = true; //// update session //if (this.CurrentSession == null) //{ // this.CurrentSession = new LauncherSession(); //} //this.CurrentSession.DefaultHeight = this.Height; //this.CurrentSession.AlwaysOnTop = this.TopMost; //this.CurrentSession.StartPosition = this.Location; //this.CurrentSession.Groups = tileContainer1.GroupModels?.ToList() ?? new List(); //var options = new JsonSerializerOptions(); //options.Converters.Add(new JsonPointConverter()); //options.Converters.Add(new JsonSizeConverter()); //try //{ // File.WriteAllText(filename, JsonSerializer.Serialize(this.CurrentSession, options)); // if (showNotices) // { // MessageBox.Show("Session saved!", "Save session", MessageBoxButtons.OK, MessageBoxIcon.Information); // } //} //catch (Exception exc) //{ // MessageBox.Show(exc.Message, "Save session"); // return false; //} //isBusy = false; //return true; //} //protected bool saveAsFile() //{ //if (isBusy) //{ // return false; //} //if (saveFileDialog1.ShowDialog() == DialogResult.OK) //{ // bool rv = saveFile(saveFileDialog1.FileName); // if (rv) // { // sessionFilename = saveFileDialog1.FileName; // } // return rv; //} // return false; //} #region main menu /// /// New /// /// /// private void newToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.IsBusy = true; CloseFile(); sessionFilename = null; sessionPassword = null; treeView1.Clear("Untitled"); ApplicationMode = AppMode.New; this.IsBusy = false; } /// /// Open file /// /// /// private async void openToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.IsBusy = true; CloseFile(); if (openFileDialog1.ShowDialog() == DialogResult.OK) { Result result = await LoadFile(openFileDialog1.FileName); if (!result.IsSuccess) { MessageBox.Show(result.Message, "Open File", MessageBoxButtons.OK, MessageBoxIcon.Error); } } this.IsBusy = false; } /// /// Close /// /// /// private void closeToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.IsBusy = true; CloseFile(); sessionFilename = null; sessionPassword = null; treeView1.Clear(); ApplicationMode = AppMode.Clear; this.IsBusy = false; } /// /// Save /// /// /// private async void saveToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (ApplicationMode == AppMode.Clear) { return; } this.IsBusy = true; Result result = await SaveFile(sessionFilename, sessionPassword); if (result.IsSuccess) { MessageBox.Show("File saved!", "Save File", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(result.Message, "Save File", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.IsBusy = false; } /// /// Save As /// /// /// private async void saveAsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (ApplicationMode == AppMode.Clear) { return; } this.IsBusy = true; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { Result result = await SaveAsFile(saveFileDialog1.FileName); if (result.IsSuccess) { MessageBox.Show("File saved!", "Save As File", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(result.Message, "Save As File", MessageBoxButtons.OK, MessageBoxIcon.Error); } } this.IsBusy = false; } /// /// Exit /// /// /// private void exitToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.Close(); } /// /// Find /// /// /// private void findToolStripMenuItem_Click(object sender, EventArgs e) { //tileContainer1.Add(); } /// /// Expand all /// /// /// private void expandAllToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) return; if (ApplicationMode == AppMode.Clear) return; if (treeView1.SelectedNode == null) { treeView1.ExpandAll(); } else { treeView1.SelectedNode.ExpandAll(); } } /// /// Collapse all /// /// /// private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) return; if (ApplicationMode == AppMode.Clear) return; if (treeView1.SelectedNode == null) { treeView1.CollapseAll(); } else { treeView1.SelectedNode.Collapse(false); } } /// /// Always on top /// /// /// private void alwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e) { this.TopMost = !this.TopMost; alwaysOnTopToolStripMenuItem.Checked = this.TopMost; } /// /// Options /// /// /// private void optionsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (optionsForm == null) optionsForm = new OptionsForm(this); optionsForm.ShowDialog(); //invalidateHotKey(); } /// /// View help /// /// /// private void viewHelpToolStripMenuItem1_Click(object sender, EventArgs e) { try { System.Diagnostics.Process.Start("https://www.hiimray.co.uk/software-bookmark-manager"); } catch { // do nothing } } /// /// About /// /// /// private void aboutToolStripMenuItem1_Click(object sender, EventArgs e) { MessageBox.Show(Application.ProductName + " v" + Application.ProductVersion, "About", MessageBoxButtons.OK, MessageBoxIcon.Information); } #endregion protected async void CloseFile() { if (this.ApplicationMode == AppMode.Clear) { return; } if (!treeView1.HasChanged) { return; } if (this.ApplicationMode == AppMode.New) { DialogResult response = MessageBox.Show("Save bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { Result result = await SaveAsFile(sessionFilename); if (!result.IsSuccess) { MessageBox.Show(result.Message, "Save File", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else if (response == DialogResult.Cancel) { return; } } else if (this.ApplicationMode == AppMode.Open) { DialogResult response = MessageBox.Show("Save changes to open bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { Result result = await SaveFile(sessionFilename, sessionPassword); if (!result.IsSuccess) { MessageBox.Show(result.Message, "Save File", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else if (response == DialogResult.Cancel) { return; } } } protected SupportedFileBase GetSupportedFileHandler(string filename) { SupportedFileBase rs = null; List typeList = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsSubclassOf(typeof(SupportedFileBase))).ToList(); foreach (Type t in typeList) { rs = (SupportedFileBase)Activator.CreateInstance(t); if (rs == null) { continue; } if (rs.IsSupported(filename)) { break; } rs = null; } return rs; } protected async Task LoadFile(string filename) { return await Task.Run(() => { sessionFilename = null; sessionPassword = null; ApplicationMode = AppMode.Clear; treeView1.Clear(); if (string.IsNullOrWhiteSpace(filename)) { return Result.Create(false, "Filename is empty"); } if (!File.Exists(filename)) { return Result.Create(false, "File not found"); } sessionFilename = filename; SupportedFileBase fileHandler = GetSupportedFileHandler(sessionFilename); if (fileHandler == null) { return Result.Create(false, "Handler not found for this file type"); } if (fileHandler.IsEncrypted(sessionFilename)) { PasswordForm passwordForm = new PasswordForm(this); if (passwordForm.ShowDialog() == DialogResult.OK) { sessionPassword = passwordForm.Password; } } Result result = fileHandler.Load(treeView1, sessionFilename, sessionPassword); if (!result.IsSuccess) { return result; } if (treeView1.Nodes.Count > 0) { ThreadControl.Expand(treeView1.Nodes[0]); } ApplicationMode = AppMode.Open; return result; }); } protected async Task SaveFile(string filename, string password = null) { return await Task.Run(() => { if (string.IsNullOrWhiteSpace(filename)) { return Result.Create(false, "Filename is empty"); } SupportedFileBase fileHandler = GetSupportedFileHandler(filename); if (fileHandler == null) { return Result.Create(false, "Handler not found for this file type"); } Result result = fileHandler.Save(treeView1, filename, password); if (result.IsSuccess) { treeView1.SetNoChanges(); } return result; }); } protected async Task SaveAsFile(string filename) { return await Task.Run(() => { if (string.IsNullOrWhiteSpace(filename)) { return Result.Create(false, "Filename is empty"); } SupportedFileBase fileHandler = GetSupportedFileHandler(filename); if (fileHandler == null) { return Result.Create(false, "Handler not found for this file type"); } string password = null; if (fileHandler.IsEncryptionSupported) { PasswordForm passwordForm = new PasswordForm(this); if (passwordForm.ShowDialog() == DialogResult.OK) { if (!string.IsNullOrWhiteSpace(passwordForm.Password)) { password = passwordForm.Password; } } } Result result = fileHandler.Save(treeView1, filename, password); if (result.IsSuccess) { treeView1.SetNoChanges(); } return result; }); } } }