using log4net;
using PdmSwPlugin.Commmon.Util.UI;
using PdmSwPlugin.Common.Util;
using PdmSwPlugin.Common.Util.Http;
using PdmSwPlugin.PropertySetting.Interface;
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using PdmSwPlugin.Common.Interface;
using PdmSwPlugin.Common;
using PdmSwPlugin.PropertySetting.Entity;
using PdmSwPlugin.PropertySetting.Panel;
using System.Windows.Threading;
using PdmSwPlugin.Common.Setting;
using System.IO;
using System.Runtime.InteropServices;
namespace PdmSwPlugin.PropertySetting
{
///
/// CommonSettingControl.xaml 的交互逻辑
///
[PdmSwPlugin(Title = "属性设置")]
public partial class SettingControl : UserControl, ISwAppSetter, INotifyPropertyChanged
, IActiveDocChangeHandler, ITabControlSelectionChangeHandler
{
private static ILog Logger = LogManager.GetLogger("PropertySetting");
#region 不能公用的东西,真有你的啊C#
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public void RaiseAndSetIfChanged(ref T old, T @new, [CallerMemberName] string propertyName = null)
{
old = @new;
if (propertyName != null)
{
RaisePropertyChanged(propertyName);
}
}
#endregion
public readonly Dictionary controlCache = new Dictionary();
#region 属性
public SldWorks SwApp { get; private set; }
///
/// 激活的文档
///
public ModelDoc2 activeDoc { set; get; }
///
/// 上次读取的文档
///
public ModelDoc2 LastReadDoc { get; set; }
///
/// 当前读取的文档
///
public ModelDoc2 ReadDoc { get; set; }
///
/// 当前读取的组件
///
public Component2 ReadComponent { get; set; }
private HttpClient Client { get; set; }
Dictionary settings;
#endregion
#region UI绑定
private string _readDocPath;
public string ReadDocPath
{
get => _readDocPath;
set => RaiseAndSetIfChanged(ref _readDocPath, value);
}
#endregion
private HttpClientCreator clientCreator { get; set; }
private UserControl ActiveOpter { get; set; }
public SettingControl()
{
clientCreator = new HttpClientCreator(new HttpConfig(PluginSetting.Instance.BaseAddress));
InitializeComponent();
DataContext = this;
}
public SettingControl(SldWorks SwApp) : this()
{
this.SwApp = SwApp;
}
public void InitPropertyData()
{
if (Client == null)
{
Client = clientCreator.GetClient();
}
DefaultPanel defaultPanel = new DefaultPanel();
controlCache.Add("default", defaultPanel);
JgjPartPanel jgjPart = new JgjPartPanel();
controlCache.Add("jgjPart", jgjPart);
JgjModulePanel jgjModule = new JgjModulePanel();
controlCache.Add("jgjModule", jgjModule);
var stPart = new StandardPartPanel();
controlCache.Add("standardPart", stPart);
var stModule = new StandardModulePanel();
controlCache.Add("standardModule", stModule);
LoadComboxItemSource();
Refresh_Click(null, null);
}
private void Jgj_SinglePropertyChanged(object sender, string name, object value)
{
// CustomPropertyUtil.SetCustomProperties(ReadDoc, name, (string)value);
}
///
/// 从服务器加载各种选项
///
private void LoadComboxItemSource()
{
try
{
Result> res = Client.GetSyncAction>("design/rule/openApi/test");
Dictionary datas = res.HandleResult();
settings = datas;
foreach (var key in controlCache.Keys)
{
(controlCache[key] as IPropertyOpt).SetSettings(settings);
}
}
catch (Exception ex)
{
Logger.Error("Request Jgj properties failed.", ex);
this.Error($"请求加工件属性失败!{ex.Message}");
}
}
private void UpdateActiveDoc()
{
if (activeDoc != null)
{
DetachDocNotify(activeDoc);
}
activeDoc = SwApp.ActiveDoc;
if (activeDoc != null)
{
AttachDocNotify(activeDoc);
int docType = activeDoc.GetType();
if (docType == (int)swDocumentTypes_e.swDocASSEMBLY)
{
activeDoc.ClearSelection2(true);
}
}
UpdateUI(activeDoc);
}
///
/// 附加一些插件范围内的事件
///
///
private void AttachDocNotify(ModelDoc2 doc)
{
int docType = doc.GetType();
if (docType == (int)swDocumentTypes_e.swDocASSEMBLY)
{
AssemblyDoc ass = doc as AssemblyDoc;
ass.UserSelectionPostNotify += Ass_UserSelectionPostNotify;
ass.DestroyNotify2 += ActiveDocDestroyNotify2;
}
else if (docType == (int)swDocumentTypes_e.swDocPART)
{
PartDoc part = doc as PartDoc;
part.DestroyNotify2 += ActiveDocDestroyNotify2;
}
else if (docType == (int)swDocumentTypes_e.swDocDRAWING)
{
DrawingDoc draw = doc as DrawingDoc;
draw.DestroyNotify2 += ActiveDocDestroyNotify2;
}
}
///
/// 移除插件范围内的一些事件
///
///
private void DetachDocNotify(ModelDoc2 doc)
{
try
{
int docType = doc.GetType();
if (docType == (int)swDocumentTypes_e.swDocASSEMBLY)
{
AssemblyDoc ass = doc as AssemblyDoc;
ass.UserSelectionPostNotify -= Ass_UserSelectionPostNotify;
ass.DestroyNotify2 -= ActiveDocDestroyNotify2;
}
else if (docType == (int)swDocumentTypes_e.swDocPART)
{
PartDoc part = doc as PartDoc;
part.DestroyNotify2 -= ActiveDocDestroyNotify2;
}
else if (docType == (int)swDocumentTypes_e.swDocDRAWING)
{
DrawingDoc draw = doc as DrawingDoc;
draw.DestroyNotify2 -= ActiveDocDestroyNotify2;
}
}
catch (COMException e)
{
// 如果sw把不是装配体/零件体/工程图的文档关了,有时会报这个问题,留个日志不报错了
Logger.Warn("COMObject detach event failed.", e);
activeDoc = null;
}
}
private int ActiveDocDestroyNotify2(int DestroyType)
{
if (activeDoc == null)
{
return 0;
}
DetachDocNotify(activeDoc);
activeDoc = null;
ReadComponent = null;
UpdateUI(null);
return 0;
}
public void UpdateUI(ModelDoc2 doc)
{
AlertSaveWindow();
LastReadDoc = ReadDoc;
ReadDoc = doc;
Dispatcher.Invoke(() =>
{
SwitchVisiable();
// LoadDocProperties();
});
}
///
/// 判断是否需要弹窗提示保存
///
public void AlertSaveWindow()
{
IPropertyOpt opt = ActiveOpter as IPropertyOpt;
if (opt != null && opt.GetDocChanged())
{
// 历史文档直接重置
string fullName = Path.GetFileName(ReadDocPath);
if (NameUtil.IsHistoryDoc(fullName))
{
opt.ResetProperty(out string errMsg);
return;
}
string Message = $"{fullName}属性发生变更,是否保存?";
if (SwApp.SendMsgToUser2(Message, (int)swMessageBoxIcon_e.swMbWarning
, (int)swMessageBoxBtn_e.swMbYesNo) == (int)swMessageBoxResult_e.swMbHitYes)
{
SaveDoc(true);
}
else
{
opt.ResetProperty(out string errMsg);
}
}
}
private int Ass_UserSelectionPostNotify()
{
var swSelMgr = (SelectionMgr)activeDoc.SelectionManager;
var i = swSelMgr.GetSelectedObjectCount2(-1);
if (i > 0)
{
try
{
Component2 component = swSelMgr.GetSelectedObjectsComponent4(1, -1);
ModelDoc2 doc = activeDoc;
ReadComponent = null;
if (component != null)
{
doc = component.IGetModelDoc();
ReadComponent = component;
}
UpdateUI(doc);
}
catch (Exception ex)
{
Logger.Error("Ass Change Component Error.", ex);
this.Error($"刷新属性失败!{ex.Message}");
}
}
return 1;
}
///
/// 根据激活的文档类型,变更属性可视
///
private void SwitchVisiable()
{
HashSet skipName = new HashSet {
NameConstant.materialCode
};
IPropertyOpt last = ActiveOpter as IPropertyOpt;
string contentKey = "default";
int? docType = ReadDoc?.GetType();
UserControl control;
IPropertyOpt newOne;
Dictionary properties;
if (docType == (int)swDocumentTypes_e.swDocDRAWING)
{
ReadDocPath = ReadDoc.GetPathName();
contentKey = "default";
control = controlCache[contentKey];
newOne = control as IPropertyOpt;
newOne.SetProperties(null, "当前不支持工程图", true, out _);
}
else if (docType == (int)swDocumentTypes_e.swDocPART)
{
ReadDocPath = ReadDoc.GetPathName();
properties = CustomPropertyUtil.GetCustomProperties2(ReadDoc, true, null, skipName);
string fileType = properties.Get(NameConstant.docType);
/*if (fileType == "加工件" || fileType == "模组")
{
contentKey = "jgjPart";
}*/
if (BomIniterHolder.Instance.IsJgj(ReadDoc))
{
contentKey = "jgjPart";
}
else
{
contentKey = "standardPart";
}
control = controlCache[contentKey];
newOne = control as IPropertyOpt;
newOne.SetProperties(ReadDoc, properties, true, out _);
}
else if (docType == (int)swDocumentTypes_e.swDocASSEMBLY)
{
ReadDocPath = ReadDoc.GetPathName();
if (ReadDoc.IsOpenedViewOnly())
{
contentKey = "default";
control = controlCache[contentKey];
newOne = control as IPropertyOpt;
newOne.SetProperties(null, "当前处于只读模式", true, out _);
}
else if (ReadDoc.IsOpenedReadOnly())
{
contentKey = "default";
control = controlCache[contentKey];
newOne = control as IPropertyOpt;
newOne.SetProperties(null, "当前处于只读模式", true, out _);
}
else
{
// !Equals(LastReadDoc, ReadDoc)
properties = CustomPropertyUtil.GetCustomProperties2(ReadDoc, true, null, skipName);
string fileType = properties.Get(NameConstant.docType);
/*if (fileType == "加工件" || fileType == "模组")
{
contentKey = "jgjPart";
}*/
if (BomIniterHolder.Instance.IsJgj(ReadDoc))
{
contentKey = "jgjModule";
}
else
{
contentKey = "standardModule";
}
control = controlCache[contentKey];
newOne = control as IPropertyOpt;
newOne.SetProperties(ReadDoc, properties, true, out _);
}
}
else
{
contentKey = "default";
control = controlCache[contentKey];
newOne = control as IPropertyOpt;
string PathName = ReadComponent?.GetPathName();
if (PathName == null)
{
ReadDocPath = "";
newOne.SetProperties(ReadDoc, "请打开一个文档", true, out _);
}
else
{
ReadDocPath = PathName;
string name = Path.GetFileNameWithoutExtension(PathName);
newOne.SetProperties(ReadDoc, $"【{name}】未找到文档,请检查是否被压缩或轻量化", true, out _);
}
}
if (last != null)
{
last.UpdateProperty -= Jgj_SinglePropertyChanged;
last = null;
}
ActiveOpter = control;
contentPanel.Children.Clear();
newOne.UpdateProperty += Jgj_SinglePropertyChanged;
contentPanel.Children.Add(control);
}
///
/// 根据激活的文档类型,变更属性可视
///
private void SwitchVisiable2()
{
HashSet skipName = new HashSet {
NameConstant.materialCode
};
IPropertyOpt last = ActiveOpter as IPropertyOpt;
string contentKey = "default";
int? docType = ReadDoc?.GetType();
UserControl control;
IPropertyOpt newOne;
Dictionary properties;
if (docType == (int)swDocumentTypes_e.swDocDRAWING)
{
ReadDocPath = ReadDoc.GetPathName();
control = new DefaultPanel();
newOne = control as IPropertyOpt;
newOne.SetSettings(settings);
newOne.SetProperties(null, "当前不支持工程图", true, out _);
}
else if (docType == (int)swDocumentTypes_e.swDocPART)
{
ReadDocPath = ReadDoc.GetPathName();
properties = CustomPropertyUtil.GetCustomProperties2(ReadDoc, true, null, skipName);
string fileType = properties.Get(NameConstant.docType);
/*if (fileType == "加工件" || fileType == "模组")
{
contentKey = "jgjPart";
}*/
if (BomIniterHolder.Instance.IsJgj(ReadDoc))
{
control = new JgjPartPanel();
}
else
{
control = new StandardPartPanel();
}
newOne = control as IPropertyOpt;
newOne.SetSettings(settings);
newOne.SetProperties(ReadDoc, properties, true, out _);
}
else if (docType == (int)swDocumentTypes_e.swDocASSEMBLY)
{
ReadDocPath = ReadDoc.GetPathName();
// !Equals(LastReadDoc, ReadDoc)
properties = CustomPropertyUtil.GetCustomProperties2(ReadDoc, true, null, skipName);
string fileType = properties.Get(NameConstant.docType);
/*if (fileType == "加工件" || fileType == "模组")
{
contentKey = "jgjPart";
}*/
if (BomIniterHolder.Instance.IsJgj(ReadDoc))
{
control = new JgjModulePanel();
}
else
{
control = new StandardModulePanel();
}
newOne = control as IPropertyOpt;
newOne.SetSettings(settings);
newOne.SetProperties(ReadDoc, properties, true, out _);
}
else
{
control = new DefaultPanel();
newOne = control as IPropertyOpt;
string PathName = ReadComponent?.GetPathName();
if (PathName == null)
{
ReadDocPath = "";
newOne.SetSettings(settings);
newOne.SetProperties(ReadDoc, "请打开一个文档", true, out _);
}
else
{
ReadDocPath = PathName;
string name = Path.GetFileNameWithoutExtension(PathName);
newOne.SetSettings(settings);
newOne.SetProperties(ReadDoc, $"【{name}】未找到文档,请检查是否被压缩或轻量化", true, out _);
}
}
if (last != null)
{
last.UpdateProperty -= Jgj_SinglePropertyChanged;
last = null;
}
ActiveOpter = control;
contentPanel.Children.Clear();
newOne.UpdateProperty += Jgj_SinglePropertyChanged;
contentPanel.Children.Add(control);
}
///
/// 从激活的文档中读取参数
///
private void LoadDocProperties()
{
IPropertyOpt opt = ActiveOpter as IPropertyOpt;
string ErrMsg = null;
if (ReadDoc == null)
{
string PathName = ReadComponent?.GetPathName();
if (PathName == null)
{
ReadDocPath = "";
opt.SetProperties(ReadDoc, "请打开一个文档", true, out ErrMsg);
return;
}
ReadDocPath = PathName;
string name = Path.GetFileNameWithoutExtension(PathName);
opt.SetProperties(ReadDoc, $"【{name}】未找到文档,请检查是否被压缩或轻量化", true, out ErrMsg);
return;
}
int docType = ReadDoc.GetType();
ReadDocPath = ReadDoc.GetPathName();
if (docType == (int)swDocumentTypes_e.swDocDRAWING)
{
opt.SetProperties(null, "当前不支持工程图", true, out ErrMsg);
return;
}
HashSet skipName = new HashSet {
NameConstant.materialCode
};
Dictionary properties = CustomPropertyUtil.GetCustomProperties2(ReadDoc, true, null, skipName);
opt.SetProperties(ReadDoc, properties, !Equals(LastReadDoc, ReadDoc), out ErrMsg);
}
private void ClearDocProperties()
{
IPropertyOpt opt = ActiveOpter as IPropertyOpt;
opt.ClearAllProperties(out string ErrMsg);
}
///
/// 将属性设置进文档,注意,并没有保存
///
/// 文档
private void SetDocProperty(ModelDoc2 doc, Dictionary props)
{
CustomPropertyUtil.SetCustomProperties(doc, props);
}
public void SetSwApp(SldWorks SwApp)
{
this.SwApp = SwApp;
}
private void SaveDoc(bool qiaoqiaode)
{
int errors = 0, warnings = 0;
if ((ActiveOpter as IPropertyOpt).SaveDoc(ref errors, ref warnings))
{
// if (!qiaoqiaode) this.Info("保存成功");
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
if (ReadDoc == null)
{
return;
}
SaveDoc(false);
}
public void RefreshData()
{
MaskAdorner.ShowMask(content, "属性加载中,请稍候...");
Task.Run(() =>
{
try
{
UpdateActiveDoc();
}
catch (COMException come)
{
// 频繁关闭会抛出这个异常,不管了
Logger.Warn("Read property COMObject failed.", come);
}
catch (Exception ex)
{
Logger.Error($"读取参数异常,文件:[{ReadDocPath}]!", ex);
this.Error($"读取参数异常:{ex.Message}");
}
finally
{
MaskAdorner.HideMask(content);
}
});
}
private void Refresh_Click(object sender, RoutedEventArgs e)
{
RefreshData();
}
private void LoadComboBox_Click(object sender, RoutedEventArgs e)
{
MaskAdorner.ShowMask(content, "加载MES设置,请稍候...");
Task.Run(() =>
{
try
{
LoadComboxItemSource();
}
finally
{
MaskAdorner.HideMask(content);
}
});
}
private void PropertySettingControl_Initialized(object sender, EventArgs e)
{
InitPropertyData();
}
///
/// 激活的文档变更触发
///
///
///
///
public void OnSwActiveDocChange(ModelDoc2 lastDoc, ModelDoc2 doc, Component2 comp)
{
// CurrentChanged();
RefreshData();
}
public void OnSwActiveDocSaved(ModelDoc2 doc, Component2 comp)
{
// 读取文件,设置参数
// LoadDocProperties();
}
public void OnCustomPropertyChange(string propName, string Configuration, string oldValue, string NewValue, int valueType)
{
if (oldValue == NewValue)
{
return;
}
IPropertyOpt opt = ActiveOpter as IPropertyOpt;
opt.UpdateSingleProperty(propName, NewValue);
}
public void OnDocDestroy(ModelDoc2 doc)
{
}
public void AfterDocDestroy()
{
}
public void OnTabControlSelectionChange(object sender, SelectionChangedEventArgs e)
{
if (e.RemovedItems == null)
{
return;
}
foreach (object obj in e.RemovedItems)
{
if (obj is TabItem item)
{
if (item.Content == this)
{
AlertSaveWindow();
break;
}
}
else
{
return;
}
}
}
public void DisabledHandler()
{
}
}
}