using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; using GeoSigmaDrawLib; using Microsoft.VisualBasic.Devices; using UCDraw; namespace SymbolLibManager { /// /// 符号管理界面 /// 这个类有两个作用:一是符号及符号组的增删改查,一是供图层/图元修饰时选择符号 /// 基础概念: /// 最左侧一栏我们称为符号组,对应一个符号文件 /// 中间那栏我们称为符号 /// 右边那栏是符号详情和编辑 /// public partial class FrmMarkMain : Form { public string LibPath { get; set; } private const string CurrentFile = "当前文件"; private readonly List arrItemsCache = new List(); private ImageList lstSymbolImage; public bool IsDirty { get; set; } = false; public const string ClipboardFormatSymbol = "ClipboardFormatSymbol"; private string SelectedFile = ""; private bool OnSearchStatus = false; private GeoSigma.UCDraw.MainView mainView; private readonly DelayedRefreshHelper refreshHelper; private const int delay = 100; public GeoSigmaXY DrawerGeo { get; set; } /// /// 是否显示为符号选择状态 /// public bool ShowInSelectMode { get; set; } = false; public string SelectedSymbolName { get; set; } = null; public FrmMarkMain(string dataPath) : this(null, dataPath) { } public FrmMarkMain(GeoSigmaXY geo, string dataPath) { InitializeComponent(); DrawerGeo = geo; InitSymbolGroup(dataPath); InitSymbols(); SelectFirstGroup(); refreshHelper = new DelayedRefreshHelper(delay, ShowSelectedSymbolGroup); } private void SelectFirstGroup() { if (trvSymbol.Nodes.Count > 0) { TreeNode firstChild = trvSymbol.Nodes[0]; if (firstChild != null && firstChild.Nodes.Count > 0) { TreeNode firstGrandchild = firstChild.Nodes[0]; trvSymbol.SelectedNode = firstGrandchild; } } } private void InitSymbolGroup(string dataPath) { if (string.IsNullOrEmpty(dataPath)) { // 符号表默认目录 var symbolFilePath = Directory.GetParent(Application.StartupPath); LibPath = Path.Combine(symbolFilePath.FullName, "Symbol"); } else { LibPath = dataPath; } string symbolData = ""; GeoSigmaXY.InitLibrary(LibPath, ref symbolData); InitSymbolTree(symbolData); } private void InitSymbols() { lstSymbolImage = new ImageList(); lstSymbolImage.ColorDepth = ColorDepth.Depth24Bit; lstSymbolImage.ImageSize = new Size(50, 50); lsvSymbol.LargeImageList = lstSymbolImage; lsvSymbol.View = View.LargeIcon; lsvSymbol.HideSelection = false; lsvSymbol.VirtualMode = true; lsvSymbol.MultiSelect = false; lsvSymbol.LabelEdit = true; lsvSymbol.ContextMenuStrip = ctmSymbols; } private void ApplicationIdle(object sender, EventArgs e) { try { bool bHasSelected = lsvSymbol.SelectedIndices.Count > 0; bool bHasClip = false; var clipData = Clipboard.GetData(ClipboardFormatSymbol); if (clipData is List lstPxy) { if (lstPxy.Count > 0) { bHasClip = true; } } // 粘贴、添加 tsbtnSymbolPaste.Enabled = (bHasClip && OnSearchStatus == false); ctsbtnPasteSymbol.Enabled = tsbtnSymbolPaste.Enabled; tsbtnListAdd.Enabled = !OnSearchStatus; if (string.IsNullOrEmpty(SelectedFile)) { tsbtnListAdd.Enabled = false; } // 复制 tsbtnSymbolCopy.Enabled = bHasSelected; ctsbtnCopySymbol.Enabled = tsbtnSymbolCopy.Enabled; // 删除、编辑 tsbtnListRemove.Enabled = tsbtnSymbolCopy.Enabled; // (!OnSearchStatus && bHasSelected); ctsbtnDeleteSymbol.Enabled = tsbtnListRemove.Enabled; tsbtnEdit.Enabled = tsbtnListRemove.Enabled; ctsbtnEditName.Enabled = tsbtnEdit.Enabled; var root = trvSymbol.Nodes[0]; bool bGroupChecked = false; foreach (TreeNode node in root.Nodes) { if (node.Checked) { bGroupChecked = true; break; } } tsbtnDeleteFile.Enabled = bGroupChecked; tsbtnExportFile.Enabled = bGroupChecked; } catch { } } /// /// 初始化最左侧的符号组 /// /// 以分号分割的字符串,表示符号组列表 private void InitSymbolTree(string nodeData) { var root = trvSymbol.Nodes.Add("符号库"); root.ImageIndex = 1; root.SelectedImageIndex = 1; root.StateImageIndex = 1; root.Nodes.AddRange(nodeData.Split(';') .Where(itemData => !string.IsNullOrEmpty(itemData)) .Select(itemData => new TreeNode { Text = Path.GetFileNameWithoutExtension(itemData), ImageIndex = 0, Tag = itemData }) .ToArray()); // 如果当前有选中文件,符号组中添加当前文件 if (DrawerGeo != null) { TreeNode currentNode = new TreeNode { Text = CurrentFile, Tag = CurrentFile, }; root.Nodes.Insert(0, currentNode); } root.Expand(); } private void lsvSymbol_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { if (arrItemsCache == null || arrItemsCache.Count == 0) { e.Item = new ListViewItem(); } e.Item = arrItemsCache[e.ItemIndex]; } protected override void OnClosed(EventArgs e) { mainView.CloseFaultEditor(); base.OnClosed(e); } private void FrmMarkMain_Load(object sender, EventArgs e) { mainView = new GeoSigma.UCDraw.MainView(); //设置窗体最大化 mainView.Dock = DockStyle.Fill; //指定当前子窗体显示的容器 mainView.Parent = spMain.Panel2; mainView.BringToFront(); mainView.Show(); mainView.PropertyVisible = true; mainView.LayerVisible = false; mainView.StatisticVisble = false; mainView.ToolstripView.Visible = false; mainView.BeforeSaveFileEvent += MainView_SaveFile; mainView.AutoReleaseView = false; DrawerEnable(false); SetUIMode(); Application.Idle += ApplicationIdle; } private void SetUIMode() { if (ShowInSelectMode) { spMain.Panel2Collapsed = true; tspTree.Visible = false; tspItems.Visible = false; tsbtnOK.Visible = true; tsbtnCancel.Visible = true; } } private ListViewItem CreateSymbolItem(string symbolName, int imageIndex, SymbolItemData itemData) { ListViewItem item = new ListViewItem(symbolName); item.Name = symbolName; item.ImageIndex = imageIndex; item.Tag = itemData; return item; } /// /// 获取分组的符号列表 /// /// 分组名称 /// private List GetGroupSymbolNames(string group) { if (group == null) { return new List(); } SelectedFile = group; if (string.IsNullOrEmpty(SelectedFile)) { return new List(); } return ListSymbols(SelectedFile); } /// /// 添加符号 /// /// private void AddSymbol(SymbolItemData symbol) { CreateBitMap(symbol.Group, symbol.Name, out Bitmap bmp, out IntPtr pXy); SymbolItemData itemData = new SymbolItemData(); itemData.Group = symbol.Group; itemData.Name = symbol.Name; itemData.PtrXY = pXy; ListViewItem item = CreateSymbolItem(symbol.Name, arrItemsCache.Count, itemData); lstSymbolImage.Images.Add(bmp); arrItemsCache.Add(item); lsvSymbol.VirtualListSize = arrItemsCache.Count; } /// /// 查找符号 /// /// private List FindSymbol(string text) { List result = new List(); foreach (string group in ListAllGroups()) { List symbols = ListSymbols(group); foreach (string symbol in symbols) { if (!symbol.Contains(text)) { continue; } var item = new SymbolItemData() { Name = symbol, Group = group, }; result.Add(item); } } return result; } /// /// 清除当前的符号 /// private void ClearSymbols() { foreach (Image image in lstSymbolImage.Images) { image.Dispose(); } arrItemsCache.Clear(); lstSymbolImage.Images.Clear(); lsvSymbol.VirtualListSize = arrItemsCache.Count; } /// /// 查出所有符号组 /// /// 返回符号组列表 private List ListAllGroups() { TreeNode rootNode = trvSymbol.Nodes[0]; return rootNode.Nodes.Cast() .Select(node => node.Tag.ToString()) .ToList(); } private void RemoveGroup(string group) { GeoSigmaXY.LibraryRemoveGroup(group); try { File.Delete(group); } catch { } } private List ListSymbols(string group) { // 获取符号名称列表的逻辑 string strNames = string.Empty; if (group.Equals(CurrentFile)) { // 当前文件时 DrawerGeo?.GetDrawerSymbolNames(ref strNames); } else { GeoSigmaXY.GetLibrarySymbolNames(group, ref strNames); } List symbols = strNames.Split(';') .Where(name => !string.IsNullOrEmpty(name)) .OrderBy(name => name) .ToList(); return symbols; } /// /// 构建同一组的符号 /// /// 符号组 /// private void BuildSymbols(string group, List symbols) { foreach (string symbol in symbols) { SymbolItemData item = new SymbolItemData() { Name = symbol, Group = group, }; AddSymbol(item); } } private void BuildSymbols(List symbols) { foreach (SymbolItemData item in symbols) { AddSymbol(item); } } /// /// 显示左侧选中的符号组 /// private void ShowSelectedSymbolGroup() { TreeNode node = trvSymbol.SelectedNode; OnSearchStatus = false; string group = node.Tag?.ToString(); if (group == null) { return; } ClearSymbols(); List symbolNames = GetGroupSymbolNames(group); BuildSymbols(group, symbolNames); if (lsvSymbol.Items.Count > 0) { lsvSymbol.Items[0].Selected = true; } else { // 如果该组没有任何符号,要清理最右侧的显示,不然会显示上次打开的内容 ClearymbolDetials(); } string strGroupName = Path.GetFileNameWithoutExtension(group); statusLableGroup.Text = $"所属: {strGroupName}"; } private void CreateBitMap(string group, string symbolName, out Bitmap bmp, out IntPtr pXy) { bmp = new Bitmap(50, 50); Graphics gBmp = Graphics.FromImage(bmp); IntPtr pBmpDC = gBmp.GetHdc(); pXy = IntPtr.Zero; if (group.Equals(CurrentFile)) { DrawerGeo?.DrawerDrawSymbol(symbolName, pBmpDC, 50, 50, ref pXy); } else { GeoSigmaXY.LibaryDrawSymbol(group, symbolName, pBmpDC, 50, 50, ref pXy); } gBmp.ReleaseHdc(); } private void CreateBitMap(string symbolName, out Bitmap bmp, out IntPtr pXy) { bmp = new Bitmap(50, 50); Graphics gBmp = Graphics.FromImage(bmp); IntPtr pBmpDC = gBmp.GetHdc(); pXy = IntPtr.Zero; if (SelectedFile.Equals(CurrentFile)) { DrawerGeo?.DrawerDrawSymbol(symbolName, pBmpDC, 50, 50, ref pXy); } else { GeoSigmaXY.LibaryDrawSymbol(SelectedFile, symbolName, pBmpDC, 50, 50, ref pXy); } gBmp.ReleaseHdc(); } private void trvSymbol_AfterSelect(object sender, TreeViewEventArgs e) { //refreshHelper.SelectionChange(); ShowSelectedSymbolGroup(); } /// /// 关闭前 /// /// /// private void FrmMarkMain_FormClosing(object sender, FormClosingEventArgs e) { if (!SelectedFile.Equals(CurrentFile) && mainView.IsDocumentModified()) { IsDirty = true; } if (IsDirty) { DialogResult result = MessageBox.Show( this, "是否保存修改?", "关闭文档", MessageBoxButtons.YesNoCancel); switch (result) { case DialogResult.Yes: // 保存文件 MainView_SaveFile(new CancelEventArgs()); break; case DialogResult.Cancel: e.Cancel = true; return; case DialogResult.No: break; } } } private void FrmMarkMain_FormClosed(object sender, FormClosedEventArgs e) { Application.Idle -= ApplicationIdle; DrawerGeo?.ResetSymbol(); ClearSymbols(); } private void MainView_SaveFile(CancelEventArgs e) { if (!SelectedFile.Equals(CurrentFile) && mainView.IsDocumentModified()) { IsDirty = true; } if (!IsDirty) { e.Cancel = true; return; } bool bSaved = GeoSigmaXY.LibarySaveAll(); if (bSaved) { mainView.SetDocumentModified(!bSaved); // 重新激活左侧当前符号组,让它刷新缩略图 //TreeNode node = trvSymbol.SelectedNode; //trvSymbol.SelectedNode = null; //trvSymbol.SelectedNode = node; updateCurrentSymbolIcon(); } IsDirty = !bSaved; if (e != null) { e.Cancel = true; } } /// /// 查找符号事件 /// /// 查找按钮 /// 事件参数 private void tsbtnFindSymbol_Click(object sender, EventArgs e) { string strSearchName = txtSearchName.Text.Trim(); if (string.IsNullOrEmpty(strSearchName)) { return; } // 设置查询状态标识 OnSearchStatus = true; ClearSymbols(); List symbols = FindSymbol(strSearchName); BuildSymbols(symbols); } private void txtSearchName_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) { e.Handled = true; SendKeys.Send("{TAB}"); tsbtnFindSymbol.PerformClick(); } } /// /// 确定 /// /// /// private void tsbtnOK_Click(object sender, EventArgs e) { if (lsvSymbol.SelectedIndices.Count <= 0) { MessageBox.Show("没有选中任何符号!"); return; } ListViewItem itemLast = lsvSymbol.Items[lsvSymbol.SelectedIndices[0]]; SymbolItemData itemDataLast = itemLast.Tag as SymbolItemData; string strName = itemDataLast.Name; // 检查名称重复 ListViewItem lviFind = arrItemsCache.Find(p => { return p.Text.Equals(strName, StringComparison.CurrentCultureIgnoreCase); }); if (lviFind != null) { IntPtr pxyNew = IntPtr.Zero; DrawerGeo.DrawerCopySymbol(itemDataLast.PtrXY, strName, ref pxyNew); } SelectedSymbolName = strName; DialogResult = DialogResult.OK; Close(); } /// /// 取消 /// /// /// private void tsbtnCancel_Click(object sender, EventArgs e) { if (IsDirty) { DialogResult result = MessageBox.Show(this, "符号已修改,是否放弃修改并退出符号管理界面?", "退出", MessageBoxButtons.YesNo); if (result == DialogResult.No) { return; } } DialogResult = DialogResult.Cancel; Close(); } /// /// 修改符号名称 /// /// /// private void tsbtnEdit_Click(object sender, EventArgs e) { ListView.SelectedIndexCollection selItems = lsvSymbol.SelectedIndices; if (selItems.Count > 0) { lsvSymbol.Items[selItems[0]].BeginEdit(); } } /// /// 修改符号名称 /// /// /// private void lsvSymbol_AfterLabelEdit(object sender, LabelEditEventArgs e) { if (e.Label == null) { return; } string newName = e.Label.Trim(); if (string.IsNullOrEmpty(newName)) { MessageBox.Show("此名称不能为空!"); e.CancelEdit = true; return; } ListViewItem lvi = lsvSymbol.Items[e.Item]; ListViewItem lviFind = null; if (arrItemsCache != null) { lviFind = arrItemsCache.FirstOrDefault(item => item.Text.Equals(newName, StringComparison.CurrentCultureIgnoreCase)); } else { var ie = lsvSymbol.Items.GetEnumerator(); while (ie.MoveNext()) { ListViewItem lviCur = (ListViewItem)ie.Current; if (lviCur.Text.Equals(newName, StringComparison.CurrentCultureIgnoreCase)) { lviFind = lviCur; break; } } } if (lviFind != null) { MessageBox.Show("此名称已经存在!"); e.CancelEdit = true; return; } lvi.Text = newName; lvi.Name = newName; IntPtr ptr = ((SymbolItemData)(lvi.Tag)).PtrXY; if (!SelectedFile.Equals(CurrentFile)) { IsDirty = GeoSigmaXY.SetDrawXyName(ptr, ((SymbolItemData)(lvi.Tag)).Group, newName); ((SymbolItemData)(lvi.Tag)).Name = newName; IsDirty = true; } else { DrawerGeo.RenameSymble(((SymbolItemData)(lvi.Tag)).Name, newName); ((SymbolItemData)(lvi.Tag)).Name = newName; } } /// /// 显示符号预览图大图,最右侧那块儿 /// /// 标识数据 private void ShowSymbolDetials(SymbolItemData itemData) { if (!SelectedFile.Equals(CurrentFile) && mainView.IsDocumentModified()) { IsDirty = true; } mainView.Visible = true; mainView.OpenXy(itemData.PtrXY); mainView.SetBackColor(192, 192, 192); mainView.SetSymbolView(true); RectangleF rect = new RectangleF(-1, -1, 2, 2); mainView.InitlizePaint(rect); DrawerEnable(true); } /// /// 清空符号预览图大图 /// private void ClearymbolDetials() { if (mainView != null) { mainView.Visible = false; } } /// /// 选择符号 /// /// /// private void lsvSymbol_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) { if (e.IsSelected == false || e.Item.Tag == null) { return; } SymbolItemData itemData = e.Item.Tag as SymbolItemData; // 非选择模式 if (!ShowInSelectMode) { ShowSymbolDetials(itemData); } statusLableGroup.Text = $"所属: {Path.GetFileNameWithoutExtension(itemData.Group)}"; } /// /// updates the current symbol icon. /// private void updateCurrentSymbolIcon() { if (lsvSymbol.SelectedIndices != null && lsvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection indices = lsvSymbol.SelectedIndices; int nIndex = indices[0]; ListViewItem item = arrItemsCache[nIndex];// lsvSymbol.Items[nIndex]; //lstSymbolImage.Images.Add(bmp); //arrItemsCache.Add(item); SymbolItemData itemData = item.Tag as SymbolItemData; Bitmap bmp = lstSymbolImage.Images[nIndex] as Bitmap; Graphics gBmp = Graphics.FromImage(bmp); gBmp.Clear(Color.White); IntPtr pBmpDC = gBmp.GetHdc(); IntPtr pXy = itemData.PtrXY; GeoSigmaXY.XyDrawSymbol(pXy, pBmpDC, 50, 50); gBmp.ReleaseHdc(); lstSymbolImage.Images[nIndex] = bmp; lsvSymbol.Invalidate(); } } private void lsvSymbol_ItemCheck(object sender, ItemCheckEventArgs e) { CheckState status = e.NewValue; } private void lsvSymbol_ItemChecked(object sender, ItemCheckedEventArgs e) { bool bChecked = e.Item.Checked; } private string NewSymbolName() { for (int newSymbolIdx = 1; newSymbolIdx < int.MaxValue; newSymbolIdx++) { string strSymbolName = "新建符号" + newSymbolIdx; if (!arrItemsCache.Any(p => p.Text.Equals(strSymbolName, StringComparison.CurrentCultureIgnoreCase))) { return strSymbolName; } } return string.Empty; } /// /// 添加符号 /// /// /// private void tsbtnListAdd_Click(object sender, EventArgs e) { string strSymbolName = NewSymbolName(); IntPtr pXy = IntPtr.Zero; Bitmap bmp = new Bitmap(50, 50); Graphics gBmp = Graphics.FromImage(bmp); gBmp.Clear(Color.White); IntPtr pBmpDC = gBmp.GetHdc(); // 当前文件时 if (SelectedFile.Equals(CurrentFile)) { DrawerGeo.CreateDrawerSymbol(strSymbolName, ref pXy); DrawerGeo.DrawerDrawSymbol(strSymbolName, pBmpDC, 50, 50, ref pXy); } else { GeoSigmaXY.CreateLibrarySymbol(SelectedFile, strSymbolName, ref pXy); GeoSigmaXY.LibaryDrawSymbol(SelectedFile, strSymbolName, pBmpDC, 50, 50, ref pXy); } gBmp.ReleaseHdc(); SymbolItemData itemData = new SymbolItemData() { Group = SelectedFile, Name = strSymbolName, PtrXY = pXy, }; ListViewItem item = new ListViewItem(strSymbolName); item.Name = strSymbolName; item.ImageIndex = lstSymbolImage.Images.Count; item.Tag = itemData; arrItemsCache.Add(item); lstSymbolImage.Images.Add(bmp); lsvSymbol.VirtualListSize = arrItemsCache.Count; SelectSymbol(arrItemsCache.Count - 1); IsDirty = true; } private void SelectSymbol(int nIndex) { lsvSymbol.Focus(); if (nIndex >= lsvSymbol.Items.Count) { return; } lsvSymbol.Items[nIndex].Selected = true; if (lsvSymbol.SelectedIndices != null && lsvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection indices = lsvSymbol.SelectedIndices; lsvSymbol.Items[indices[0]].Selected = false; } lsvSymbol.Items[nIndex].Selected = true; lsvSymbol.EnsureVisible(nIndex); } /// /// 移除符号 /// /// 符号下标 private void RemoveSymbol(int index) { string strName = lsvSymbol.Items[index].Text; SymbolItemData itemData = lsvSymbol.Items[index].Tag as SymbolItemData; IntPtr pXy = itemData.PtrXY; ListViewItem cachedItem = arrItemsCache.FirstOrDefault(item => { SymbolItemData itemDataFind = (SymbolItemData)item.Tag; return itemDataFind.PtrXY == pXy; }); if (cachedItem != null) { arrItemsCache.Remove(cachedItem); } lsvSymbol.VirtualListSize = arrItemsCache.Count; if (pXy == IntPtr.Zero) { return; } if (SelectedFile.Equals(CurrentFile)) { // 当前文件时 DrawerGeo.RemoveDrawerSymbol(pXy); } else { IsDirty = GeoSigmaXY.RemoveLibrarySymbol(SelectedFile, pXy); } } /// /// 选中下一个符号 /// /// 被删除的 index 下标 private void SelectNextSymbol(int index) { if (index == arrItemsCache.Count) { index = arrItemsCache.Count - 1; } if (index >= 0 && index < arrItemsCache.Count) { lsvSymbol.Items[index].Selected = true; } else { // 清空画布 DrawerEnable(false); mainView.ClearGeo(); } } /// /// 删除符号 /// /// /// private void tsbtnListRemove_Click(object sender, EventArgs e) { ListView.SelectedIndexCollection selItems = lsvSymbol.SelectedIndices; if (arrItemsCache == null || selItems.Count == 0) { return; } int index = selItems[0]; RemoveSymbol(index); SelectNextSymbol(index); } private void DrawerEnable(bool enable) { mainView.ToolDefault(); mainView.ToolstripElements.Enabled = enable; mainView.ToolstripView.Enabled = enable; //mainView.ToolAntiAlias(false); } /// /// 符号拷贝 /// /// 拷贝按钮 /// 事件参数 private void tsbtnSymbolCopy_Click(object sender, EventArgs e) { List lstXyData = new List(); foreach (int indice in lsvSymbol.SelectedIndices) { var item = lsvSymbol.Items[indice]; SymbolItemData itemData = (SymbolItemData)item.Tag; string strXyData = GeoSigmaXY.WriteXy2DFD(itemData.PtrXY); lstXyData.Add(strXyData); } if (lstXyData.Count > 0) { Clipboard.Clear(); Clipboard.SetData(ClipboardFormatSymbol, lstXyData); } } /// /// 粘贴事件 /// /// 粘贴按钮 /// 事件参数 private void tsbtnSymbolPaste_Click(object sender, EventArgs e) { List lstXyData = (List)Clipboard.GetData(ClipboardFormatSymbol); if (lstXyData == null) { return; } foreach (string xyData in lstXyData) { IntPtr pXy = GeoSigmaXY.CreateXyFromDFD(xyData); string strName = GeoSigmaXY.GetDrawXyName(pXy); // 检查名称重复 int nNameAppend = 0; string strNameSource = strName; while (true) { if (nNameAppend == 0) { strName = strNameSource; } else { strName = $"{strNameSource}{nNameAppend}"; } ListViewItem lviFind = arrItemsCache.Find(p => { return p.Text.Equals(strName, StringComparison.CurrentCultureIgnoreCase); }); if (lviFind != null) { nNameAppend++; continue; } break; } Bitmap bmp = new Bitmap(50, 50); Graphics gBmp = Graphics.FromImage(bmp); IntPtr pBmpDC = gBmp.GetHdc(); IntPtr pxyNew = IntPtr.Zero; // 当前文件时 if (SelectedFile.Equals(CurrentFile)) { DrawerGeo.DrawerCopySymbol(pXy, strName, ref pxyNew); DrawerGeo.DrawerDrawSymbol(strName, pBmpDC, 50, 50, ref pxyNew); } else { GeoSigmaXY.LibraryCopySymbol(SelectedFile, pXy, strName, ref pxyNew); GeoSigmaXY.LibaryDrawSymbol(SelectedFile, strName, pBmpDC, 50, 50, ref pxyNew); IsDirty = true; } gBmp.ReleaseHdc(); lstSymbolImage.Images.Add(bmp); SymbolItemData itemData = new SymbolItemData(); itemData.Name = strName; itemData.PtrXY = pxyNew; itemData.Group = SelectedFile; ListViewItem item = new ListViewItem(strName); item.Name = strName; item.ImageIndex = lstSymbolImage.Images.Count - 1; item.Tag = itemData; arrItemsCache.Add(item); } lsvSymbol.VirtualListSize = arrItemsCache.Count; SelectSymbol(arrItemsCache.Count - 1); } private void ctmSymbols_Opening(object sender, CancelEventArgs e) { //string strMsg = sender.ToString(); } private string NewGroupName() { List fileNames = Directory.EnumerateFiles(LibPath) .Select(path => Path.GetFileName(path)) .ToList(); for (int newIndex = 1; newIndex < int.MaxValue; newIndex++) { string newFileName = $"自定义符号{newIndex}.kev"; if (!fileNames.Any(s => s.Equals(newFileName, StringComparison.OrdinalIgnoreCase))) { return newFileName; } } return string.Empty; } /// /// 新建分组 /// /// /// private void tsbtnNewGroup_Click(object sender, EventArgs e) { string newFilename = NewGroupName(); string strNewFile = Path.Combine(LibPath, newFilename); File.Create(strNewFile).Close(); AddNewGroup(strNewFile); } /// /// 添加新符号库 /// /// 符号文件 private void AddNewGroup(string strNewFile) { GeoSigmaXY.LibraryAddNewGroup(strNewFile); TreeNode tnGroup = new TreeNode(); tnGroup.Text = Path.GetFileNameWithoutExtension(strNewFile); tnGroup.ImageIndex = 0; tnGroup.Tag = strNewFile; var root = trvSymbol.Nodes[0]; root.Nodes.Add(tnGroup); trvSymbol.SelectedNode = tnGroup; } /// /// 删除分组 /// /// /// private void tsbtnDeleteFile_Click(object sender, EventArgs e) { var root = trvSymbol.Nodes[0]; List lstCheckedNodes = root.Nodes.Cast().Where(node => node.Checked).ToList(); if (lstCheckedNodes.Count == 0) { return; } if (MessageBox.Show("是否删除选中符号库?") != DialogResult.OK) { return; } trvSymbol.BeginUpdate(); TreeNode tnNext = lstCheckedNodes[lstCheckedNodes.Count - 1].NextNode; for (int i = 0; i < lstCheckedNodes.Count; i++) { string strFileName = lstCheckedNodes[i].Tag as string; RemoveGroup(strFileName); lstCheckedNodes[i].Remove(); } trvSymbol.EndUpdate(); ClearSymbols(); if (tnNext == null && root.Nodes.Count > 0) { tnNext = root.Nodes[root.Nodes.Count - 1]; } if (tnNext != null) { trvSymbol.SelectedNode = tnNext; } } /// /// 从文件导入符号 /// /// 事件按钮 /// 事件参数 private void tsbtnImportFile_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.RestoreDirectory = true; ofd.Filter = "*.kev|*.kev|*.pcg|*.pcg|*.*|*.*"; if (ofd.ShowDialog() != DialogResult.OK) { return; } if (!Directory.Exists(LibPath)) { Directory.CreateDirectory(LibPath); } string strFile = ofd.FileName; string strFileNew = string.Empty; // string strDir = Path.GetDirectoryName(strFile); string strOldName = Path.GetFileNameWithoutExtension(strFile); string[] straOldFiles = Directory.GetFiles(LibPath); string strFind = straOldFiles.FirstOrDefault(it => { string strName = Path.GetFileNameWithoutExtension(it); return strName.Equals(strOldName); }); if (strFind != null) { strOldName += "1"; strFileNew = Path.Combine(LibPath, strOldName + Path.GetExtension(strFile)); } else { strFileNew = Path.Combine(LibPath, Path.GetFileName(strFile)); } Cursor.Current = Cursors.WaitCursor; trvSymbol.BeginUpdate(); FileInfo fi = new FileInfo(strFile); fi.CopyTo(strFileNew); AddNewGroup(strFileNew); Cursor.Current = Cursors.Default; trvSymbol.EndUpdate(); } /// /// 符号导出到文件 /// /// 符号导出事件 /// 事件参数 private void tsbtnExportFile_Click(object sender, EventArgs e) { FolderBrowserDialog fldDlg = new FolderBrowserDialog(); fldDlg.Description = @"将选中节点的符号导出到指定文件夹中。 文件名为符号的类别名。"; if (fldDlg.ShowDialog() != DialogResult.OK) { return; } string strDir = fldDlg.SelectedPath; if (!Directory.Exists(strDir)) { Directory.CreateDirectory(strDir); } // 保存编辑中的图形 MainView_SaveFile(null); var root = trvSymbol.Nodes[0]; List lstCheckedNodes = new List(); foreach (TreeNode node in root.Nodes) { if (!node.Checked) { continue; } string strFileSource = node.Tag as string; string strNameDes = Path.GetFileName(strFileSource); string strFileDes = Path.Combine(strDir, strNameDes); bool bOverwrite = false; if (File.Exists(strFileDes)) { DialogResult result = MessageBox.Show(this, $@"存在同名的文件“{strNameDes}”,覆盖还是跳过? 选择“是”,进行覆盖; 选择“否”,则跳过; 选择“取消”,则终止导入。", "导出", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result == DialogResult.Cancel) { break; } else if (result == DialogResult.Yes) { bOverwrite = true; } else { bOverwrite = false; continue; } } FileInfo fi = new FileInfo(strFileSource); try { fi.CopyTo(strFileDes, bOverwrite); } catch (Exception ex) { MessageBox.Show(ex.Message); } } MessageBox.Show("导出成功!"); } /// /// 删除选中文件 /// /// /// private void tmiDeleteFile_Click(object sender, EventArgs e) { if (trvSymbol.SelectedNode == null) { return; } DialogResult result = MessageBox.Show($"要删除选中“{trvSymbol.SelectedNode.Text}”吗?\r\n删除后不可恢复!" , "删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result != DialogResult.Yes) { return; } string strFileName = trvSymbol.SelectedNode.Tag as string; GeoSigmaXY.LibraryRemoveGroup(strFileName); trvSymbol.SelectedNode.Remove(); try { File.Delete(strFileName); } catch { } } /// /// 重命名选中文件 /// /// /// private void tmiRename_Click(object sender, EventArgs e) { trvSymbol.SelectedNode?.BeginEdit(); } // 重命名符号组 private void trvSymbol_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) { if (string.IsNullOrEmpty(e.Label)) { return; } string strFileName = trvSymbol.SelectedNode.Tag as string; string strNewFile = e.Label + Path.GetExtension(strFileName); string strNewFileFull = Path.Combine(Path.GetDirectoryName(strFileName), strNewFile); if (GeoSigmaXY.LibraryRenameGroup(strFileName, strNewFileFull) != true) { e.CancelEdit = true; // 取消节点的编辑操作 MessageBox.Show("重命名失败!"); return; } Computer MyComputer = new Computer(); MyComputer.FileSystem.RenameFile(strFileName, strNewFile); trvSymbol.SelectedNode.Tag = strNewFileFull; } /// /// 鼠标点击,右键菜单 /// /// /// private void trvSymbol_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { Point point = new Point(e.X, e.Y); TreeNode treeNode = trvSymbol.GetNodeAt(point); if (treeNode == trvSymbol.Nodes[0]) { return; } trvSymbol.SelectedNode = treeNode; if (e.Button == MouseButtons.Right) { if (treeNode.Text == CurrentFile) { EnableRenameDeleteItems(false); } else { EnableRenameDeleteItems(true); } //显示上下文菜单 ctmTree.Show(trvSymbol.PointToScreen(point)); } } private void EnableRenameDeleteItems(bool enabled) { ctmTree.Items.OfType() .Where(x => x.Text == "重命名" || x.Text == "删除") .ToList() .ForEach(x => x.Enabled = enabled); } private void tmiMerge_Click(object sender, EventArgs e) { if (trvSymbol.SelectedNode == null || string.IsNullOrWhiteSpace(SelectedFile)) { return; } // 选择文件 var dialog = new OpenFileDialog { Filter = "*.kev;*.dfd;*.pcg|*kev;*.dfd;*.pcg" }; if (dialog.ShowDialog(this) != DialogResult.OK) { return; } // 合并符号 MergeSymbol(dialog.FileName); // 刷新 ShowSelectedSymbolGroup(); } private void MergeSymbol(string mergeFile) { if (SelectedFile.Equals(CurrentFile)) { MergeSymbol(DrawerGeo.GetDrawerXy(), mergeFile); } else { MergeSymbol(SelectedFile, mergeFile); } } private void MergeSymbol(string sourceFile, string mergeFile) { var drawerData = new DrawerData(); if (drawerData.OpenFile(SelectedFile)) { drawerData.MergeSymbol(mergeFile); drawerData.SaveAs(sourceFile); drawerData.Dispose(); // FIXME: 符号库里面有缓存,这里需要重新加载一下, // 也许正确的方法应该是符号库去追踪文件变化,然后自动重新加载 GeoSigmaLib.LibraryReloadGroup(sourceFile); } } private void MergeSymbol(IntPtr sourceXy, string mergeFile) { var drawerData = new DrawerData(); drawerData.OpenXy(sourceXy); drawerData.MergeSymbol(mergeFile); drawerData.Dispose(); } } public class SymbolItemData { public string Group { get; set; } public string Name { get; set; } public IntPtr PtrXY { get; set; } } }