SuperDesign/Source/开发辅助工具/Tools/SmartEditor/FrmFileBrowser.cs
鑫Intel 03bcb8c5fd ### 2023-02-21更新
------
#### SuperDesign    V3.0.2302.2101
- *.[新增]全新文本编辑器,支持高亮、FTP查看和编辑、目录浏览,历史版本等众多功能。
2023-02-21 09:46:13 +08:00

389 lines
15 KiB
C#

using BrightIdeasSoftware;
using ObjectListViewDemo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ryCommon;
using System.Collections;
using System.Drawing.Drawing2D;
using WeifenLuo.WinFormsUI.Docking;
using .Tools.SmartEditor;
using .Manager;
using Newtonsoft.Json.Linq;
using .Controls;
namespace SuperDesign.Tools.SmartEditor
{
public partial class FrmFileBrowser : DockContent
{
public FrmFileBrowser()
{
InitializeComponent();
SetupColumns();
SetupTree();
TreeListView.TreeRenderer renderer = this.treeListView.TreeColumnRenderer;
renderer.LinePen = new Pen(Color.Firebrick, 0.5f)
{
DashStyle = DashStyle.Dot
};
}
private void Drag_ElevatedDragDrop(object sender, ElevatedDragDropArgs e)
{
if (e.Files.Count == 1)
{
if (System.IO.Directory.Exists(e.Files[0]))
{
Add(e.Files[0]);
}
}
}
private void SetupColumns()
{
// The column setup here is identical to the File Explorer example tab --
// nothing specific to the TreeListView.
// The only difference is that we don't setup anything to do with grouping,
// since TreeListViews can't show groups.
SysImageListHelper helper = new SysImageListHelper(this.treeListView);
this.olvColumnName.ImageGetter = delegate (object x) {
return helper.GetImageIndex(((MyFileSystemInfo)x).FullName);
};
// Get the size of the file system entity.
// Folders and errors are represented as negative numbers
this.olvColumnSize.AspectGetter = delegate (object x) {
MyFileSystemInfo myFileSystemInfo = (MyFileSystemInfo)x;
if (myFileSystemInfo.IsDirectory)
return (long)-1;
try
{
return myFileSystemInfo.Length;
}
catch (System.IO.FileNotFoundException)
{
// Mono 1.2.6 throws this for hidden files
return (long)-2;
}
};
// Show the size of files as GB, MB and KBs. By returning the actual
// size in the AspectGetter, and doing the conversion in the
// AspectToStringConverter, sorting on this column will work off the
// actual sizes, rather than the formatted string.
this.olvColumnSize.AspectToStringConverter = delegate (object rowdata, object x) {
long sizeInBytes = (long)x;
if (sizeInBytes < 0) // folder or error
return "";
return RyFiles.GetFileSizeStr(sizeInBytes);
};
// Show the system description for this object
this.olvColumnFileType.AspectGetter = delegate (object x) {
return ShellUtilities.GetFileType(((MyFileSystemInfo)x).FullName);
};
}
private void SetupTree()
{
// TreeListView require two delegates:
// 1. CanExpandGetter - Can a particular model be expanded?
// 2. ChildrenGetter - Once the CanExpandGetter returns true, ChildrenGetter should return the list of children
// CanExpandGetter is called very often! It must be very fast.
this.treeListView.CanExpandGetter = delegate (object x) {
return ((MyFileSystemInfo)x).IsDirectory;
};
// We just want to get the children of the given directory.
// This becomes a little complicated when we can't (for whatever reason). We need to report the error
// to the user, but we can't just call MessageBox.Show() directly, since that would stall the UI thread
// leaving the tree in a potentially undefined state (not good). We also don't want to keep trying to
// get the contents of the given directory if the tree is refreshed. To get around the first problem,
// we immediately return an empty list of children and use BeginInvoke to show the MessageBox at the
// earliest opportunity. We get around the second problem by collapsing the branch again, so it's children
// will not be fetched when the tree is refreshed. The user could still explicitly unroll it again --
// that's their problem :)
this.treeListView.ChildrenGetter = delegate (object x) {
try
{
return ((MyFileSystemInfo)x).GetFileSystemInfos();
}
catch (UnauthorizedAccessException ex)
{
this.BeginInvoke((MethodInvoker)delegate () {
this.treeListView.Collapse(x);
MessageBox.Show(this, ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
});
return new ArrayList();
}
};
// Once those two delegates are in place, the TreeListView starts working
// after setting the Roots property.
var WorkArea = Itrycn_Db.GetSetting("WorkArea", "");
JArray jarr = WorkArea.Length == 0 ? new JArray() : JArray.Parse(WorkArea);
for (int i = 0; i < jarr.Count; i++)
{
var item = jarr[i];
roots.Add(new MyFileSystemInfo(new DirectoryInfo(item["path"].ToString()), item["name"].ToString()));
}
this.treeListView.Roots = roots;
}
readonly List<MyFileSystemInfo> roots = new List<MyFileSystemInfo>();
private void TreeListView_ItemActivate(object sender, EventArgs e)
{
Object model = this.treeListView.SelectedObject;
if (model != null)
this.treeListView.ToggleExpansion(model);
}
private void TreeListView_MouseDoubleClick(object sender, MouseEventArgs e)
{
MyFileSystemInfo model = (MyFileSystemInfo)this.treeListView.SelectedObject;
if (model != null)
{
if (model.IsDirectory) { return; }
if (model.Length >= 1024*1024 * 20)
{
MessageBox.Show("不支持打开超过20M的文本。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
FrmMainEditor.MainEditor.OpenFile(model.FullName);
}
}
public void Add(string path)
{
var dir_path = path;
var WorkArea = Itrycn_Db.GetSetting("WorkArea", "");
JArray jarr = WorkArea.Length == 0 ? new JArray() : JArray.Parse(WorkArea);
for (int i = jarr.Count - 1; i >= 0; i--)
{
var item = jarr[i];
if (item["path"].ToString().ToLower() == dir_path.ToLower())
{
MessageBox.Show("当前文件夹已存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}
JObject jo = new JObject
{
{ "name", System.IO.Path.GetFileName(dir_path) },
{ "path", dir_path }
};
jarr.Add(jo);
Itrycn_Db.SetSetting("WorkArea", jarr.ToString());
roots.Add(new MyFileSystemInfo(new DirectoryInfo(dir_path), System.IO.Path.GetFileName(dir_path)));
this.treeListView.Roots = roots;
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
if(folderBrowserDialog1.ShowDialog()== DialogResult.OK)
{
var dir_path = folderBrowserDialog1.SelectedPath;
Add(dir_path);
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
MyFileSystemInfo model = (MyFileSystemInfo)this.treeListView.SelectedObject;
if (model == null) { return; }
if (treeListView.GetParent(model)==null)
{
switch (MessageBox.Show("是否要删除工作区?", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2))
{
case DialogResult.No:
return;
}
var WorkArea = Itrycn_Db.GetSetting("WorkArea", "");
JArray jarr = WorkArea.Length == 0 ? new JArray() : JArray.Parse(WorkArea);
for (int i = jarr.Count-1; i>=0; i--)
{
var item = jarr[i];
if (item["path"].ToString().ToLower()== model.FullName.ToLower())
{
jarr.Remove(item);
}
}
roots.Remove(model);
Itrycn_Db.SetSetting("WorkArea", jarr.ToString());
treeListView.RemoveObject(model);
}
}
private void ContextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
MyFileSystemInfo model = (MyFileSystemInfo)this.treeListView.SelectedObject;
if (model == null) { ToolStripMenuItem.Enabled = false; ToolStripMenuItem.Enabled = false;return; }
if (treeListView.GetParent(model) != null)
{
ToolStripMenuItem.Enabled = false;
ToolStripMenuItem.Enabled = false; return;
}
ToolStripMenuItem.Enabled = true;
ToolStripMenuItem.Enabled = true;
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
MyFileSystemInfo model = (MyFileSystemInfo)this.treeListView.SelectedObject;
if (model == null) { return; }
if (treeListView.GetParent(model) == null)
{
FrmTitle frm = new FrmTitle();
frm.TxtTitle.Text = model.Name;
frm.Text = "请输入重命名的名称";
if (frm.ShowDialog() == DialogResult.OK)
{
var WorkArea = Itrycn_Db.GetSetting("WorkArea", "");
JArray jarr = WorkArea.Length == 0 ? new JArray() : JArray.Parse(WorkArea);
for (int i = jarr.Count - 1; i >= 0; i--)
{
var item = jarr[i];
if (item["path"].ToString().ToLower() == model.FullName.ToLower())
{
item["name"] = frm.TxtTitle.Text;
model.Name = frm.TxtTitle.Text;
}
}
Itrycn_Db.SetSetting("WorkArea", jarr.ToString());
treeListView.RefreshObject(model);
}
frm.Dispose();
}
}
private void FrmFileBrowser_Load(object sender, EventArgs e)
{
treeListView.IsSimpleDragSource = true;
}
private void FrmFileBrowser_FormClosing(object sender, FormClosingEventArgs e)
{
//drag.ElevatedDragDrop -= Drag_ElevatedDragDrop;
}
private void TreeListView_Dropped(object sender, OlvDropEventArgs e)
{
}
private void TreeListView_DragDrop(object sender, DragEventArgs e)
{
string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);
if(s!=null && s.Length==1)
{
Add(s[0]);
}
}
private void TreeListView_DragOver(object sender, DragEventArgs e)
{
}
private void TreeListView_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.All;
}
else
{
e.Effect = DragDropEffects.None;
}
}
public void GotoPath(string path)
{
if (path.Length == 0) { return; }
var isexist = false;
MyFileSystemInfo find_item = null;
for (int i = 0; i < roots.Count; i++)
{
var root = roots[i];
if(path.IndexOfEx(root.FullName)==0)
{
treeListView.Expand(root);
Find(root);
if(isexist)
{
break;
}
void Find(MyFileSystemInfo _item)
{
if (_item.FullName.ToLower() == path.ToLower())
{
isexist = true;
find_item = _item;
return;
}
var list = treeListView.GetChildren(_item);
foreach (var _file in list)
{
var file = (MyFileSystemInfo)_file;
if (file.IsDirectory)
{
if (path.IndexOfEx(file.FullName) == 0)
{
treeListView.Expand(file);
if (path.Length == file.FullName.Length)
{
isexist = true;
find_item = file;
break;
}
else
{
Find(file);
continue;
}
}
else { continue; }
}
if (file.FullName.ToLower() == path.ToLower())
{
isexist = true;
find_item = file;
break;
}
}
}
}
}
if (isexist)
{
treeListView.EnsureModelVisible(find_item);
//var aa= treeListView.SelectedObject==find_item;
treeListView.Expand(find_item);
treeListView.SelectedObject = find_item;
//treeListView.Expand(find_item);
}
}
private void ToolStripMenuItem1_Click(object sender, EventArgs e)
{
FrmTitle frm = new FrmTitle();
frm.TxtTitle.Text = Text;
frm.Text = "请输入重命名的工作区名称";
if (frm.ShowDialog() == DialogResult.OK)
{
Text = frm.TxtTitle.Text;
}
frm.Dispose();
}
}
}