using bzit.bomg.Models; using ICSharpCode.SharpZipLib.Zip; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Text; using System.Windows.Forms; using System.Xml; using static RyzStudio.Windows.Forms.BookmarkTreeView; using TextBoxForm = RyzStudio.Windows.ThemedForms.TextBoxForm; using Resources = bzit.bomg.Properties.Resources; namespace bzit.bomg { public partial class MainForm : Form { public enum AppMode { Clear = 0, Open, New } public enum LoadFileType { None = 0, Jsnx, Ryz } protected BackgroundWorker loadFileThread = null; protected LoadFileType loadFileType = LoadFileType.None; protected AppMode appMode = AppMode.Clear; protected string sessionFilename = null; protected string sessionPassword = null; protected bool usePassword = false; public MainForm() { InitializeComponent(); if (loadFileThread == null) { loadFileThread = new BackgroundWorker(); loadFileThread.WorkerReportsProgress = loadFileThread.WorkerSupportsCancellation = true; } loadFileThread.DoWork += loadFileThread_DoWork; loadFileThread.RunWorkerCompleted += loadFileThread_RunWorkerCompleted; treeView1.OnNodeChanged += treeView1_OnNodeChanged; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); bool rv = false; string iconDBFilename = Path.ChangeExtension(Application.ExecutablePath, ".db"); string errorMessage; rv = treeView1.InitialiseIconDatabase(out errorMessage, iconDBFilename); if (!rv) { MessageBox.Show("Can not find icon database. [" + errorMessage + "]"); this.Close(); } this.ApplicationMode = AppMode.Clear; sessionFilename = sessionPassword = null; usePassword = false; } protected override void OnShown(EventArgs e) { base.OnShown(e); this.Height = Screen.PrimaryScreen.WorkingArea.Height; this.Location = Screen.PrimaryScreen.WorkingArea.Location; // command line string[] args = Environment.GetCommandLineArgs(); if (args.Length > 1) { int i = 1; while (true) { if (i > (args.Length - 1)) { break; } switch (args[i].Trim().ToLower()) { case "-o": case "-open": if ((i + 1) > (args.Length - 1)) break; string openFilename = args[(i + 1)]; if (string.IsNullOrWhiteSpace(openFilename)) break; if (!File.Exists(openFilename)) break; string openExtension = Path.GetExtension(openFilename).Trim('.'); if (openExtension.Equals("jsnx", StringComparison.CurrentCultureIgnoreCase)) { loadBookmarkFile(openFilename, 1); } else if (openExtension.Equals("ryz", StringComparison.CurrentCultureIgnoreCase)) { loadBookmarkFile(openFilename, 2); } i++; break; } i++; } } } protected override void OnFormClosing(FormClosingEventArgs e) { if (this.IsBusy) { e.Cancel = true; return; } if (this.ApplicationMode == AppMode.Clear) { // do later } else { if (treeView1.HasChanged) { if (this.ApplicationMode == AppMode.New) { DialogResult response = MessageBox.Show("Save bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { bool hasSaved = saveAsBookmarkFile(); if (!hasSaved) { e.Cancel = true; return; } } else if (response == DialogResult.No) { // do later } else if (response == DialogResult.Cancel) { e.Cancel = true; 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) { if (usePassword) { if (string.IsNullOrWhiteSpace(sessionPassword)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); sessionPassword = passwordForm.ShowDialog(); } } saveBookmarkFile_ForJSNX(sessionFilename, sessionPassword ?? string.Empty); } else if (response == DialogResult.No) { // do later } else if (response == DialogResult.Cancel) { e.Cancel = true; return; } } } else { // do later } } treeView1.CloseIconDatabase(); treeView1.Clear(); this.ApplicationMode = AppMode.Clear; sessionFilename = sessionPassword = null; Application.Exit(); } protected AppMode ApplicationMode { get => appMode; set { appMode = value; switch (value) { case AppMode.Clear: this.Text = Properties.Resources.app_name; closeFileMenuItem.Enabled = false; saveFileMenuItem.Enabled = saveMenuBarItem.Enabled = false; saveAsFileMenuItem.Enabled = false; findEditMenuItem.Enabled = false; expandAllViewMenuItem.Enabled = collapseAllViewMenuItem.Enabled = false; optionsToolMenuItem.Enabled = false; break; case AppMode.Open: closeFileMenuItem.Enabled = true; saveFileMenuItem.Enabled = saveMenuBarItem.Enabled = true; saveAsFileMenuItem.Enabled = true; findEditMenuItem.Enabled = true; expandAllViewMenuItem.Enabled = collapseAllViewMenuItem.Enabled = true; optionsToolMenuItem.Enabled = true; break; case AppMode.New: this.Text = Properties.Resources.app_name; closeFileMenuItem.Enabled = true; saveFileMenuItem.Enabled = saveMenuBarItem.Enabled = true; saveAsFileMenuItem.Enabled = true; findEditMenuItem.Enabled = true; expandAllViewMenuItem.Enabled = collapseAllViewMenuItem.Enabled = true; optionsToolMenuItem.Enabled = true; break; } } } protected bool IsBusy { get { return loadFileThread.IsBusy; } set { treeView1.Enabled = !value; } } #region toolbar private void fileNewMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.Clear) { // do later } else { if (treeView1.HasChanged) { if (this.ApplicationMode == AppMode.New) { DialogResult response = MessageBox.Show("Save bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { bool hasSaved = saveAsBookmarkFile(); if (!hasSaved) { return; } } else if (response == DialogResult.No) { // do later } 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) { if (usePassword) { if (string.IsNullOrWhiteSpace(sessionPassword)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); sessionPassword = passwordForm.ShowDialog(); } } saveBookmarkFile_ForJSNX(sessionFilename, sessionPassword ?? string.Empty); } else if (response == DialogResult.No) { // do later } else if (response == DialogResult.Cancel) { return; } } } else { // do later } } TextBoxForm newSessionForm = new TextBoxForm("New Session", "Name"); string rv = newSessionForm.ShowDialog(); if (string.IsNullOrWhiteSpace(rv)) { return; } treeView1.Clear(rv); this.ApplicationMode = AppMode.New; sessionFilename = sessionPassword = null; } private void fileOpenMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.Clear) { // do later } else { if (treeView1.HasChanged) { if (this.ApplicationMode == AppMode.New) { DialogResult response = MessageBox.Show("Save bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { bool hasSaved = saveAsBookmarkFile(); if (!hasSaved) { return; } } else if (response == DialogResult.No) { // do later } 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) { if (usePassword) { if (string.IsNullOrWhiteSpace(sessionPassword)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); sessionPassword = passwordForm.ShowDialog(); } } saveBookmarkFile_ForJSNX(sessionFilename, sessionPassword ?? string.Empty); } else if (response == DialogResult.No) { // do later } else if (response == DialogResult.Cancel) { return; } } } else { // do later } } if (openFileDialog.ShowDialog() == DialogResult.OK) { loadBookmarkFile(openFileDialog.FileName, openFileDialog.FilterIndex); } } private void fileCloseMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.Clear) { // do later } else { if (treeView1.HasChanged) { if (this.ApplicationMode == AppMode.New) { DialogResult response = MessageBox.Show("Save bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { bool hasSaved = saveAsBookmarkFile(); if (!hasSaved) { return; } } else if (response == DialogResult.No) { // do later } 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) { if (usePassword) { if (string.IsNullOrWhiteSpace(sessionPassword)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); sessionPassword = passwordForm.ShowDialog(); } } saveBookmarkFile_ForJSNX(sessionFilename, sessionPassword ?? string.Empty); } else if (response == DialogResult.No) { // do later } else if (response == DialogResult.Cancel) { return; } } } else { // do later } } treeView1.Clear(); this.ApplicationMode = AppMode.Clear; sessionFilename = sessionPassword = null; } private void fileSaveMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.New) { DialogResult response = MessageBox.Show("Save bookmarks", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (response == DialogResult.Yes) { bool hasSaved = saveAsBookmarkFile(); if (!hasSaved) { return; } } else if (response == DialogResult.No) { return; } else if (response == DialogResult.Cancel) { return; } } else if (this.ApplicationMode == AppMode.Open) { if (usePassword) { if (string.IsNullOrWhiteSpace(sessionPassword)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); sessionPassword = passwordForm.ShowDialog(); } } saveBookmarkFile_ForJSNX(sessionFilename, sessionPassword ?? string.Empty); } } private void fileSaveAsMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.Clear) { return; } bool hasSaved = saveAsBookmarkFile(); if (!hasSaved) { return; } } private void fileExitMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } this.Close(); } private void editFindMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } FindForm findForm = new FindForm(this); findForm.Show(); } private void viewExpandAllMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.Clear) { return; } if (treeView1.SelectedNode == null) { treeView1.ExpandAll(); } else { treeView1.SelectedNode.ExpandAll(); } } private void viewCollapseAllMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } if (this.ApplicationMode == AppMode.Clear) { return; } if (treeView1.SelectedNode == null) { treeView1.CollapseAll(); } else { treeView1.SelectedNode.Collapse(false); } } private void viewAlwaysOnTopMenuItem_Click(object sender, EventArgs e) { this.TopMost = !this.TopMost; alwaysOnTopToolStripMenuItem1.Checked = this.TopMost; } private void toolsOptionsMenuItem_Click(object sender, EventArgs e) { if (this.IsBusy) { return; } OptionForm optionForm = new OptionForm(this); optionForm.ShowDialog(); } private void helpViewHelpMenuItem_Click(object sender, EventArgs e) { try { System.Diagnostics.Process.Start(Resources.url_help); } catch { // do nothing } } private void helpAboutMenuItem_Click(object sender, EventArgs e) { try { System.Diagnostics.Process.Start(Resources.url_about); } catch { // do nothing } } #endregion protected void loadBookmarkFile(string filename, int filterIndex) { switch (filterIndex) { case 1: if (RyzStudio.IO.SharpZipLib.IsZipEncrypted(filename)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); string password = string.Empty; while (true) { password = passwordForm.ShowDialog(); if (string.IsNullOrWhiteSpace(password)) { break; } if (RyzStudio.IO.SharpZipLib.TestZipEncrypted(filename, password)) { sessionFilename = filename; sessionPassword = password; usePassword = true; loadFileType = LoadFileType.Jsnx; break; } } } else { sessionFilename = filename; sessionPassword = null; usePassword = false; loadFileType = LoadFileType.Jsnx; } break; case 2: if (RyzStudio.IO.SharpZipLib.IsZipEncrypted(filename)) { TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); string password = string.Empty; while (true) { password = passwordForm.ShowDialog(); if (string.IsNullOrWhiteSpace(password)) { break; } if (RyzStudio.IO.SharpZipLib.TestZipEncrypted(filename, password)) { sessionFilename = filename; sessionPassword = password; usePassword = true; loadFileType = LoadFileType.Ryz; break; } } } else { sessionFilename = filename; sessionPassword = null; usePassword = false; loadFileType = LoadFileType.Ryz; } break; default: sessionFilename = sessionPassword = null; usePassword = false; break; } if (string.IsNullOrWhiteSpace(sessionFilename)) { return; } this.IsBusy = true; loadFileThread.RunWorkerAsync(); } protected void loadBookmarkFile_ForJSNX(string filename, string password = "") { int size = 2048; byte[] buffer = new byte[size]; int bufferSize = 0; List rs = null; ZipEntry readEntry = null; ZipInputStream readStream = new ZipInputStream(File.OpenRead(filename)); readStream.Password = password; while (true) { readEntry = readStream.GetNextEntry(); if (readEntry == null) { break; } if (string.IsNullOrWhiteSpace(readEntry.Name)) { continue; } if (!readEntry.IsFile) { continue; } if (!readEntry.Name.Equals("bookmarks.json")) { continue; } MemoryStream ms = new MemoryStream(); buffer = new byte[size]; bufferSize = 0; do { bufferSize = readStream.Read(buffer, 0, buffer.Length); ms.Write(buffer, 0, bufferSize); } while (bufferSize > 0); ms.Position = 0; StreamReader sr = new StreamReader(ms); rs = JsonConvert.DeserializeObject>(sr.ReadToEnd()); break; } readStream.Flush(); readStream.Close(); readStream.Dispose(); readStream = null; treeView1.AddItem(rs); if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { this.ApplicationMode = AppMode.Open; })); } else { this.ApplicationMode = AppMode.Open; } RyzStudio.Windows.Forms.ThreadControl.SetText(this, Path.GetFileNameWithoutExtension(filename) + " - " + Resources.app_name); } protected void loadBookmarkFile_ForRYZ(string filename, string password = "") { int size = 2048; byte[] buffer = new byte[size]; int bufferSize = 0; List rs = new List(); ZipEntry readEntry = null; ZipInputStream readStream = new ZipInputStream(File.OpenRead(filename)); readStream.Password = password; while (true) { readEntry = readStream.GetNextEntry(); if (readEntry == null) { break; } if (string.IsNullOrWhiteSpace(readEntry.Name)) { continue; } if (!readEntry.IsFile) { continue; } if (!readEntry.Name.Equals("bookmarks.xml")) { continue; } MemoryStream ms = new MemoryStream(); buffer = new byte[size]; bufferSize = 0; do { bufferSize = readStream.Read(buffer, 0, buffer.Length); ms.Write(buffer, 0, bufferSize); } while (bufferSize > 0); ms.Position = 0; // read stream StreamReader sr = new StreamReader(ms); // load xml XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(sr.ReadToEnd()); // parse XmlNode xnl = xmlDocument.SelectSingleNode("bomg/b/g"); if (xnl == null) { break; } string rootName = (xnl.Attributes["name"] == null) ? "Bookmarks" : (string.IsNullOrWhiteSpace(xnl.Attributes["name"].InnerText) ? "Bookmarks" : xnl.Attributes["name"].InnerText.Trim()); foreach (XmlNode xn in xnl.ChildNodes) { BookmarkItemViewModel viewModel = new BookmarkItemViewModel(); foreach (XmlNode xn2 in xn.ChildNodes) { switch (xn2.LocalName) { case "name": viewModel.SiteName = xn2.InnerText?.Trim(); break; case "address": viewModel.SiteAddress = xn2.InnerText?.Trim(); break; case "description": viewModel.SiteDescription = xn2.InnerText?.Trim(); break; //case "created": // bi.Created = xn2.InnerText?.Trim(); // break; default: break; } } // fix fullpath and name if (viewModel.SiteName.Contains("|")) { StringBuilder sb = new StringBuilder(); sb.Append("\\"); sb.Append(System.Web.HttpUtility.UrlEncode(rootName)); sb.Append("\\"); string[] pathParts = viewModel.SiteName.Split('|'); for (int i = 0; i < (pathParts.Length - 1); i++) { sb.Append(pathParts[i]); //sb.Append(System.Web.HttpUtility.UrlDecode(pathParts[i])); sb.Append("\\"); } viewModel.SiteName = System.Web.HttpUtility.UrlDecode(pathParts[(pathParts.Length - 1)] ?? string.Empty); viewModel.TreeviewPath = sb.ToString(); } else { viewModel.SiteName = System.Web.HttpUtility.UrlDecode(viewModel.SiteName); viewModel.TreeviewPath = string.Format("\\{0}\\", System.Web.HttpUtility.UrlEncode(rootName)); } rs.Add(viewModel); } break; } readStream.Flush(); readStream.Close(); readStream.Dispose(); readStream = null; treeView1.AddItem(rs); sessionFilename = sessionPassword = null; usePassword = !string.IsNullOrWhiteSpace(password); if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { this.ApplicationMode = AppMode.New; })); } else { this.ApplicationMode = AppMode.New; } RyzStudio.Windows.Forms.ThreadControl.SetText(this, Path.GetFileNameWithoutExtension(filename) + " - " + Resources.app_name); } protected void openBookmark(TreeNode node) { if (treeView1.GetNodeType(node) != RyzStudio.Windows.Forms.BookmarkTreeView.NodeType.Page) { return; } BookmarkItemViewModel viewModel = (BookmarkItemViewModel)node.Tag; if (viewModel == null) { return; } if (string.IsNullOrWhiteSpace(viewModel.SiteAddress)) { return; } try { System.Diagnostics.Process.Start(viewModel.SiteAddress); } catch { // do nothing } } protected bool saveAsBookmarkFile() { if (saveFileDialog.ShowDialog() == DialogResult.OK) { switch (saveFileDialog.FilterIndex) { case 1: saveBookmarkFile_ForJSNX(saveFileDialog.FileName); this.Text = Path.GetFileNameWithoutExtension(saveFileDialog.FileName) + " - " + Properties.Resources.app_name; sessionFilename = saveFileDialog.FileName; usePassword = false; this.ApplicationMode = AppMode.Open; treeView1.HasChanged = false; break; case 2: TextBoxForm passwordForm = new TextBoxForm("Password", "Password", true); string password = passwordForm.ShowDialog(); saveBookmarkFile_ForJSNX(saveFileDialog.FileName, password ?? string.Empty); this.Text = Path.GetFileNameWithoutExtension(saveFileDialog.FileName) + " - " + Properties.Resources.app_name; sessionFilename = saveFileDialog.FileName; sessionPassword = password; usePassword = true; this.ApplicationMode = AppMode.Open; treeView1.HasChanged = false; break; default: break; } return true; } else { return false; } } protected void saveBookmarkFile_ForJSNX(string filename, string password = "") { List rs = treeView1.GetBookmarkList(); int size = 2048; byte[] buffer = new byte[size]; int bufferSize = 0; ZipOutputStream zipStream = new ZipOutputStream(File.Create(filename)); zipStream.SetLevel(9); zipStream.Password = password; // stream MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(rs))); ms.Position = 0; // write file entry zipStream.PutNextEntry(new ZipEntry("bookmarks.json")); buffer = new byte[size]; bufferSize = 0; do { bufferSize = ms.Read(buffer, 0, buffer.Length); zipStream.Write(buffer, 0, bufferSize); } while (bufferSize > 0); ms.Flush(); ms.Close(); ms.Dispose(); ms = null; zipStream.Finish(); zipStream.Flush(); zipStream.Close(); zipStream.Dispose(); zipStream = null; treeView1.HasChanged = false; } protected void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button != MouseButtons.Right) { return; } switch (treeView1.SNode.GetNodeType()) { case RyzStudio.Windows.Forms.BookmarkTreeView.NodeType.Root: rootTreeNodeMenu.Show(e.Node.TreeView, e.X, e.Y); break; case RyzStudio.Windows.Forms.BookmarkTreeView.NodeType.Folder: folderTreeNodeMenu.Show(e.Node.TreeView, e.X, e.Y); break; case RyzStudio.Windows.Forms.BookmarkTreeView.NodeType.Page: pageTreeNodeMenu.Show(e.Node.TreeView, e.X, e.Y); break; default: break; } } protected void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) => openBookmark(e.Node); protected void treeView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { TreeNode tn = treeView1.SelectedNode; if (tn == null) { return; } NodeType nodeType = treeView1.SNode.GetNodeType(); switch (e.KeyCode) { case Keys.Apps: treeView1_NodeMouseClick(sender, new TreeNodeMouseClickEventArgs(tn, MouseButtons.Right, 1, tn.Bounds.X, tn.Bounds.Y)); return; case Keys.Enter: openBookmark(tn); break; case Keys.F2: if (nodeType == NodeType.Page) { (new BookmarkEditForm(treeView1)).ShowDialog(); } break; case Keys.Insert: if (e.Modifiers != Keys.Shift) { if ((nodeType == NodeType.Root) || (nodeType == NodeType.Folder)) { (new BookmarkEditForm(treeView1)).ShowDialog(); } else if (nodeType == NodeType.Page) { treeView1.SelectedNode = tn.Parent; (new BookmarkEditForm(treeView1)).ShowDialog(); } } break; default: break; } } #region root context menu private void addPageContextMenu_Click(object sender, EventArgs e) => (new BookmarkEditForm(treeView1)).ShowDialog(); private void addFolderContextMenu_Click(object sender, EventArgs e) => treeView1.SelectedNode = treeView1.SNode.AddFolder(); private void editContextMenu_Click(object sender, EventArgs e) => treeView1.SNode.Edit(); private void sortContextMenu_Click(object sender, EventArgs e) => treeView1.SNode.Sort(); #endregion #region folder context menu private void addPageContextMenu2_Click(object sender, EventArgs e) => (new BookmarkEditForm(treeView1)).ShowDialog(); private void addFolderContextMenu2_Click(object sender, EventArgs e) => treeView1.SelectedNode = treeView1.SNode.AddFolder(); private void openAllContextMenu_Click(object sender, EventArgs e) { if (treeView1.SelectedNode == null) { return; } if (treeView1.SelectedNode.Nodes.Count <= 0) { return; } foreach (TreeNode item in treeView1.SelectedNode.Nodes) { openBookmark(item); } } private void editContextMenu2_Click(object sender, EventArgs e) => treeView1.SNode.Edit(); private void deleteContextMenu_Click(object sender, EventArgs e) => treeView1.SNode.Delete(); private void sortContextMenu2_Click(object sender, EventArgs e) => treeView1.SNode.Sort(); private void moveUpContextMenu_Click(object sender, EventArgs e) => treeView1.SNode.MoveUp(); private void moveDownContextMenu_Click(object sender, EventArgs e) => treeView1.SNode.MoveDown(); #endregion #region page context menu private void openContextMenu_Click(object sender, EventArgs e) => openBookmark(treeView1.SelectedNode); private void editContextMenu3_Click(object sender, EventArgs e) => (new BookmarkEditForm(treeView1)).ShowDialog(); private void deleteContextMenu2_Click(object sender, EventArgs e) => treeView1.SNode.Delete(); private void moveUpContextMenu2_Click(object sender, EventArgs e) => treeView1.SNode.MoveUp(); private void moveDownContextMenu2_Click(object sender, EventArgs e) => treeView1.SNode.MoveDown(); #endregion protected void treeView1_OnNodeChanged(object sender, EventArgs e) { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { saveMenuBarItem.Enabled = saveFileMenuItem.Enabled = treeView1.HasChanged; })); } else { saveMenuBarItem.Enabled = saveFileMenuItem.Enabled = treeView1.HasChanged; } } private void loadFileThread_DoWork(object sender, DoWorkEventArgs e) { if (loadFileType == LoadFileType.Jsnx) { loadBookmarkFile_ForJSNX(sessionFilename, sessionPassword ?? string.Empty); } else if (loadFileType == LoadFileType.Ryz) { loadBookmarkFile_ForRYZ(sessionFilename, sessionPassword ?? string.Empty); } } private void loadFileThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { this.IsBusy = false; saveMenuBarItem.Enabled = saveFileMenuItem.Enabled = false; } } }