|
|
using DevExpress.XtraScheduler.Outlook.Native;
|
|
|
using GeoSigmaDrawLib;
|
|
|
using Microsoft.VisualBasic.Devices;
|
|
|
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 UCDraw;
|
|
|
|
|
|
namespace SymbolLibManager
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 符号管理界面
|
|
|
/// 这个类有两个作用:一是符号及符号组的增删改查,一是供图层/图元修饰时选择符号
|
|
|
/// 基础概念:
|
|
|
/// 最左侧一栏我们称为符号组,对应一个符号文件
|
|
|
/// 中间那栏我们称为符号
|
|
|
/// 右边那栏是符号详情和编辑
|
|
|
/// </summary>
|
|
|
public partial class FrmMarkMain : Form
|
|
|
{
|
|
|
public string LibPath { get; set; }
|
|
|
|
|
|
private const string CurrentFile = "当前文件";
|
|
|
private readonly List<ListViewItem> arrItemsCache = new List<ListViewItem>();
|
|
|
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; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否显示为符号选择状态
|
|
|
/// </summary>
|
|
|
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();
|
|
|
tsbtnRemoveSymbol.Visible = false; // 初始默认隐藏
|
|
|
|
|
|
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);
|
|
|
var symbolFilePath = Path.GetFullPath(Path.Combine(Application.StartupPath, ".."));
|
|
|
LibPath = Path.Combine(symbolFilePath, "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;
|
|
|
|
|
|
// 允许使用鼠标框选
|
|
|
lsvSymbol.MultiSelect = true; // 必须设为 true
|
|
|
// 确保父容器允许捕获鼠标移动
|
|
|
lsvSymbol.FullRowSelect = true;
|
|
|
}
|
|
|
|
|
|
private void ApplicationIdle(object sender, EventArgs e)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 获取选中项的数量
|
|
|
int selectedCount = lsvSymbol.SelectedIndices.Count;
|
|
|
bool bHasSelected = selectedCount > 0;
|
|
|
bool bSingleSelected = selectedCount == 1; // 是否只选中了一个
|
|
|
|
|
|
bool bHasClip = false;
|
|
|
var clipData = Clipboard.GetData(ClipboardFormatSymbol);
|
|
|
if (clipData is List<string> 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 = bHasSelected;
|
|
|
ctsbtnDeleteSymbol.Enabled = tsbtnListRemove.Enabled;
|
|
|
|
|
|
// 编辑名称逻辑:通常只在选中单个符号时允许编辑
|
|
|
tsbtnEdit.Enabled = bSingleSelected;
|
|
|
ctsbtnEditName.Enabled = bSingleSelected;
|
|
|
|
|
|
// 符号库(左侧树)逻辑
|
|
|
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
|
|
|
{
|
|
|
// 静默处理异常以防 Idle 事件崩溃影响 UI 响应
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 初始化最左侧的符号组
|
|
|
/// </summary>
|
|
|
/// <param name="nodeData">以分号分割的字符串,表示符号组列表</param>
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取分组的符号列表
|
|
|
/// </summary>
|
|
|
/// <param name="group">分组名称</param>
|
|
|
/// <returns></returns>
|
|
|
private List<string> GetGroupSymbolNames(string group)
|
|
|
{
|
|
|
if (group == null)
|
|
|
{
|
|
|
return new List<string>();
|
|
|
}
|
|
|
|
|
|
SelectedFile = group;
|
|
|
if (string.IsNullOrEmpty(SelectedFile))
|
|
|
{
|
|
|
return new List<string>();
|
|
|
}
|
|
|
|
|
|
return ListSymbols(SelectedFile);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 添加符号
|
|
|
/// </summary>
|
|
|
/// <param name="symbol"></param>
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查找符号
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private List<SymbolItemData> FindSymbol(string text)
|
|
|
{
|
|
|
List<SymbolItemData> result = new List<SymbolItemData>();
|
|
|
|
|
|
foreach (string group in ListAllGroups())
|
|
|
{
|
|
|
List<string> 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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 清除当前的符号
|
|
|
/// </summary>
|
|
|
private void ClearSymbols()
|
|
|
{
|
|
|
foreach (Image image in lstSymbolImage.Images)
|
|
|
{
|
|
|
image.Dispose();
|
|
|
}
|
|
|
|
|
|
arrItemsCache.Clear();
|
|
|
lstSymbolImage.Images.Clear();
|
|
|
lsvSymbol.VirtualListSize = arrItemsCache.Count;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查出所有符号组
|
|
|
/// </summary>
|
|
|
/// <returns>返回符号组列表</returns>
|
|
|
private List<string> ListAllGroups()
|
|
|
{
|
|
|
TreeNode rootNode = trvSymbol.Nodes[0];
|
|
|
return rootNode.Nodes.Cast<TreeNode>()
|
|
|
.Select(node => node.Tag.ToString())
|
|
|
.ToList();
|
|
|
}
|
|
|
|
|
|
private void RemoveGroup(string group)
|
|
|
{
|
|
|
GeoSigmaXY.LibraryRemoveGroup(group);
|
|
|
try
|
|
|
{
|
|
|
File.Delete(group);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private List<string> ListSymbols(string group)
|
|
|
{
|
|
|
// 获取符号名称列表的逻辑
|
|
|
string strNames = string.Empty;
|
|
|
|
|
|
if (group.Equals(CurrentFile))
|
|
|
{
|
|
|
// 当前文件时
|
|
|
DrawerGeo?.GetDrawerSymbolNames(ref strNames);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
GeoSigmaXY.GetLibrarySymbolNames(group, ref strNames);
|
|
|
}
|
|
|
|
|
|
List<string> symbols = strNames.Split(';')
|
|
|
.Where(name => !string.IsNullOrEmpty(name))
|
|
|
.OrderBy(name => name)
|
|
|
.ToList();
|
|
|
|
|
|
return symbols;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 构建同一组的符号
|
|
|
/// </summary>
|
|
|
/// <param name="group">符号组</param>
|
|
|
/// <param name="symbols"></param>
|
|
|
private void BuildSymbols(string group, List<string> symbols)
|
|
|
{
|
|
|
foreach (string symbol in symbols)
|
|
|
{
|
|
|
SymbolItemData item = new SymbolItemData()
|
|
|
{
|
|
|
Name = symbol,
|
|
|
Group = group,
|
|
|
};
|
|
|
AddSymbol(item);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void BuildSymbols(List<SymbolItemData> symbols)
|
|
|
{
|
|
|
foreach (SymbolItemData item in symbols)
|
|
|
{
|
|
|
AddSymbol(item);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 显示左侧选中的符号组
|
|
|
/// </summary>
|
|
|
private void ShowSelectedSymbolGroup()
|
|
|
{
|
|
|
TreeNode node = trvSymbol.SelectedNode;
|
|
|
|
|
|
OnSearchStatus = false;
|
|
|
|
|
|
string group = node.Tag?.ToString();
|
|
|
if (group == null)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
ClearSymbols();
|
|
|
List<string> 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)
|
|
|
{
|
|
|
// 获取当前选中的节点对应的文件名/组名
|
|
|
SelectedFile = e.Node.Text;
|
|
|
// 只有当选中“当前文件”时,才显示按钮
|
|
|
tsbtnRemoveSymbol.Visible = (SelectedFile == CurrentFile);
|
|
|
|
|
|
// 刷新右侧列表显示
|
|
|
ShowSelectedSymbolGroup();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 关闭前
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查找符号事件
|
|
|
/// </summary>
|
|
|
/// <param name="sender">查找按钮</param>
|
|
|
/// <param name="e">事件参数</param>
|
|
|
private void tsbtnFindSymbol_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
string strSearchName = txtSearchName.Text.Trim();
|
|
|
if (string.IsNullOrEmpty(strSearchName))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
// 设置查询状态标识
|
|
|
OnSearchStatus = true;
|
|
|
|
|
|
ClearSymbols();
|
|
|
List<SymbolItemData> 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();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 确定
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 取消
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 修改符号名称
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
private void tsbtnEdit_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
ListView.SelectedIndexCollection selItems = lsvSymbol.SelectedIndices;
|
|
|
|
|
|
if (selItems.Count > 0)
|
|
|
{
|
|
|
lsvSymbol.Items[selItems[0]].BeginEdit();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 修改符号名称
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 显示符号预览图大图,最右侧那块儿
|
|
|
/// </summary>
|
|
|
/// <param name="itemData">标识数据</param>
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 清空符号预览图大图
|
|
|
/// </summary>
|
|
|
private void ClearymbolDetials()
|
|
|
{
|
|
|
if (mainView != null)
|
|
|
{
|
|
|
mainView.Visible = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 选择符号
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
|
|
|
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)}";
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// updates the current symbol icon.
|
|
|
/// </summary>
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 添加符号
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 移除符号
|
|
|
/// </summary>
|
|
|
/// <param name="index">符号下标</param>
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 选中下一个符号
|
|
|
/// </summary>
|
|
|
/// <param name="index">被删除的 index 下标</param>
|
|
|
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();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 删除符号
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
private void tsbtnListRemove_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
// 获取所有选中项的索引
|
|
|
ListView.SelectedIndexCollection selIndices = lsvSymbol.SelectedIndices;
|
|
|
|
|
|
if (arrItemsCache == null || selIndices.Count == 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
string msg = selIndices.Count > 1 ? $"确定要删除选中的 {selIndices.Count} 个符号吗?" : "确定要删除选中符号吗?";
|
|
|
if (MessageBox.Show(msg, "删除确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 必须【从后往前】遍历索引进行删除,否则前面的项被移除后,后面的索引会改变
|
|
|
List<int> sortedIndices = selIndices.Cast<int>().OrderByDescending(i => i).ToList();
|
|
|
|
|
|
foreach (int index in sortedIndices)
|
|
|
{
|
|
|
// 调用你现有的移除逻辑
|
|
|
RemoveSymbol(index);
|
|
|
}
|
|
|
|
|
|
// 刷新选择状态
|
|
|
if (arrItemsCache.Count > 0)
|
|
|
{
|
|
|
// 尝试选中删除点附近的项
|
|
|
int nextIndex = Math.Min(sortedIndices.Last(), arrItemsCache.Count - 1);
|
|
|
SelectNextSymbol(nextIndex);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
DrawerEnable(false);
|
|
|
mainView.ClearGeo();
|
|
|
}
|
|
|
|
|
|
IsDirty = true;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 删除当前未使用的符号
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
private void tsbtnRemoveSymbol_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
// 只有选中“当前文件”才执行
|
|
|
if (SelectedFile != CurrentFile || DrawerGeo == null) return;
|
|
|
string strNames = string.Empty;
|
|
|
DrawerGeo.GetDrawerCurrentSymbolNames(ref strNames);
|
|
|
|
|
|
HashSet<string> validNames = new HashSet<string>(
|
|
|
strNames.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries),
|
|
|
StringComparer.OrdinalIgnoreCase
|
|
|
);
|
|
|
|
|
|
//找出所有需要删除的索引
|
|
|
List<int> deleteIndices = new List<int>();
|
|
|
for (int i = 0; i < arrItemsCache.Count; i++)
|
|
|
{
|
|
|
if (!validNames.Contains(arrItemsCache[i].Text))
|
|
|
{
|
|
|
deleteIndices.Add(i);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (deleteIndices.Count == 0) return;
|
|
|
string msg = $"检测到 {deleteIndices.Count} 个未使用的符号,确定要清理吗?";
|
|
|
if (MessageBox.Show(msg, "清理确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 从后往前遍历索引,调用你现有的 RemoveSymbol 进行同步删除
|
|
|
// 必须倒序,否则删掉前面的,后面的索引就乱了
|
|
|
for (int i = deleteIndices.Count - 1; i >= 0; i--)
|
|
|
{
|
|
|
int targetIndex = deleteIndices[i];
|
|
|
RemoveSymbol(targetIndex);
|
|
|
}
|
|
|
|
|
|
IsDirty = true;
|
|
|
if (arrItemsCache.Count > 0)
|
|
|
{
|
|
|
// 清除旧的选择,尝试选中第一项
|
|
|
lsvSymbol.SelectedIndices.Clear();
|
|
|
SelectSymbol(0);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
DrawerEnable(false);
|
|
|
mainView.ClearGeo();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
private void DrawerEnable(bool enable)
|
|
|
{
|
|
|
mainView.ToolDefault();
|
|
|
mainView.ToolstripElements.Enabled = enable;
|
|
|
mainView.ToolstripView.Enabled = enable;
|
|
|
//mainView.ToolAntiAlias(false);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 符号拷贝
|
|
|
/// </summary>
|
|
|
/// <param name="sender">拷贝按钮</param>
|
|
|
/// <param name="e">事件参数</param>
|
|
|
private void tsbtnSymbolCopy_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
List<string> lstXyData = new List<string>();
|
|
|
|
|
|
// 遍历所有选中的索引
|
|
|
foreach (int index in lsvSymbol.SelectedIndices)
|
|
|
{
|
|
|
// 虚拟模式下,直接操作数据源 arrItemsCache 性能更好
|
|
|
var item = arrItemsCache[index];
|
|
|
SymbolItemData itemData = (SymbolItemData)item.Tag;
|
|
|
|
|
|
if (itemData?.PtrXY != IntPtr.Zero)
|
|
|
{
|
|
|
string strXyData = GeoSigmaXY.WriteXy2DFD(itemData.PtrXY);
|
|
|
lstXyData.Add(strXyData);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (lstXyData.Count > 0)
|
|
|
{
|
|
|
Clipboard.Clear();
|
|
|
// 存入 List<string>
|
|
|
Clipboard.SetData(ClipboardFormatSymbol, lstXyData);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 粘贴事件
|
|
|
/// </summary>
|
|
|
/// <param name="sender">粘贴按钮</param>
|
|
|
/// <param name="e">事件参数</param>
|
|
|
private void tsbtnSymbolPaste_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
List<string> lstXyData = (List<string>)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<string> 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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 新建分组
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
private void tsbtnNewGroup_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
string newFilename = NewGroupName();
|
|
|
string strNewFile = Path.Combine(LibPath, newFilename);
|
|
|
File.Create(strNewFile).Close();
|
|
|
|
|
|
AddNewGroup(strNewFile);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 添加新符号库
|
|
|
/// </summary>
|
|
|
/// <param name="strNewFile">符号文件</param>
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 删除分组
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
private void tsbtnDeleteFile_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
var root = trvSymbol.Nodes[0];
|
|
|
List<TreeNode> lstCheckedNodes = root.Nodes.Cast<TreeNode>().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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从文件导入符号
|
|
|
/// </summary>
|
|
|
/// <param name="sender">事件按钮</param>
|
|
|
/// <param name="e">事件参数</param>
|
|
|
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();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 符号导出到文件
|
|
|
/// </summary>
|
|
|
/// <param name="sender">符号导出事件</param>
|
|
|
/// <param name="e">事件参数</param>
|
|
|
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<TreeNode> lstCheckedNodes = new List<TreeNode>();
|
|
|
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("导出成功!");
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 删除选中文件
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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
|
|
|
{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 重命名选中文件
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 鼠标点击,右键菜单
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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<ToolStripMenuItem>()
|
|
|
.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; }
|
|
|
}
|
|
|
}
|