1241 lines
38 KiB
C#
1241 lines
38 KiB
C#
using BookmarkManager;
|
|
using bzit.bomg.Models;
|
|
using FizzyLauncher.Models;
|
|
using Newtonsoft.Json;
|
|
using RyzStudio.Windows.Forms;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace FizzyLauncher
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
public enum AppMode
|
|
{
|
|
Clear = 0,
|
|
Open,
|
|
New
|
|
}
|
|
|
|
|
|
protected IconDatabase iconDatabase = null;
|
|
protected UpdateIconsForm updateIconsForm = null;
|
|
protected OptionsForm optionsForm = null;
|
|
protected FindForm findForm = 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();
|
|
|
|
jsonfigFilename = Path.ChangeExtension(Application.ExecutablePath, "jsonfig");
|
|
|
|
if (iconDatabase == null) iconDatabase = new IconDatabase(Path.ChangeExtension(Application.ExecutablePath, "db"));
|
|
|
|
this.AutoScaleMode = AutoScaleMode.None;
|
|
this.StartPosition = FormStartPosition.WindowsDefaultLocation;
|
|
this.ClientSize = new System.Drawing.Size(300, 580);
|
|
//this.Visible = false;
|
|
|
|
treeView1.IconDatabase = iconDatabase;
|
|
treeView1.RootContextMenu = rootContextMenu;
|
|
treeView1.FolderContextMenu = folderContextMenu;
|
|
treeView1.PageContextMenu = pageContextMenu;
|
|
treeView1.NodeMouseDoubleClick += treeView1_NodeMouseDoubleClick;
|
|
treeView1.OnNodeChanged += treeView1_OnNodeChanged;
|
|
treeView1.PreviewKeyDown += treeView1_PreviewKeyDown;
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
{
|
|
base.OnLoad(e);
|
|
|
|
//ThreadControl.SetVisible(this, false);
|
|
ThreadControl.SetSize(this, 300, 580);
|
|
|
|
List<string> supportedFileExtensions = GetSupportedFileTypes();
|
|
|
|
openFileDialog1.Filter = BuildOpenFileSupportedFiles(supportedFileExtensions);
|
|
saveFileDialog1.Filter = BuildSaveFileSupportedFiles(supportedFileExtensions);
|
|
|
|
ApplicationMode = AppMode.Clear;
|
|
}
|
|
|
|
protected async override void OnShown(EventArgs e)
|
|
{
|
|
base.OnShown(e);
|
|
|
|
//ThreadControl.SetVisible(this, false);
|
|
|
|
await LoadAppSession(jsonfigFilename);
|
|
|
|
InvalidateAppSession();
|
|
|
|
string[] commandLineArgs = Environment.GetCommandLineArgs();
|
|
|
|
bool hasCommands = await LoadCommandLine(commandLineArgs);
|
|
if (!hasCommands)
|
|
{
|
|
newToolStripMenuItem_Click(null, null);
|
|
}
|
|
}
|
|
|
|
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();
|
|
iconDatabase?.Close();
|
|
|
|
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(toolStripButton3, false);
|
|
ThreadControl.SetEnable(saveAsToolStripMenuItem, false);
|
|
|
|
ThreadControl.SetEnable(findToolStripMenuItem, false);
|
|
ThreadControl.SetEnable(toolStripButton4, false);
|
|
|
|
ThreadControl.SetEnable(toolStripMenuItem9, false);
|
|
|
|
ThreadControl.SetEnable(expandAllToolStripMenuItem, false);
|
|
ThreadControl.SetEnable(collapseAllToolStripMenuItem, false);
|
|
|
|
break;
|
|
case AppMode.Open:
|
|
ThreadControl.SetEnable(closeToolStripMenuItem, true);
|
|
|
|
ThreadControl.SetEnable(saveToolStripMenuItem, true);
|
|
ThreadControl.SetEnable(toolStripButton3, true);
|
|
ThreadControl.SetEnable(saveAsToolStripMenuItem, true);
|
|
|
|
ThreadControl.SetEnable(findToolStripMenuItem, true);
|
|
ThreadControl.SetEnable(toolStripButton4, true);
|
|
|
|
ThreadControl.SetEnable(toolStripMenuItem9, 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(toolStripButton3, false);
|
|
ThreadControl.SetEnable(saveAsToolStripMenuItem, true);
|
|
|
|
ThreadControl.SetEnable(findToolStripMenuItem, true);
|
|
ThreadControl.SetEnable(toolStripButton4, true);
|
|
|
|
ThreadControl.SetEnable(toolStripMenuItem9, true);
|
|
|
|
ThreadControl.SetEnable(expandAllToolStripMenuItem, true);
|
|
ThreadControl.SetEnable(collapseAllToolStripMenuItem, true);
|
|
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#region main menu
|
|
|
|
/// <summary>
|
|
/// New
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open file
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save As
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exit
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.Close();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void findToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (findForm == null) findForm = new FindForm(treeView1);
|
|
findForm.Show();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Expand all
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Collapse all
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Always on top
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void alwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
this.TopMost = !this.TopMost;
|
|
|
|
alwaysOnTopToolStripMenuItem.Checked = this.TopMost;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Update icons
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void toolStripMenuItem9_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (updateIconsForm == null) updateIconsForm = new UpdateIconsForm(this.CurrentSession, treeView1, iconDatabase);
|
|
updateIconsForm.ShowDialog();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Options
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
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();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// View help
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void viewHelpToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
System.Diagnostics.Process.Start("https://www.hiimray.co.uk/software-bookmark-manager");
|
|
}
|
|
catch
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// About
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show(Application.ProductName + " v" + Application.ProductVersion, "About", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region context menu
|
|
|
|
/// <summary>
|
|
/// Add page
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void addPageToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (treeView1.GetNodeType() == BookmarkTreeView.NodeType.Page)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (treeView1.SelectedNode == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// add placeholder
|
|
TreeNode node = treeView1.AddItem(treeView1.SelectedNode, new BookmarkItem()
|
|
{
|
|
SiteName = "New Bookmark"
|
|
});
|
|
node.EnsureVisible();
|
|
treeView1.SelectedNode = node;
|
|
|
|
UpdateBookmarkNode(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add folder
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void addFolderToolStripMenuItem_Click(object sender, EventArgs e) => treeView1.AddFolder();
|
|
|
|
/// <summary>
|
|
/// Edit root node
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void editToolStripMenuItem_Click(object sender, EventArgs e) => treeView1.EditNode();
|
|
|
|
/// <summary>
|
|
/// Sort
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void sortToolStripMenuItem_Click(object sender, EventArgs e) => treeView1.Sort();
|
|
|
|
|
|
/// <summary>
|
|
/// Add page
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void addPageToolStripMenuItem1_Click(object sender, EventArgs e) => addPageToolStripMenuItem_Click(sender, e);
|
|
|
|
/// <summary>
|
|
/// Add folder
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void addFolderToolStripMenuItem1_Click(object sender, EventArgs e) => treeView1.AddFolder();
|
|
|
|
/// <summary>
|
|
/// Open all pages
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void openAllToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (treeView1.SelectedNode == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (treeView1.SelectedNode.Nodes.Count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (TreeNode item in treeView1.SelectedNode.Nodes)
|
|
{
|
|
await OpenBookmark(item);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Edit folder name
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void editToolStripMenuItem1_Click(object sender, EventArgs e) => treeView1.EditNode();
|
|
|
|
/// <summary>
|
|
/// Delete folder and contents
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void deleteToolStripMenuItem_Click(object sender, EventArgs e) => treeView1.DeleteNode();
|
|
|
|
/// <summary>
|
|
/// Sort children
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void sortToolStripMenuItem1_Click(object sender, EventArgs e) => treeView1.Sort();
|
|
|
|
/// <summary>
|
|
/// Move up
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void moveUpToolStripMenuItem_Click(object sender, EventArgs e) => treeView1.MoveUp();
|
|
|
|
/// <summary>
|
|
/// Move down
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void moveDownToolStripMenuItem_Click(object sender, EventArgs e) => treeView1.MoveDown();
|
|
|
|
|
|
/// <summary>
|
|
/// Open page
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void openToolStripMenuItem1_Click(object sender, EventArgs e) => await OpenBookmark(treeView1.SelectedNode);
|
|
|
|
/// <summary>
|
|
/// Edit page
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void editToolStripMenuItem2_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BookmarkTreeView.NodeType nodeType = treeView1.GetNodeType();
|
|
if (nodeType == BookmarkTreeView.NodeType.Page)
|
|
{
|
|
UpdateBookmarkNode(false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete page
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void deleteToolStripMenuItem1_Click(object sender, EventArgs e) => treeView1.DeleteNode();
|
|
|
|
/// <summary>
|
|
/// Move up
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void moveUpToolStripMenuItem1_Click(object sender, EventArgs e) => treeView1.MoveUp();
|
|
|
|
/// <summary>
|
|
/// Move down
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void moveDownToolStripMenuItem1_Click(object sender, EventArgs e) => treeView1.MoveDown();
|
|
|
|
#endregion
|
|
|
|
|
|
private async void treeView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
|
{
|
|
TreeNode tn = treeView1.SelectedNode;
|
|
if (tn == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BookmarkTreeView.NodeType nodeType = treeView1.GetNodeType();
|
|
|
|
switch (e.KeyCode)
|
|
{
|
|
case Keys.Enter:
|
|
await OpenBookmark(tn);
|
|
break;
|
|
case Keys.F2:
|
|
editToolStripMenuItem2_Click(sender, null);
|
|
break;
|
|
case Keys.Insert:
|
|
if (e.Modifiers != Keys.Shift)
|
|
{
|
|
if ((nodeType == BookmarkTreeView.NodeType.Root) || (nodeType == BookmarkTreeView.NodeType.Folder))
|
|
{
|
|
// do nothing
|
|
}
|
|
else if (nodeType == BookmarkTreeView.NodeType.Page)
|
|
{
|
|
treeView1.SelectedNode = tn.Parent;
|
|
}
|
|
|
|
addPageToolStripMenuItem_Click(sender, null);
|
|
}
|
|
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
private async void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) => await OpenBookmark(e.Node);
|
|
|
|
private void treeView1_OnNodeChanged(object sender, EventArgs e)
|
|
{
|
|
bool state = (treeView1.HasChanged && ApplicationMode == AppMode.Open);
|
|
|
|
ThreadControl.SetEnable(saveToolStripMenuItem, state);
|
|
ThreadControl.SetEnable(toolStripButton3, state);
|
|
}
|
|
|
|
protected string BuildOpenFileSupportedFiles(List<string> supportList)
|
|
{
|
|
StringBuilder rs = new StringBuilder();
|
|
rs.Append("All supported files (*" + string.Join("; *", supportList) + ")");
|
|
rs.Append("|*" + string.Join(";*", supportList));
|
|
|
|
for (int i = 0; i < supportList.Count; i++)
|
|
{
|
|
rs.Append("|" + supportList[i].TrimStart('.')?.ToUpper() + " Bookmark files");
|
|
rs.Append("|*" + supportList[i]);
|
|
}
|
|
|
|
return rs.ToString();
|
|
}
|
|
|
|
protected string BuildSaveFileSupportedFiles(List<string> supportList)
|
|
{
|
|
StringBuilder rs = new StringBuilder();
|
|
|
|
for (int i = 0; i < supportList.Count; i++)
|
|
{
|
|
if (i > 0) rs.Append("|");
|
|
|
|
rs.Append(supportList[i].TrimStart('.')?.ToUpper() + " Bookmark file");
|
|
rs.Append("|*" + supportList[i]);
|
|
}
|
|
|
|
return rs.ToString();
|
|
}
|
|
|
|
protected async Task<Result> CloseFile()
|
|
{
|
|
return await Task.Run<Result>(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<Type> 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 List<string> GetSupportedFileTypes()
|
|
{
|
|
List<string> rs = new List<string>();
|
|
|
|
List<Type> typeList = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsSubclassOf(typeof(SupportedFileBase))).ToList();
|
|
foreach (Type t in typeList)
|
|
{
|
|
SupportedFileBase fileHandler = (SupportedFileBase)Activator.CreateInstance(t);
|
|
if (fileHandler == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
rs.AddRange(fileHandler.SupportedExtensions ?? new List<string>());
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
protected void InvalidateAppSession()
|
|
{
|
|
if (CurrentSession == null) CurrentSession = new AppSession();
|
|
|
|
if (CurrentSession.EnableAutoPosition)
|
|
{
|
|
this.Height = Screen.PrimaryScreen.WorkingArea.Height;
|
|
this.Location = Screen.PrimaryScreen.WorkingArea.Location;
|
|
}
|
|
|
|
toolStrip1.Visible = CurrentSession.ShowToolbar;
|
|
|
|
this.TopMost = CurrentSession.AlwaysOnTop;
|
|
}
|
|
|
|
protected async Task<bool> 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<AppSession>(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<bool> LoadCommandLine(string[] args)
|
|
{
|
|
bool rs = false;
|
|
|
|
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;
|
|
|
|
await LoadFile(openFilename);
|
|
|
|
//LoadBookmarksForm loadFileForm = new LoadBookmarksForm(this, openFilename);
|
|
//loadFileForm.ShowDialog();
|
|
|
|
rs = true;
|
|
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return rs;
|
|
}
|
|
|
|
protected async Task<Result> 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();
|
|
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 OpenBookmark(TreeNode node)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
if (BookmarkTreeView.GetNodeType(node) != BookmarkTreeView.NodeType.Page)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BookmarkItem viewModel = (BookmarkItem)node.Tag;
|
|
if (viewModel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(viewModel.SiteAddress))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string cmd = (string.IsNullOrWhiteSpace(CurrentSession.RunCommand) ? viewModel.SiteAddress : CurrentSession.RunCommand.Replace("{0}", viewModel.SiteAddress));
|
|
|
|
try
|
|
{
|
|
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo
|
|
{
|
|
FileName = cmd,
|
|
UseShellExecute = true
|
|
};
|
|
System.Diagnostics.Process.Start(psi);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
#if DEBUG
|
|
MessageBox.Show(exc.Message);
|
|
#endif
|
|
}
|
|
});
|
|
}
|
|
|
|
protected async Task<Result> 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<bool> 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<Result> 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();
|
|
if (passwordForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(passwordForm.Password))
|
|
{
|
|
password = passwordForm.Password;
|
|
}
|
|
}
|
|
}
|
|
|
|
Result result = fileHandler.Save(treeView1, filename, password);
|
|
if (result.IsSuccess)
|
|
{
|
|
this.ApplicationMode = AppMode.Open;
|
|
sessionFilename = filename;
|
|
sessionPassword = password;
|
|
|
|
treeView1.SetNoChanges();
|
|
}
|
|
|
|
return result;
|
|
});
|
|
}
|
|
|
|
protected void UpdateBookmarkNode(bool deleteOnCancel)
|
|
{
|
|
BookmarkItem model = treeView1.GetNodeModel();
|
|
Image icon = null;
|
|
|
|
// retrieve icon from DB
|
|
string iconID = model?.ToHash();
|
|
|
|
icon = iconDatabase.FindIcon(iconID);
|
|
|
|
BookmarkForm bookmarkForm = new BookmarkForm(this.CurrentSession, model, icon);
|
|
if (bookmarkForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
//string iconID = bookmarkForm.Model.Item?.ToHash();
|
|
iconID = bookmarkForm.Model.Item?.ToHash();
|
|
if (!string.IsNullOrWhiteSpace(iconID))
|
|
{
|
|
iconDatabase.AddIcon(iconID, bookmarkForm.Model.Icon);
|
|
}
|
|
|
|
treeView1.UpdateItem(treeView1.SelectedNode, bookmarkForm.Model.Item);
|
|
}
|
|
else
|
|
{
|
|
if (deleteOnCancel)
|
|
{
|
|
treeView1.SelectedNode.Remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
} |