using BookmarkManager; using FizzyLauncher.Models; using Newtonsoft.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.Threading.Tasks; using System.Windows.Forms; namespace FizzyLauncher { public partial class MainForm : Form { public enum AppMode { Clear = 0, Open, New } protected OptionsForm optionsForm = null; protected AppMode appMode = AppMode.Clear; protected string sessionFilename = null; protected string sessionPassword = null; protected bool isBusy = false; protected readonly string jsonfigFilename; public MainForm() { InitializeComponent(); this.AutoScaleMode = AutoScaleMode.None; this.StartPosition = FormStartPosition.WindowsDefaultLocation; this.ClientSize = new System.Drawing.Size(300, 580); //this.Visible = false; jsonfigFilename = Path.ChangeExtension(Application.ExecutablePath, "jsonfig"); treeView1.OnNodeChanged += treeView1_OnNodeChanged; treeView1.NodeMouseClick += treeView1_NodeMouseClick; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); //ThreadControl.SetVisible(this, false); ThreadControl.SetSize(this, 300, 580); ApplicationMode = AppMode.Clear; } protected async override void OnShown(EventArgs e) { base.OnShown(e); //ThreadControl.SetVisible(this, false); await LoadAppSession(jsonfigFilename); InvalidateAppSession(); } protected async override void OnClosing(CancelEventArgs e) { e.Cancel = true; if (this.IsBusy) { return; } this.IsBusy = true; Result result = await CloseFile(); if (!result.IsSuccess) { if (!string.IsNullOrWhiteSpace(result.Message)) { MessageBox.Show(result.Message, "Close", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.IsBusy = false; e.Cancel = true; return; } sessionFilename = null; sessionPassword = null; treeView1.Clear(); ApplicationMode = AppMode.Clear; this.IsBusy = false; Application.Exit(); } public AppSession 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(findToolStripMenuItem, false); ThreadControl.SetEnable(expandAllToolStripMenuItem, false); ThreadControl.SetEnable(collapseAllToolStripMenuItem, false); break; case AppMode.Open: ThreadControl.SetEnable(closeToolStripMenuItem, true); ThreadControl.SetEnable(saveToolStripMenuItem, true); ThreadControl.SetEnable(saveAsToolStripMenuItem, true); ThreadControl.SetEnable(findToolStripMenuItem, true); ThreadControl.SetEnable(expandAllToolStripMenuItem, true); ThreadControl.SetEnable(collapseAllToolStripMenuItem, 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(findToolStripMenuItem, true); ThreadControl.SetEnable(expandAllToolStripMenuItem, true); ThreadControl.SetEnable(collapseAllToolStripMenuItem, true); break; default: break; } } } #region main menu /// /// New /// /// /// private async void newToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.IsBusy = true; Result result = await CloseFile(); if (!result.IsSuccess) { if (!string.IsNullOrWhiteSpace(result.Message)) { MessageBox.Show(result.Message, "New Session", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.IsBusy = false; return; } 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; Result result = await CloseFile(); if (!result.IsSuccess) { if (!string.IsNullOrWhiteSpace(result.Message)) { MessageBox.Show(result.Message, "Open File", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.IsBusy = false; return; } if (openFileDialog1.ShowDialog() == DialogResult.OK) { result = await LoadFile(openFileDialog1.FileName); if (result.IsSuccess) { ThreadControl.SetText(this, Path.GetFileNameWithoutExtension(openFileDialog1.FileName) + " - " + AppResource.app_name); } else { MessageBox.Show(result.Message, "Open File", MessageBoxButtons.OK, MessageBoxIcon.Error); } } this.IsBusy = false; } /// /// Close /// /// /// private async void closeToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.IsBusy = true; Result result = await CloseFile(); if (!result.IsSuccess) { if (!string.IsNullOrWhiteSpace(result.Message)) { MessageBox.Show(result.Message, "Close File", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.IsBusy = false; return; } 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 async void optionsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (optionsForm == null) optionsForm = new OptionsForm(this); if (optionsForm.ShowDialog() == DialogResult.OK) { await SaveAppSession(jsonfigFilename); } InvalidateAppSession(); } /// /// 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 private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button != MouseButtons.Right) { return; } switch (treeView1.GetNodeType()) { case BookmarkTreeView.NodeType.Root: //rootTreeNodeMenu.Show(e.Node.TreeView, e.X, e.Y); break; case BookmarkTreeView.NodeType.Folder: //folderTreeNodeMenu.Show(e.Node.TreeView, e.X, e.Y); break; case BookmarkTreeView.NodeType.Page: //pageTreeNodeMenu.Show(e.Node.TreeView, e.X, e.Y); break; default: break; } } private void treeView1_OnNodeChanged(object sender, EventArgs e) { ThreadControl.SetEnable(saveToolStripMenuItem, (treeView1.HasChanged && ApplicationMode == AppMode.Open)); } protected void InvalidateAppSession() { if (CurrentSession == null) CurrentSession = new AppSession(); if (CurrentSession.EnableAutoPosition) { this.Height = Screen.PrimaryScreen.WorkingArea.Height; this.Location = Screen.PrimaryScreen.WorkingArea.Location; } this.TopMost = CurrentSession.AlwaysOnTop; } protected async Task LoadAppSession(string filename) { return await Task.Run(() => { if (File.Exists(filename)) { string sourceCode = null; try { sourceCode = File.ReadAllText(filename); } catch (Exception) { // do nothing } if (string.IsNullOrWhiteSpace(sourceCode)) { this.CurrentSession = new AppSession(); return false; } try { this.CurrentSession = JsonConvert.DeserializeObject(sourceCode); } catch (Exception) { this.CurrentSession = null; } if (this.CurrentSession == null) { this.CurrentSession = new AppSession(); return false; } } else { this.CurrentSession = new AppSession(); try { File.WriteAllText(filename, JsonConvert.SerializeObject(this.CurrentSession)); } catch (Exception) { // do nothing } } return true; }); } protected async Task SaveAppSession(string filename) { return await Task.Run(() => { if (this.CurrentSession == null) this.CurrentSession = new AppSession(); try { File.WriteAllText(filename, JsonConvert.SerializeObject(this.CurrentSession)); } catch (Exception) { return false; } return true; }); } protected async Task CloseFile() { return await Task.Run(async () => { if (this.ApplicationMode == AppMode.Clear) { return Result.Create(true); } if (!treeView1.HasChanged) { return Result.Create(true); } 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) { return Result.Create(false, result.Message); } } else if (response == DialogResult.Cancel) { return Result.Create(false, ""); } } 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) { return Result.Create(false, result.Message); } } else if (response == DialogResult.Cancel) { return Result.Create(false, ""); } } return Result.Create(true); }); } 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; if (result.IsSuccess) { treeView1.SetNoChanges(); } ThreadControl.SetFocus(treeView1); 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; }); } } }