using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Customization;
using System.Collections.Specialized;
using System.IO;
namespace CadPluginPlatform
{
/// <summary>
/// 操作Cuix的类
/// </summary>
/// todo:
/// 1. 只写一次,自动生成其他,初步是只写一次ribbon,然后自动根据ribbon生成菜单和工具条
/// 2. 根据cuix的内容生成侧边栏的数据
/// 3. 是否采用xml文件存储历史菜单数据
///
public static class Cuix
{
/// <summary>
/// 获取并打开主CUIX文件
/// </summary>
/// <param name="doc">AutoCAD文档对象</param>
/// <returns>返回主CUIX文件</returns>
public static CustomizationSection GetMainCustomizationSection(this Document doc)
{
//获得主Cuix文件所在的位置
string mainCuiFile = Application.GetSystemVariable("MENUNAME") + ".cuix";
//打开主Cuix文件
return new CustomizationSection(mainCuiFile);
}
/// <summary>
/// 创建局部Cuix文件
/// </summary>
/// <param name="doc">AutoCAD文档对象</param>
/// <param name="cuiFile">Cuix文件名</param>
/// <param name="menuGroupName">菜单组的名称</param>
/// <returns>返回创建的Cuix文件</returns>
public static CustomizationSection AddCuix(this Document doc, string cuiFile, string menuGroupName)
{
CustomizationSection cs;//声明Cuix文件对象
if (!File.Exists(cuiFile))//如果要创建的文件不存在
{
cs = new CustomizationSection
{
MenuGroupName = menuGroupName//指定菜单组名称
};//创建Cuix文件对象
cs.SaveAs(cuiFile);//保存Cuix文件
}
//如果已经存在指定的Cuix文件,则打开该文件
else cs = new CustomizationSection(cuiFile);
return cs;//返回Cuix文件对象
}
/// <summary>
/// 装载指定的局部Cuix文件
/// </summary>
/// <param name="cs">Cuix文件</param>
public static void LoadCuix(this CustomizationSection cs)
{
if (cs.IsModified) cs.Save();//如果Cuix文件被修改,则保存
//获取当前活动文档
Document doc = Application.DocumentManager.MdiActiveDocument;
//获取主Cuix文件
var maincui = doc.GetMainCustomizationSection();
//如果已存在局部Cuix文件,则先卸载
if (maincui.PartialCuiFiles.Contains(cs.CUIFileName))
{
Application.UnloadPartialMenu(cs.CUIFileName);
}
Application.LoadPartialMenu(cs.CUIFileName);
//Application.ReloadAllMenus();
}
/// <summary>
/// 添加菜单项所要执行的宏,宏id默认为ID_Marco_command
/// </summary>
/// <param name="source">Cuix文件</param>
/// <param name="command">宏的具体命令</param>
/// <param name="helpString">宏的状态栏提示信息</param>
/// <param name="imagePath">宏的图标</param>
/// <returns>返回创建的宏</returns>
public static MenuMacro AddMacro(this CustomizationSection source, string command, string helpString, string imagePath)
{
var commandMacro = "^C^C_" + command;
var commandId = "ID_Marco_" + command;
var macroName = "Name_" + command;
var labelId = "lbl" + command;
MenuGroup menuGroup = source.MenuGroup;//获取Cuix文件中的菜单组
//判断菜单组中是否已经定义与菜单组名相同的宏集合
MacroGroup mg = menuGroup.FindMacroGroup(menuGroup.Name);
if (mg == null)//如果宏集合没有定义,则创建一个与菜单组名相同的宏集合
mg = new MacroGroup(menuGroup.Name, menuGroup);
//如果已经宏已经被定义,则返回
foreach (MenuMacro macro in mg.MenuMacros)
if (macro.ElementID == commandId) return macro;
//在宏集合中创建一个命令宏
var menuMacro = mg.CreateMenuMacro(macroName,
commandMacro,
commandId,
helpString,
MacroType.Any,
imagePath,
imagePath,
labelId);
menuMacro.macro.CLICommand = command;
return menuMacro;//返回命令宏
}
/// <summary>
/// 添加下拉菜单,别名默认为空,id默认为ID_Menu_name
/// </summary>
/// <param name="menuGroup">包含菜单的菜单组</param>
/// <param name="name">菜单名</param>
/// <returns>返回下拉菜单对象</returns>
public static PopMenu AddPopMenu(this MenuGroup menuGroup, string name)
{
var tag = $"ID_Menu_{name}";
var alias = new StringCollection
{
"POP15",
tag
};
//如果菜单组中没有名称为name的下拉菜单
if (menuGroup.PopMenus.IsNameFree(name))
{
//为下拉菜单指定显示名称、别名、标识符和所属的菜单组
return new PopMenu(name, alias, tag, menuGroup);
}
return menuGroup.PopMenus.FindPopWithName(name);
//返回下拉菜单对象
}
/// <summary>
/// 为菜单添加菜单项
/// </summary>
/// <param name="parentMenu">菜单项所属的菜单</param>
/// <param name="index">菜单项的位置</param>
/// <param name="name">菜单项的显示名称</param>
/// <param name="macro">菜单项的命令宏</param>
/// <returns>返回添加的菜单项</returns>
public static PopMenuItem AddMenuItem(this PopMenu parentMenu, int index, string name, MenuMacro macro)
{
var id = $"ID_MenuItem_{name}";
//如果存在名为name的菜单项,则返回
foreach (var item in parentMenu.PopMenuItems)
{
if (item is PopMenuItem popMenuItem && popMenuItem.Name == name)
{
return null;
}
}
//定义一个菜单项对象,指定所属的菜单及位置
var newPmi = new PopMenuItem(parentMenu, index);
////如果name不为空,则指定菜单项的显示名为name,否则会使用命令宏的名称
if (name != null) newPmi.Name = name;
newPmi.MacroID = macro.ElementID;//菜单项的命令宏的ID
newPmi.ElementID = id;
return newPmi;//返回菜单项对象
}
/// <summary>
/// 为下拉菜单添加子菜单
/// </summary>
/// <param name="parentMenu">下拉菜单</param>
/// <param name="index">子菜单的位置</param>
/// <param name="name">子菜单的显示名称</param>
/// <param name="tag">子菜单的标识字符串</param>
/// <returns>返回添加的子菜单</returns>
public static PopMenu AddSubMenu(this PopMenu parentMenu, int index, string name)
{
var id = $"ID_SubMenu_{name}";
PopMenu pm = null;//声明子菜单对象(属于下拉菜单类)
//如果菜单组中没有名称为name的下拉菜单
if (parentMenu.CustomizationSection.MenuGroup.PopMenus.IsNameFree(name))
{
//为子菜单指定显示名称、标识符和所属的菜单组,别名设为null
pm = new PopMenu(name, null, id, parentMenu.CustomizationSection.MenuGroup);
//为子菜单指定其所属的菜单
_ = new PopMenuRef(pm, parentMenu, index);
}
pm = parentMenu.CustomizationSection.MenuGroup.PopMenus.FindPopWithName(name);
return pm;//返回子菜单对象
}
/// <summary>
/// 为菜单添加分隔条
/// </summary>
/// <param name="parentMenu">下拉菜单</param>
/// <param name="index">分隔条的位置</param>
/// <returns>返回添加的分隔条</returns>
public static PopMenuItem AddSeparator(this PopMenu parentMenu, int index)
{
//定义一个分隔条并返回
return new PopMenuItem(parentMenu, index);
}
#region toolbar
/// <summary>
/// 添加工具栏
/// </summary>
/// <param name="menuGroup">工具栏所属的菜单组</param>
/// <param name="name">工具栏的显示名称</param>
/// <returns>返回添加的工具栏</returns>
public static Toolbar AddToolbar(this MenuGroup menuGroup, string name)
{
Toolbar tb = null;//声明一个工具栏对象
//如果菜单组中没有名称为name的工具栏
if (menuGroup.Toolbars.IsNameFree(name))
{
//为工具栏指定显示名称和所属的菜单组
tb = new Toolbar(name, menuGroup)
{
//设置工具栏为浮动工具栏
ToolbarOrient = ToolbarOrient.floating,
//设置工具栏可见
ToolbarVisible = ToolbarVisible.show
};
}
return tb;//返回工具栏对象
}
/// <summary>
/// 向工具栏添加按钮
/// </summary>
/// <param name="parent">按钮所属的工具栏</param>
/// <param name="index">按钮在工具栏上的位置</param>
/// <param name="name">按钮的显示名称</param>
/// <param name="macroId">按钮的命令宏的Id</param>
/// <returns>返回工具栏按钮对象</returns>
public static ToolbarButton AddToolbarButton(this Toolbar parent, int index, string name, string macroId)
{
//创建一个工具栏按钮对象,指定其命令宏Id、显示名称、所属的工具栏和位置
ToolbarButton button = new ToolbarButton(macroId, name, parent, index);
return button;//返回工具栏按钮对象
}
/// <summary>
/// 向工具栏添加弹出式工具栏
/// </summary>
/// <param name="parent">工具栏所属的父工具栏</param>
/// <param name="index">弹出式工具栏在父工具栏上的位置</param>
/// <param name="toolbarRef">弹出式工具栏所引用的工具栏</param>
public static void AttachToolbarToFlyout(this Toolbar parent, int index, Toolbar toolbarRef)
{
//创建一个弹出式工具栏,指定其所属的工具栏和位置
_ = new ToolbarFlyout(parent, index)
{
//指定弹出式工具栏所引用的工具栏
ToolbarReference = toolbarRef.Name
};
//引用的工具栏初始状态不可见
toolbarRef.ToolbarVisible = ToolbarVisible.hide;
}
#endregion
#region ribbon
/// <summary>
/// 添加新标签页
/// </summary>
/// <param name="instance">cui文件对象</param>
/// <param name="name">标签页名字</param>
/// <param name="text">标签页名字</param>
/// <returns>ribbon 标签对象资源集合</returns>
public static RibbonTabSource AddTab(
this CustomizationSection instance, string name)
{
var ribbonRoot = instance.MenuGroup.RibbonRoot;
var id = $"ID_RibbonTabSource_{name}";
if (ribbonRoot.RibbonTabSources.Contains(id))
{
return ribbonRoot.RibbonTabSources[id];
}
var ribbonTabSource = new RibbonTabSource(ribbonRoot)
{
Name = name,
Text = name,
Id = id,
ElementID = id
};
ribbonRoot.RibbonTabSources.Add(ribbonTabSource);
return ribbonTabSource;
}
/// <summary>
/// 添加新面板
/// </summary>
/// <param name="instance">cui文件对象</param>
/// <param name="name">面板名字</param>
/// <returns>ribbon 面板对象资源集合</returns>
public static RibbonPanelSource AddPanel(
this RibbonTabSource instance, string name)
{
var ribbonRoot = instance.CustomizationSection.MenuGroup.RibbonRoot;
var panels = ribbonRoot.RibbonPanelSources;
var id = $"ID_RibbonPanelSource_{instance.ElementID.Split('_')[2]}_{name}";
if (ribbonRoot.RibbonPanelSources.Contains(id))
{
return ribbonRoot.RibbonPanelSources[id];
}
var ribbonPanelSource = new RibbonPanelSource(ribbonRoot)
{
Name = name,
Text = name,
Id = id,
ElementID = id
};
panels.Add(ribbonPanelSource);
var ribbonPanelSourceReference = new RibbonPanelSourceReference(instance)
{
PanelId = ribbonPanelSource.ElementID
};
instance.Items.Add(ribbonPanelSourceReference);
return ribbonPanelSource;
}
/// <summary>
/// 添加ribbon 行
/// </summary>
/// <param name="instance">ribbon 面板对象资源集合</param>
/// <returns>ribbon 行</returns>
public static RibbonRow AddRibbonRow(this RibbonPanelSource instance, string name)
{
var id = $"ID_PanelSource_{instance.ElementID.Split('_')[3]}_{name}";
if (instance.Items.Contains(id))
{
return instance.Items[id] as RibbonRow;
}
var row = new RibbonRow(instance)
{
ElementID = id,
Text = name
};
instance.Items.Add(row);
return row;
}
/// <summary>
/// 添加ribbon 行
/// </summary>
/// <param name="instance">ribbon 行面板</param>
/// <returns>ribbon 行</returns>
public static RibbonRow AddRibbonRow(this RibbonRowPanel instance, string name)
{
var id = $"ID_RowPanel_{instance.ElementID.Split('_')[3]}_{name}";
if (instance.Items.Contains(id))
{
return instance.Items[id] as RibbonRow;
}
var row = new RibbonRow(instance)
{
ElementID = id,
Text = name
};
instance.Items.Add(row);
return row;
}
/// <summary>
/// 添加行面板
/// </summary>
/// <param name="instance">ribbon 行</param>
/// <returns>行面板</returns>
public static RibbonRowPanel AddRowPanel(this RibbonRow instance, string name)
{
var id = $"ID_Row_{instance.ElementID.Split('_')[3]}_{name}";
if (instance.Items.Contains(id))
{
return instance.Items[id] as RibbonRowPanel;
}
var row = new RibbonRowPanel(instance)
{
ElementID = id,
Text = name
};
instance.Items.Add(row);
return row;
}
/// <summary>
/// 添加命令按钮
/// </summary>
/// <param name="instanse">ribbon 行</param>
/// <param name="text">按钮名</param>
/// <param name="macro">命令宏</param>
/// <param name="style">按钮风格</param>
/// <returns></returns>
public static RibbonCommandButton AddButton(this RibbonRow instance, string text, MenuMacro macro, RibbonButtonStyle style)
{
var id = $"ID_RowButton_{instance.ElementID.Split('_')[3]}_{text}";
if (instance.Items.Contains(id))
{
return instance.Items[id] as RibbonCommandButton;
}
var button = new RibbonCommandButton(instance)
{
Text = text,
MacroID = macro.ElementID,
ButtonStyle = style,
ElementID = id
};
instance.Items.Add(button);
return button;
}
/// <summary>
/// 添加命令按钮
/// </summary>
/// <param name="instanse">下拉按钮</param>
/// <param name="text">按钮名</param>
/// <param name="macro">命令宏</param>
/// <param name="style">按钮风格</param>
/// <returns></returns>
public static RibbonCommandButton AddButton(this RibbonSplitButton instance, string text, MenuMacro macro, RibbonButtonStyle style)
{
var id = $"ID_SplitButton_{instance.ElementID.Split('_')[3]}_{text}";
if (instance.Items.Contains(id))
{
return instance.Items[id] as RibbonCommandButton;
}
var button = new RibbonCommandButton(instance)
{
Text = text,
MacroID = macro.ElementID,
ButtonStyle = style,
ElementID = id
};
instance.Items.Add(button);
return button;
}
/// <summary>
/// 添加新的下拉按钮
/// </summary>
/// <param name="instance">ribbon 行</param>
/// <param name="text">下拉按钮名</param>
/// <param name="behavior">按钮行为</param>
/// <param name="listStyle">按钮列表风格</param>
/// <param name="style">按钮风格</param>
/// <returns></returns>
public static RibbonSplitButton AddSplitButton(
this RibbonRow instance,
string text,
RibbonSplitButtonBehavior behavior,
RibbonSplitButtonListStyle listStyle,
RibbonButtonStyle style)
{
var id = $"ID_Split_{instance.ElementID.Split('_')[3]}_{text}";
if (instance.Items.Contains(id))
{
return instance.Items[id] as RibbonSplitButton;
}
var button = new RibbonSplitButton(instance)
{
Text = text,
Behavior = behavior,
ListStyle = listStyle,
ButtonStyle = style,
ElementID = id
};
instance.Items.Add(button);
return button;
}
/// <summary>
/// 添加分隔符
/// </summary>
/// <param name="instance">ribbon 行</param>
/// <param name="style">分隔符风格</param>
/// <returns></returns>
public static RibbonSeparator AddRibbonSeparator(
this RibbonRow instance,
RibbonSeparatorStyle style = RibbonSeparatorStyle.Line)
{
var separator = new RibbonSeparator(instance);
separator.SeparatorStyle = style;
instance.Items.Add(separator);
return separator;
}
/// <summary>
/// 添加分隔符
/// </summary>
/// <param name="instance">下拉按钮</param>
/// <param name="style">分隔符风格</param>
/// <returns></returns>
public static RibbonSeparator AddRibbonSeparator(
this RibbonSplitButton instance,
RibbonSeparatorStyle style = RibbonSeparatorStyle.Line)
{
var separator = new RibbonSeparator(instance);
separator.SeparatorStyle = style;
instance.Items.Add(separator);
return separator;
}
#endregion ribbon
}
}