commit ef741673b23fd10bfb720a420326f1b934c12829 Author: liujb@connor.net.cn Date: Thu Feb 20 10:39:33 2025 +0800 first commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ce6fdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file diff --git a/EPLAN.EplAddin.KPlan.dll.config b/EPLAN.EplAddin.KPlan.dll.config new file mode 100644 index 0000000..7219447 --- /dev/null +++ b/EPLAN.EplAddin.KPlan.dll.config @@ -0,0 +1,171 @@ + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ESS_part001.ldb b/ESS_part001.ldb new file mode 100644 index 0000000..fc611c2 Binary files /dev/null and b/ESS_part001.ldb differ diff --git a/ESS_part001.mdb b/ESS_part001.mdb new file mode 100644 index 0000000..e5cb937 Binary files /dev/null and b/ESS_part001.mdb differ diff --git a/KPlan.sln b/KPlan.sln new file mode 100644 index 0000000..27644f8 --- /dev/null +++ b/KPlan.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KPlan", "KPlan\KPlan.csproj", "{A7F5F234-14A2-4AC1-A8FF-4535D68A3B40}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A7F5F234-14A2-4AC1-A8FF-4535D68A3B40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7F5F234-14A2-4AC1-A8FF-4535D68A3B40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7F5F234-14A2-4AC1-A8FF-4535D68A3B40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7F5F234-14A2-4AC1-A8FF-4535D68A3B40}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/KPlan/2606_Public.snk b/KPlan/2606_Public.snk new file mode 100644 index 0000000..0805940 Binary files /dev/null and b/KPlan/2606_Public.snk differ diff --git a/KPlan/Actions/CheckProjectAction.cs b/KPlan/Actions/CheckProjectAction.cs new file mode 100644 index 0000000..9b4e0a1 --- /dev/null +++ b/KPlan/Actions/CheckProjectAction.cs @@ -0,0 +1,155 @@ +using Eplan.EplApi.ApplicationFramework; +using Eplan.EplApi.Base; +using Eplan.EplApi.DataModel; +using Eplan.EplApi.HEServices; +using KPlan.RefActions; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using KPlan.Util; + +namespace KPlan.Actions { + class CheckProjectAction : Eplan.EplApi.ApplicationFramework.IEplAction { + private String projectCode = string.Empty; + private String PROJ_NAME = string.Empty; //Project's property which return Name of Project - project name only without path. + private String PROJ_FULL_NAME = string.Empty;//string : project's full name for example "C:\EPLANPROJECTSDEMO2_D" + + public bool Execute(ActionCallingContext ctx) { + if (!Util.TCUtil.CheckLogin()) { + return true; + } + + try { + SelectionSet selectionSet = new SelectionSet(); + Project currentProject = selectionSet.GetCurrentProject(false); + if (currentProject == null) { + MessageBox.Show("项目不存在!", "提示"); + return true; + } + projectCode = EplanUtil.GetPropValue(currentProject.Properties.PROJ_DRAWINGNUMBER); + if (projectCode == String.Empty) { + MessageBox.Show("项目编号不能为空!", "提示"); + return true; + } + string prjPath = currentProject.ProjectDirectoryPath; + // MessageBox.Show("prjPath--------------" + prjPath, "提示"); + DirectoryInfo di = new DirectoryInfo(prjPath); + prjPath = di.Parent.FullName; + //MessageBox.Show("prjPath2--------------" + prjPath, "提示"); + if (!prjPath.EndsWith("\\")) { + prjPath += "\\"; + } + // MessageBox.Show("prjPath3--------------" + prjPath, "提示"); + //项目打包并生成Xml + + + + if (ExportXml(currentProject, prjPath)) { + //MessageBox.Show("打包--------------" , "提示"); + CheckForm checkForm = new CheckForm(); + checkForm.projectCode = projectCode; + checkForm.currentProject = currentProject; + checkForm.xmlFilePath = prjPath + currentProject.ProjectName + ".xml"; + checkForm.ShowDialog(); + if (TCTool.deleteXML.Equals("TRUE", StringComparison.OrdinalIgnoreCase)) { + File.Delete(prjPath + currentProject.ProjectName + ".xml"); + } + } + } + catch (System.Exception ex) { + Util.KUtil.LogErr(ex); + MessageBox.Show("执行出错:" + ex.Message); + } + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "CheckProjectAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + + + + private bool ExportXml(Project currentProject, string exportPath) { + Progress progress = new Progress("SimpleProgress"); + try { + progress.SetTitle("检查项目..."); + progress.SetAllowCancel(true); + progress.BeginPart(100.0, ""); + //progress.ShowImmediately(); + PROJ_FULL_NAME = currentProject.ProjectFullName; + PROJ_NAME = currentProject.ProjectName; + string xmlFilePath = exportPath + PROJ_NAME + ".xml"; + KUtil.Log("导出Partlist:"+xmlFilePath); + PartsService ps = new PartsService(); + ps.ExportPartsList(currentProject, xmlFilePath, PartsService.Format.XML); + if (progress.Canceled()) { + progress.EndPart(true); + return false; + } + progress.EndPart(true); + } + catch(System.Exception ex) { + KUtil.LogErr(ex); + progress.EndPart(true); + MessageBox.Show("导出xml信息失败!"); + return false; + } + return true; + } + + private bool ExportXml_old(Project currentProject, string exportPath) { + //MessageBox.Show("开始导出xml信息!"); + bool result = true; + try { + PROJ_FULL_NAME = currentProject.ProjectFullName; + PROJ_NAME = currentProject.ProjectName; + string elkName = PROJ_FULL_NAME + ".elk"; + string xmlFilePath = exportPath + PROJ_NAME + ".xml"; + // MessageBox.Show("xmlFilePath------------------" + xmlFilePath); + ActionCallingContext context_temp = new ActionCallingContext(); + context_temp.AddParameter("TYPE", "EXPORT"); + context_temp.AddParameter("PROJECTNAME", elkName); + context_temp.AddParameter("EXPORTFILE", xmlFilePath); + //context_temp.AddParameter("FORMAT", "XPalXmlExporter"); + context_temp.AddParameter("MODE", "0"); + context_temp.AddParameter("ADDITIONAL_LANGUAGE", "1"); + + Progress progress = new Progress("SimpleProgress"); + progress.SetActionText("检查"); + progress.BeginPart(100.0, ""); + progress.ShowImmediately(); + progress.SetAllowCancel(true); + if (!progress.Canceled()) { + CommandLineInterpreter commandLineInterpreter = new CommandLineInterpreter(); + if (!Util.KUtil.FileIsUsed(xmlFilePath)) { + if (!commandLineInterpreter.Execute("partslist", context_temp)) { + MessageBox.Show("导出xml信息失败!"); + result = false; + progress.EndPart(true); + return result; + } + } + progress.EndPart(); + } + progress.EndPart(true); + } + catch (Exception ex) { + MessageBox.Show("Error:" + ex.Message); + result = false; + } + return result; + } + + } +} diff --git a/KPlan/Actions/ConfigureAction.cs b/KPlan/Actions/ConfigureAction.cs new file mode 100644 index 0000000..4cf242b --- /dev/null +++ b/KPlan/Actions/ConfigureAction.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Eplan.EplApi.ApplicationFramework; +using KPlan.Forms; + +namespace KPlan.Actions { + class ConfigureAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + if (!Util.TCUtil.CheckLogin()) { + return true; + } + new Configure().ShowDialog(); + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "ConfigureAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/CreateProjectAction.cs b/KPlan/Actions/CreateProjectAction.cs new file mode 100644 index 0000000..c3b36a8 --- /dev/null +++ b/KPlan/Actions/CreateProjectAction.cs @@ -0,0 +1,39 @@ +using Eplan.EplApi.ApplicationFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using KPlan.Forms; + +namespace KPlan.Actions { + class CreateProjectAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + CreateProject projDialog = new CreateProject(); + projDialog.ShowDialog(); + if (projDialog.create) { + try { + projDialog.DoCreateProject(); + } + catch (Exception ex) { + System.Windows.MessageBox.Show("创建项目出错:" + ex.Message); + Util.KUtil.LogErr(ex); + } + } + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "CreateProjectAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + + } +} diff --git a/KPlan/Actions/DownloadTCDataAction.cs b/KPlan/Actions/DownloadTCDataAction.cs new file mode 100644 index 0000000..2099b99 --- /dev/null +++ b/KPlan/Actions/DownloadTCDataAction.cs @@ -0,0 +1,222 @@ +using Eplan.EplApi.ApplicationFramework; +using KPlan.RefActions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using KPlan.Util; +using System.Windows.Forms; +using System.IO; +using Teamcenter.ClientX; +using Teamcenter.Soa.Client; +using Eplan.EplApi.Base; +using KPlan.Forms; +using System.ComponentModel; +using System.Threading; +using Teamcenter.Soa.Client.Model; + +namespace KPlan.Actions { + class DownloadTCDataAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + + public bool Execute(ActionCallingContext ctx) { + TCUtil.DO_NOTHING(); + if (!Util.TCUtil.CheckLogin()) { + return true; + } + Progress progress = new Progress("SimpleProgress"); + try { + loadEplanEnv(progress); + progress.EndPart(true); + } + catch (System.Exception ex) { + progress.EndPart(true); + KUtil.LogErr(ex); + MessageBox.Show("执行出错:" + ex.Message); + } + return true; + } + + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "DownloadTCDataAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + static private short loadEplanEnv(Progress progress) { + progress.SetTitle("下载TC数据"); + progress.SetAllowCancel(false); + progress.BeginPart(30.0, "查询数据"); + progress.ShowImmediately(); + progress.SetActionText("查询数据..."); + string loadEplanEnvTime = KUtil.GetConfigValue(KConfigure.REF_SECTION, KConfigure.REF_DATABASE_LAST_UPDATE_TIME); + bool load = false; + + string eplanDataFolderPath = KUtil.GetConfigValue(KConfigure.EPLAN_DATA_SECTION, KConfigure.EPLAN_DATA_FOLDER); + string dsUid = KUtil.GetConfigValue(KConfigure.EPLAN_DATA_SECTION, KConfigure.EPLAN_DATASET_UID); + if (KUtil.IsEmpty(dsUid)) { + throw new Exception("未配置TC数据集UID"); + } + if (!System.IO.Directory.Exists(eplanDataFolderPath)) { + throw new Exception("EPLAN数据文件夹不存在,请检查配置:" + eplanDataFolderPath); + } + KUtil.Log("准备下载EPLAN数据文件夹:" + eplanDataFolderPath); + ModelObject mo = TCUtil.StringToComponent(dsUid); + if (mo == null) { + throw new Exception("未查询到数据集 uid = " + dsUid + ",请检查配置"); + } + ModelObject[] mos = TCUtil.Refresh(mo); + TCUtil.GetProperties(false, mos, "object_string"); + string dsName = mo.GetPropertyDisplayableValue("object_string"); + KUtil.Log("找到数据集:" + dsName); + if (!TCUtil.IsType(mo.SoaType, "Zip")) { + throw new Exception("配置的数据集<" + dsName + ">不是Zip数据集,uid = " + dsUid); + } + Teamcenter.Soa.Client.Model.Strong.Dataset dataset_zip = mo as Teamcenter.Soa.Client.Model.Strong.Dataset; + if (dataset_zip == null) { + return 0; + } + /*string dbItemID = KUtil.GetConfigValue(KConfigure.REF_SECTION, KConfigure.REF_DATABSE_ITEMID); + Teamcenter.Soa.Client.Model.Strong.ItemRevision eplanEnvItemRevision = TCTool.getLastItemRev(dbItemID); + TCUtil.Refresh(eplanEnvItemRevision); + Teamcenter.Soa.Client.Model.Strong.Dataset dataset_zip = TCTool.getDataset(eplanEnvItemRevision, "Zip", "EPLAN_PARTS"); + if (dataset_zip != null) { + TCUtil.Refresh(dataset_zip); + if (0 != TCTool.checkZipDatasetCheckout(dataset_zip)) { + return 1; + } + //if (0 != TCTool.deleteDataset(projItemRevision, dataset_zw1)) + //{ + // return 2; + //} + } + else { + dataset_zip = TCTool.createDataset(eplanEnvItemRevision, "Zip", "EPLAN_PARTS"); + if (dataset_zip == null) { + return 3; + } + }*/ + String[] attributes2 = { "last_mod_date" }; + TCUtil.dmService.GetProperties(mos, attributes2); + string last_mod_date = dataset_zip.Last_mod_date.ToString("yyyyMMddHHmmss"); + KUtil.Log("数据修改时间:" + last_mod_date); + KUtil.Log("当前数据版本:" + loadEplanEnvTime); + if (string.IsNullOrEmpty(loadEplanEnvTime)) { + load = true; + } + if (!load) { + if (-1 == string.Compare(loadEplanEnvTime, last_mod_date)) { + load = true; + } + } + if (!load) { + MessageBox.Show("当前EPLAN部件库已经是最新的,无须更新!", "提示"); + return 0; + } + progress.EndPart(); + progress.BeginPart(30.0, "下载数据集"); + progress.SetActionText("下载数据集..."); + string fmsHome = Environment.GetEnvironmentVariable("FMS_HOME"); + string zipFile = fmsHome + "\\EPlan\\" + "EPLAN_PARTS.zip"; + try { + // Console.WriteLine("0-------------------------"); + List orgFileNames = new List(); + List orgFilePaths = new List(); + String cacheDir = KUtil.GetConfigValue(KConfigure.FMS_SECTION, KConfigure.FMS_PATH); + if (!Directory.Exists(cacheDir)) { + Directory.CreateDirectory(cacheDir); + } + String[] FMS_Bootstrap_Urls = new String[] { KUtil.GetConfigValue(KConfigure.FMS_SECTION, KConfigure.FMS_URL) }; + FileManagementUtility fMSFileManagement = new FileManagementUtility(Session.getConnection(), null, null, FMS_Bootstrap_Urls, cacheDir); + TCUtil.dmService.GetProperties(new Teamcenter.Soa.Client.Model.ModelObject[] { dataset_zip }, new string[] { "ref_list" }); + Teamcenter.Soa.Client.Model.ModelObject[] ref_list = dataset_zip.Ref_list; + //Console.WriteLine("1-------------------------"); + foreach (Teamcenter.Soa.Client.Model.ModelObject refobj in ref_list) { + Teamcenter.Soa.Client.Model.ModelObject[] ref_list1 = new Teamcenter.Soa.Client.Model.ModelObject[1]; + ref_list1[0] = refobj; + TCUtil.dmService.GetProperties(ref_list1, new string[] { "original_file_name" }); + string original_file_name = ref_list1[0].GetProperty("original_file_name").StringValue; + //Console.WriteLine("1.1-------------------------"); + Teamcenter.Soa.Client.GetFileResponse fileresp = fMSFileManagement.GetFiles(ref_list1); + //Console.WriteLine("1.2-------------------------"); + if (fileresp != null && fileresp.SizeOfFiles() > 0) { + FileInfo[] fis = fileresp.GetFiles(); + FileInfo fi = fis[0]; + orgFileNames.Add(original_file_name); + orgFilePaths.Add(fi.FullName); + break; + } + } + // Console.WriteLine("2-------------------------"); + fMSFileManagement.Term(); + // Console.WriteLine("2.1-------------------------"); + if (orgFilePaths.Count > 0) { + if (File.Exists(zipFile)) { + FileInfo fi = new FileInfo(zipFile); + if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) + fi.Attributes = FileAttributes.Normal; + File.Delete(zipFile); + } + System.IO.File.Copy(orgFilePaths[0], zipFile, true); + { + FileInfo fi = new FileInfo(zipFile); + if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) + fi.Attributes = FileAttributes.Normal; + } + //Console.WriteLine("3-------------------------"); + { + FileInfo fi = new FileInfo(orgFilePaths[0]); + if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) + fi.Attributes = FileAttributes.Normal; + File.Delete(orgFilePaths[0]); + } + //Console.WriteLine("4-------------------------"); + } + } + catch (SystemException e) { + progress.EndPart(true); + MessageBox.Show("下载EPLAN部件库失败:\r\n" + e.ToString(), "提示"); + return 11; + } + progress.EndPart(); + progress.BeginPart(40.0, "解压文件"); + progress.SetActionText("解压文件..."); + //Console.WriteLine("待解压的文件-------------------------" + zipFile); + if (File.Exists(zipFile)) { + // Console.WriteLine("解压目录-------------------------" + TCTool.DatabaseInfo["ELECPartLib"]); + //Console.WriteLine("测试解压-------------------------" ); + // if (!ZipHelper.UnZips(zipFile, TCTool.DatabaseInfo["ELECPartLib"])) + //string unzipPath = KUtil.GetConfigValue(KConfigure.REF_SECTION, KConfigure.REF_UNZIP_PATH); + KUtil.ReplaceZipContentName(zipFile); + if (!ZipHelper.UnZips(zipFile, eplanDataFolderPath)) { + progress.EndPart(true); + MessageBox.Show("解压缩EPLAN部件库失败!", "提示"); + return 21; + } + /* if (!ZipHelper.UnZips(zipFile, "D:\\AS2")) + { + MessageBox.Show("解压缩D:\\AS失败", "提示"); + return 21; + }*/ + /* if (!ZipHelper.UnZip(zipFile, TCTool.DatabaseInfo["ELECPartLibUnzip"])) + { + MessageBox.Show("解压缩EPLAN部件库失败!", "提示"); + return 21; + }*/ + } + KUtil.SetConfigValue(KConfigure.REF_SECTION, KConfigure.REF_DATABASE_LAST_UPDATE_TIME, last_mod_date); + progress.EndPart(true); + //iniFile.WriteString("databaseinfo", "更新时间", last_mod_date); + MessageBox.Show("下载EPLAN部件库完毕!", "提示"); + + return 0; + } + + } +} diff --git a/KPlan/Actions/KCheckProjectAction.cs b/KPlan/Actions/KCheckProjectAction.cs new file mode 100644 index 0000000..084dfb6 --- /dev/null +++ b/KPlan/Actions/KCheckProjectAction.cs @@ -0,0 +1,81 @@ +using System; +using System.IO; +using System.Windows; +using Eplan.EplApi.ApplicationFramework; +using Eplan.EplApi.DataModel; +using Eplan.EplApi.HEServices; +using KPlan.Util; +using Progress = Eplan.EplApi.Base.Progress; + +namespace KPlan.Actions { + class KCheckProjectAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + TCUtil.DO_NOTHING(); + if (!TCUtil.CheckLogin()) { + return true; + } + SelectionSet selectionSet = new SelectionSet(); + Project currentProject = selectionSet.GetCurrentProject(false); + if (currentProject == null) { + MessageBox.Show("没有选择项目"); + return true; + } + string projectCode = EplanUtil.GetPropValue(currentProject.Properties.PROJ_DRAWINGNUMBER); + if (KUtil.IsEmpty(projectCode)) { + MessageBox.Show("项目编号不可为空"); + return true; + } + string projPath = currentProject.ProjectDirectoryPath; + DirectoryInfo di = new DirectoryInfo(projPath); + projPath = di.Parent.FullName; + KUtil.Log("加载项目信息[" + currentProject.ProjectName + "]:" + projPath); + if (!projPath.EndsWith("\\")) { + projPath += "\\"; + } + string exportFile = projPath + currentProject.ProjectName + ".xml"; + Progress progress = new Progress("SimpleProgress"); + try { + ExportPartList(progress,currentProject,exportFile); + if (progress.Canceled()) { + progress.EndPart(true); + return true; + } + progress.EndPart(true); + if (!File.Exists(exportFile)) { + MessageBox.Show("导出Partlist异常,未找到导出文件"); + return true; + } + } + catch (System.Exception ex) { + progress.EndPart(true); + KUtil.LogErr(ex); + MessageBox.Show("执行出错:" + ex.Message); + } + new Forms.KCheckProject(currentProject,projPath,exportFile,projectCode).ShowDialog(); + string save = KUtil.GetConfigValue(KConfigure.CHECK_SECTION, KConfigure.CHECK_SAVEXML); + if (!"TRUE".Equals(save?.ToUpper())) { + File.Delete(exportFile); + } + return true; + } + + private void ExportPartList(Progress progress,Project currentProject, string exportFile) { + progress.SetTitle("导出检查数据..."); + progress.SetAllowCancel(true); + progress.BeginPart(100.0, ""); + EplanUtil.ExportPartList(currentProject, exportFile, PartsService.Format.XML); + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "KCheckProjectAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/KCheckProjectAction_Ex.cs b/KPlan/Actions/KCheckProjectAction_Ex.cs new file mode 100644 index 0000000..316f3f5 --- /dev/null +++ b/KPlan/Actions/KCheckProjectAction_Ex.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Windows; +using Eplan.EplApi.ApplicationFramework; +using Eplan.EplApi.DataModel; +using Eplan.EplApi.HEServices; +using KPlan.Util; +using Progress = Eplan.EplApi.Base.Progress; + +namespace KPlan.Actions { + class KCheckProjectAction_Ex : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + TCUtil.DO_NOTHING(); + if (!TCUtil.CheckLogin()) { + return true; + } + SelectionSet selectionSet = new SelectionSet(); + Project currentProject = selectionSet.GetCurrentProject(false); + if (currentProject == null) { + MessageBox.Show("没有选择项目"); + return true; + } + string projectCode = EplanUtil.GetPropValue(currentProject.Properties.PROJ_DRAWINGNUMBER); + if (KUtil.IsEmpty(projectCode)) { + MessageBox.Show("项目编号不可为空"); + return true; + } + string projPath = currentProject.ProjectDirectoryPath; + DirectoryInfo di = new DirectoryInfo(projPath); + projPath = di.Parent.FullName; + KUtil.Log("项目路径[" + currentProject.ProjectName + "]:" + projPath); + if (!projPath.EndsWith("\\")) { + projPath += "\\"; + } + string exportFile = projPath + currentProject.ProjectName + ".xml"; + KUtil.Log("导出路径[" + currentProject.ProjectName + "]:" + exportFile); + new Forms.KCheckProject_Ex(currentProject, projPath, exportFile, projectCode).Show();//.ShowDialog(); + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "KCheckProjectAction_Ex"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/KDownloadTCDataAction.cs b/KPlan/Actions/KDownloadTCDataAction.cs new file mode 100644 index 0000000..0045521 --- /dev/null +++ b/KPlan/Actions/KDownloadTCDataAction.cs @@ -0,0 +1,122 @@ +using Eplan.EplApi.ApplicationFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using KPlan.Forms; +using KPlan.Util; +using System.ComponentModel; +using System.Windows; +using Eplan.EplApi.Base; +using System.Threading; +using Teamcenter.Soa.Client.Model; +using System.IO; + +namespace KPlan.Actions { + class KDownloadTCDataAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + TCUtil.DO_NOTHING(); + if (!Util.TCUtil.CheckLogin()) { + return true; + } + Progress progress = new Progress("SimpleProgress"); + try { + Download(progress); + progress.EndPart(true); + } + catch(Exception ex) { + progress.EndPart(true); + KUtil.LogErr(ex); + MessageBox.Show("执行出错:" + ex.Message); + } + return true; + } + + + private void Download(Progress progress) { + progress.SetTitle("下载TC数据"); + progress.SetAllowCancel(false); + progress.BeginPart(30.0, "查询数据"); + progress.SetActionText("查询数据..."); + progress.ShowImmediately(); + string loadEplanEnvTime = KUtil.GetConfigValue(KConfigure.REF_SECTION, KConfigure.REF_DATABASE_LAST_UPDATE_TIME); + string eplanDataFolderPath = KUtil.GetConfigValue(KConfigure.EPLAN_DATA_SECTION, KConfigure.EPLAN_DATA_FOLDER); + string dsUid = KUtil.GetConfigValue(KConfigure.EPLAN_DATA_SECTION, KConfigure.EPLAN_DATASET_UID); + if (KUtil.IsEmpty(dsUid)) { + throw new Exception("未配置TC数据集UID"); + } + if (!System.IO.Directory.Exists(eplanDataFolderPath)) { + throw new Exception("EPLAN数据文件夹不存在,请检查配置:" + eplanDataFolderPath); + } + KUtil.Log("准备下载EPLAN数据文件夹:" + eplanDataFolderPath); + ModelObject mo = TCUtil.StringToComponent(dsUid); + if (mo == null) { + throw new Exception("未查询到Zip数据集 uid = " + dsUid + ",请检查配置"); + } + ModelObject[] mos = TCUtil.Refresh(mo); + TCUtil.GetProperties(false, mos, "object_string"); + string dsName = mo.GetPropertyDisplayableValue("object_string"); + KUtil.Log("找到数据集:" + dsName); + if (!TCUtil.IsType(mo.SoaType, "Zip")) { + throw new Exception("配置的数据集<" + dsName + ">不是Zip数据集,uid = " + dsUid); + } + Teamcenter.Soa.Client.Model.Strong.Dataset dataset_zip = mo as Teamcenter.Soa.Client.Model.Strong.Dataset; + if (dataset_zip == null) { + return; + } + TCUtil.GetProperties(false,mos, "last_mod_date"); + string last_mod_date = dataset_zip.Last_mod_date.ToString("yyyyMMddHHmmss"); + KUtil.Log("数据修改时间:" + last_mod_date); + KUtil.Log("当前数据版本:" + loadEplanEnvTime); + if (last_mod_date.Equals(loadEplanEnvTime)) { + MessageBox.Show("当前EPLAN部件库已经是最新的,无须更新!", "提示"); + return; + } + progress.EndPart(false); + + progress.BeginPart(30.0, "下载数据集"); + progress.SetActionText("下载数据集..."); + List zipFiles = TCUtil.GetDatasetFile(dataset_zip, ""); + int len = zipFiles == null ? 0 : zipFiles.Count; + if (len == 0) { + KUtil.Log("数据集<" + dsName + ">不存在文件引用"); + throw new Exception("缺少Eplan主数据,请确认是否已上传Eplan主数据"); + //throw new Exception("数据集<"+dsName+">不存在文件引用"); + } + if (len > 1) { + throw new Exception("数据集<" + dsName + ">存在多个文件引用:"+len); + } + FileInfo zipFile = TCUtil.GetFileInfo(zipFiles[0]); + if (zipFile == null || !File.Exists(zipFile.FullName)){ + throw new Exception("从数据集<" + dsName + ">下载文件失败"); + } + KUtil.Log("下载文件:"+zipFile.FullName); + progress.EndPart(false); + + progress.BeginPart(40.0, "解压文件"); + progress.SetActionText("解压文件..."); + KUtil.ReplaceZipContentName(zipFile.FullName); + KUtil.UnZipDirectory(zipFile.FullName, eplanDataFolderPath); + KUtil.SetConfigValue(KConfigure.REF_SECTION, KConfigure.REF_DATABASE_LAST_UPDATE_TIME, last_mod_date); + progress.EndPart(true); + if (!"TRUE".Equals(KUtil.GetConfigValue(KConfigure.EPLAN_DATA_SECTION, KConfigure.EPLAN_KEEP_ZIP)?.ToUpper())) { + zipFile.Delete(); + KUtil.Log("已清理临时文件"); + } + MessageBox.Show("下载EPLAN部件库完毕!", "提示"); + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "KDownloadTCDataAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/KPartSyncAction.cs b/KPlan/Actions/KPartSyncAction.cs new file mode 100644 index 0000000..0749b8c --- /dev/null +++ b/KPlan/Actions/KPartSyncAction.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Eplan.EplApi.ApplicationFramework; +using KPlan.Forms; + +namespace KPlan.Actions { + class KPartSyncAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + if (!Util.TCUtil.CheckLogin()) { + return true; + } + Eplan.EplApi.MasterData.MDPartsDatabase mdPartsDatabase = Util.EplanUtil.OpenDatabase(); + new KPartSync(mdPartsDatabase).ShowDialog(); + Util.EplanUtil.UpdateAndClose(mdPartsDatabase); + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "KPartSyncAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/LoginAction.cs b/KPlan/Actions/LoginAction.cs new file mode 100644 index 0000000..4c31be9 --- /dev/null +++ b/KPlan/Actions/LoginAction.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Eplan.EplApi.ApplicationFramework; +using KPlan.Util; +using KPlan.Forms; +using System.Windows; + + +namespace KPlan.Actions { + class LoginAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + new Login().ShowDialog(); + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "LoginAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/OpenFromTCAction.cs b/KPlan/Actions/OpenFromTCAction.cs new file mode 100644 index 0000000..b8706ed --- /dev/null +++ b/KPlan/Actions/OpenFromTCAction.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Eplan.EplApi.ApplicationFramework; +using KPlan.Forms; +using KPlan.Util; + +namespace KPlan.Actions { + class OpenFromTCAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + if (!TCUtil.CheckLogin()) { + return true; + } + new OpenFromTC().ShowDialog(); + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "OpenFromTCAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/PartSyncAction.cs b/KPlan/Actions/PartSyncAction.cs new file mode 100644 index 0000000..866a444 --- /dev/null +++ b/KPlan/Actions/PartSyncAction.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Eplan.EplApi.ApplicationFramework; +using KPlan.Forms; + +namespace KPlan.Actions { + class PartSyncAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + public bool Execute(ActionCallingContext ctx) { + if (!Util.TCUtil.CheckLogin()) { + return true; + } + Eplan.EplApi.MasterData.MDPartsDatabase mdPartsDatabase = Util.EplanUtil.OpenDatabase(); + new PartSync(mdPartsDatabase).ShowDialog(); + Util.EplanUtil.UpdateAndClose(mdPartsDatabase); + return true; + } + + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "PartSyncAction"; + Ordinal = 20; + return true; + } + + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + } +} diff --git a/KPlan/Actions/SaveProjectAction.cs b/KPlan/Actions/SaveProjectAction.cs new file mode 100644 index 0000000..1e36c4c --- /dev/null +++ b/KPlan/Actions/SaveProjectAction.cs @@ -0,0 +1,659 @@ +using Eplan.EplApi.ApplicationFramework; +using Eplan.EplApi.Base; +using Eplan.EplApi.DataModel; +using Eplan.EplApi.HEServices; +using KPlan.RefActions; +using KPlan.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml; + +namespace KPlan.Actions { + class SaveProjectAction : Eplan.EplApi.ApplicationFramework.IEplAction { + + private String projectCode = string.Empty; + private String PROJ_NAME = string.Empty; //Project's property which return Name of Project - project name only without path. + private String PROJ_FULL_NAME = string.Empty;//string : project's full name for example "C:\EPLANPROJECTSDEMO2_D" + + public bool Execute(ActionCallingContext ctx) { + if (!Util.TCUtil.CheckLogin()) { + return true; + } + try { + TCTool.ReadConfigs(); + + SelectionSet selectionSet = new SelectionSet(); + Project currentProject = selectionSet.GetCurrentProject(false); + if (currentProject == null) { + MessageBox.Show("项目不存在11!", "提示"); + return true; + } + projectCode = EplanUtil.GetProjectCode(currentProject); + if (projectCode == String.Empty) { + MessageBox.Show("项目编号不能为空!", "提示"); + return true; + } + string prjPath = currentProject.ProjectDirectoryPath; + DirectoryInfo di = new DirectoryInfo(prjPath); + prjPath = di.Parent.FullName; + if (!prjPath.EndsWith("\\")) { + prjPath += "\\"; + } + + Dictionary nameToPaths = new Dictionary(); + if (ZipProjectAndExport(currentProject, prjPath, nameToPaths)) { + KUtil.Log(prjPath); + SaveForm saveForm = new SaveForm(); + saveForm.projectCode = projectCode; + saveForm.currentProject = currentProject; + saveForm.xmlFilePath = prjPath + currentProject.ProjectName + ".xml"; + saveForm.nameToPaths = nameToPaths; + saveForm.ShowDialog(); + + if (TCTool.deleteXML.Equals("TRUE", StringComparison.OrdinalIgnoreCase)) { + File.Delete(prjPath + currentProject.ProjectName + ".xml"); + } + Dictionary.KeyCollection kc = nameToPaths.Keys; + foreach (string name in kc) { + File.Delete(nameToPaths[name]); + } + } + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show("执行出错:" + ex.Message); + } + return true; + } + public bool OnRegister(ref string Name, ref int Ordinal) { + Name = "SaveProjectAction"; + Ordinal = 20; + return true; + } + public void GetActionProperties(ref ActionProperties actionProperties) { + //actionProperties.Description = "Action test with parameters."; + } + + private bool ZipProjectAndExport(Project currentProject, string exportPath, Dictionary nameToPaths) { + bool result = true; + Progress progress = new Progress("SimpleProgress"); + try { + PROJ_FULL_NAME = currentProject.ProjectFullName; + PROJ_NAME = currentProject.ProjectName; + string elkName = PROJ_FULL_NAME + ".elk"; + string zipName = PROJ_NAME + ".zw1"; + string pdfName = exportPath + PROJ_NAME + ".pdf"; + string xmlFilePath = exportPath + PROJ_NAME + ".xml"; + KUtil.Log(xmlFilePath); + + progress.BeginPart(100.0, ""); + progress.ShowImmediately(); + progress.SetAllowCancel(true); + // MessageBox.Show("progress----------------1" ); + if (!progress.Canceled()) { + // MessageBox.Show("progress----------------2"); + File.Delete(zipName); + // MessageBox.Show("progress----------------3"); + if (File.Exists(zipName)) { + MessageBox.Show("项目不能备份1!"); + result = false; + progress.EndPart(true); + return result; + } + KUtil.Log("备份项目:"+elkName+" -> "+exportPath+"|"+zipName); + Backup backup = new Backup(); + backup.Project(elkName, "", exportPath, zipName, Backup.Type.MakeBackup, Backup.Medium.Disk, 0.0, Backup.Amount.All, false, true, true, false); + + nameToPaths.Add("ZW1", exportPath + zipName); + if (!KUtil.FileIsUsed(xmlFilePath)) { + File.Delete(xmlFilePath); + if (File.Exists(xmlFilePath)) { + MessageBox.Show("导出xml信息失败1!"); + result = false; + progress.EndPart(true); + return result; + } + PartsService ps = new PartsService(); + ps.ExportPartsList(currentProject, xmlFilePath, PartsService.Format.XML); + } + bool readResult = ReadXMLFile(xmlFilePath); + //MessageBox.Show("progress----------------8"); + if (readResult) { + //MessageBox.Show("progress----------------9"); + File.Delete(pdfName); + //MessageBox.Show("progress----------------10"); + if (File.Exists(pdfName)) { + MessageBox.Show("导出PDF失败1!"); + result = false; + progress.EndPart(true); + return result; + } + Export export = new Export(); + //MessageBox.Show("progress----------------11"); + export.PdfProject(currentProject, "", pdfName, Export.DegreeOfColor.BlackAndWhite, true, "", true); + // MessageBox.Show("progress----------------12"); + if (!File.Exists(pdfName)) { + MessageBox.Show("导出PDF失败2!"); + result = false; + progress.EndPart(true); + return result; + } + KUtil.Log(pdfName); + // MessageBox.Show("progress----------------13"); + if (!nameToPaths.ContainsKey(PROJ_NAME)) { + nameToPaths.Add(PROJ_NAME, pdfName); + } + // MessageBox.Show("progress----------------14"); + Page[] pages = currentProject.Pages; + int pageNum = pages.Length; + StringBuilder invalidCharSB = new StringBuilder(""); + for (int i = 0; i < pageNum; i++) { + string pageName = pages[i].Name; + if (!pageName.StartsWith("&")) { + string plant = ""; + if (!pages[i].Properties.DESIGNATION_PLANT.IsEmpty) { + plant = pages[i].Properties.get_DESIGNATION_FULLPLANT(0); + } + string plant_descr = ""; + if (!pages[i].Properties.DESIGNATION_PLANT_DESCR.IsEmpty) { + plant_descr = pages[i].Properties.DESIGNATION_PLANT_DESCR.ToString(EplanUtil.Language_CN); + } + string userDefiend = ""; + if (!pages[i].Properties.DESIGNATION_USERDEFINED.IsEmpty) { + userDefiend = pages[i].Properties.get_DESIGNATION_FULLUSERDEFINED(0); + } + string plantFullName = plant + " " + plant_descr; + if (plantFullName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) { + if (!invalidCharSB.ToString().Contains(plantFullName)) { + invalidCharSB.Append(plantFullName).Append(","); + } + continue; + } + //string pagePdfName = exportPath + plantFullName + ".pdf"; + ArrayList listPlant = new ArrayList(); + ArrayList listCnLocation = new ArrayList(); + ArrayList listCtLocation = new ArrayList(); + ArrayList listPreLocation = new ArrayList(); + StringBuilder cadPathSB = new StringBuilder(""); + //bool isDocument = false; + //if (!pages[i].Properties.PAGE_EXTDOCUMENT.IsEmpty) + //{ + // string docName = pages[i].Properties.PAGE_EXTDOCUMENT.ToString().Trim(); + // if (!docName.Equals("")) + // { + // isDocument = true; + // if (docName.EndsWith(".dwg")) + // { + // string cadPath = docName.Replace("$(DOC)", + // currentProject.ProjectDirectoryPath + + // "\\DOC"); + // if (File.Exists(cadPath)) + // { + // cadPathSB.Append(cadPath + ";"); + // } + // } + // } + //} + //if (!isDocument) + //{ + listPlant.Add(pages[i]); + //} + string location = ""; + string cnPdfName = ""; + string ctPdfName = ""; + if (!pages[i].Properties.DESIGNATION_LOCATION.IsEmpty) { + location = pages[i].Properties.DESIGNATION_LOCATION.ToString(); + if (location.Equals("CN")) { + string locationDescr = pages[i].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + listCnLocation.Add(pages[i]); + //cnPdfName = exportPath + plantFullName + "+" + location + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + else if (location.Equals("CT")) { + string locationDescr = pages[i].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + listCtLocation.Add(pages[i]); + //ctPdfName = exportPath + plantFullName + "+" + location + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + else { + listPreLocation.Add(pages[i]); + } + } + //export.DxfDwgPageToDisk(pages[i], "", exportPath, pages[i].Properties.PAGE_FULLNAME.ToString().Replace("/", "&")); + for (int j = (i + 1); j < pageNum; j++) { + string nextPageName = pages[j].Name; + + //bool isDocument2 = false; + //if (!pages[j].Properties.PAGE_EXTDOCUMENT.IsEmpty) + //{ + // string docName = pages[j].Properties.PAGE_EXTDOCUMENT.ToString().Trim(); + // if (!docName.Equals("")) + // { + // isDocument2 = true; + // if (docName.EndsWith(".dwg")) + // { + // string cadPath = docName.Replace("$(DOC)", currentProject.ProjectDirectoryPath + "\\DOC"); + // if (File.Exists(cadPath)) + // { + // cadPathSB.Append(cadPath + ";"); + // } + // } + // } + //} + string nextPlant = ""; + if (!pages[j].Properties.DESIGNATION_PLANT.IsEmpty) { + nextPlant = pages[j].Properties.get_DESIGNATION_FULLPLANT(0); + } + if (!nextPageName.StartsWith("&") && nextPlant.Equals(plant)) { + //export.DxfDwgPageToDisk(pages[j], "", exportPath, pages[j].Properties.PAGE_FULLNAME.ToString().Replace("/", "&")); + if (!pages[j].Properties.DESIGNATION_LOCATION.IsEmpty) { + string nextLocation = pages[j].Properties.DESIGNATION_LOCATION.ToString(); + if (nextLocation.Equals("CN")) { + listCnLocation.Add(pages[j]); + if (cnPdfName.Equals("")) { + string locationDescr = pages[j].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + //cnPdfName = exportPath + plantFullName + "+" + nextLocation + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + } + else if (nextLocation.Equals("CT")) { + listCtLocation.Add(pages[j]); + if (ctPdfName.Equals("")) { + string locationDescr = pages[j].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + //ctPdfName = exportPath + plantFullName + "+" + nextLocation + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + } + else { + listPreLocation.Add(pages[j]); + } + } + //if (!isDocument2) + //{ + listPlant.Add(pages[j]); + //} + i++; + } + else { + //export.DxfDwgPageToDisk(pages[j], "", exportPath, pages[j].Properties.PAGE_FULLNAME.ToString().Replace("/", "&")); + break; + } + } + StringBuilder pdfPathSB = new StringBuilder(""); + if (listCnLocation.Count > 0) { + File.Delete(cnPdfName); + //export.PdfPages(listCnLocation, "", cnPdfName, Export.DegreeOfColor.Color, true, "", true); + //pdfPathSB.Append(cnPdfName).Append(";"); + } + if (listCtLocation.Count > 0) { + File.Delete(cnPdfName); + //export.PdfPages(listCtLocation, "", ctPdfName, Export.DegreeOfColor.Color, true, "", true); + //pdfPathSB.Append(ctPdfName).Append(";"); + } + if (!nameToPaths.ContainsKey(plantFullName)) { + if (pdfPathSB.ToString().Equals("")) { + if (listPlant.Count > 0) { + //File.Delete(pagePdfName); + //export.PdfPages(listPlant, "", pagePdfName, Export.DegreeOfColor.Color, true, "", true); + } + //MessageBox.Show("plantFullName=" + plantFullName + ",pagePdfName=" + pagePdfName); + //nameToPaths.Add(plantFullName, pagePdfName); + } + else { + if (listPreLocation.Count > 0) { + //File.Delete(pagePdfName); + //export.PdfPages(listPlant, "", pagePdfName, Export.DegreeOfColor.Color, true, "", true); + //pdfPathSB.Append(pagePdfName).Append(";"); + } + //MessageBox.Show("plantFullName=" + plantFullName + ",pagePdfName=" + pdfPathSB.ToString()); + //nameToPaths.Add(plantFullName, pdfPathSB.ToString()); + } + } + } + } + if (!invalidCharSB.ToString().Equals("")) { + MessageBox.Show("高层" + invalidCharSB.ToString().Substring(0, invalidCharSB.ToString().Length - 1) + "含有非法字符,请修改后再保存!"); + result = false; + progress.EndPart(true); + return result; + } + if (!File.Exists(pdfName)) { + MessageBox.Show("导出PDF失败!"); + result = false; + progress.EndPart(true); + return result; + } + } + progress.EndPart(); + } + progress.EndPart(true); + } + catch (Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show("Error!!!" + ex.Message); + result = false; + progress.EndPart(true); + } + return result; + } + + private bool ZipProjectAndExport_old(Project currentProject, string exportPath, Dictionary nameToPaths) { + bool result = true; + try { + PROJ_FULL_NAME = currentProject.ProjectFullName; + PROJ_NAME = currentProject.ProjectName; + + string elkName = PROJ_FULL_NAME + ".elk"; + string zipName = PROJ_NAME + ".zw1"; + string pdfName = exportPath + PROJ_NAME + ".pdf"; + // MessageBox.Show("pdfName----------------" + pdfName); + ActionCallingContext actionCallingContext_zw1 = new ActionCallingContext(); + actionCallingContext_zw1.AddParameter("TYPE", "PROJECT"); + actionCallingContext_zw1.AddParameter("PROJECTNAME", elkName); + actionCallingContext_zw1.AddParameter("DESTINATIONPATH", exportPath); + actionCallingContext_zw1.AddParameter("ARCHIVENAME", zipName); + actionCallingContext_zw1.AddParameter("BACKUPMETHOD", "BACKUP"); + actionCallingContext_zw1.AddParameter("BACKUPMEDIA", "DISK"); + actionCallingContext_zw1.AddParameter("SPLITSIZE", "0.0"); + actionCallingContext_zw1.AddParameter("BACKUPAMOUNT", "BACKUPAMOUNT_ALL"); + actionCallingContext_zw1.AddParameter("COMPRESSPRJ", "0"); + actionCallingContext_zw1.AddParameter("INCLEXTDOCS", "1"); + actionCallingContext_zw1.AddParameter("INCLIMAGES", "1"); + // MessageBox.Show("pdfName1----------------" + pdfName); + //=============通过项目生成PART_LIST,导出PART_LIST的CSV文件====== + string partListPath = currentProject.ProjectDirectoryPath;//string : project's directory path for example "C:\EPLANPROJECTSDEMO2_D.EDB" + //================通过项目导出PART_LIST的XML文件 + + string xmlFilePath = exportPath + PROJ_NAME + ".xml"; + // MessageBox.Show("pdfName2----------------" + pdfName); + // MessageBox.Show("导出xml3"); + ActionCallingContext actionCallingContext_xml = new ActionCallingContext(); + actionCallingContext_xml.AddParameter("TYPE", "EXPORT"); + actionCallingContext_xml.AddParameter("PROJECTNAME", elkName); + actionCallingContext_xml.AddParameter("EXPORTFILE", xmlFilePath); + //context_temp.AddParameter("FORMAT", "XPalXmlExporter"); + actionCallingContext_xml.AddParameter("MODE", "0"); + actionCallingContext_xml.AddParameter("ADDITIONAL_LANGUAGE", "1"); + KUtil.Log(xmlFilePath); + Progress progress = new Progress("SimpleProgress"); + progress.BeginPart(100.0, ""); + progress.ShowImmediately(); + progress.SetAllowCancel(true); + // MessageBox.Show("progress----------------1" ); + if (!progress.Canceled()) { + // MessageBox.Show("progress----------------2"); + File.Delete(zipName); + // MessageBox.Show("progress----------------3"); + if (File.Exists(zipName)) { + MessageBox.Show("项目不能备份1!"); + result = false; + progress.EndPart(true); + return result; + } + CommandLineInterpreter commandLineInterpreter = new CommandLineInterpreter(); + if (!commandLineInterpreter.Execute("backup", actionCallingContext_zw1)) { + MessageBox.Show("项目不能备份2!"); + result = false; + progress.EndPart(true); + return result; + } + nameToPaths.Add("ZW1", exportPath + zipName); + if (!KUtil.FileIsUsed(xmlFilePath)) { + File.Delete(xmlFilePath); + if (File.Exists(xmlFilePath)) { + MessageBox.Show("导出xml信息失败1!"); + result = false; + progress.EndPart(true); + return result; + } + //MessageBox.Show("progress----------------4"); + if (!commandLineInterpreter.Execute("partslist", actionCallingContext_xml)) { + + MessageBox.Show("导出xml信息失败2!"); + result = false; + progress.EndPart(true); + return result; + } + // MessageBox.Show("progress----------------5"); + } + bool readResult = ReadXMLFile(xmlFilePath); + //MessageBox.Show("progress----------------8"); + if (readResult) { + //MessageBox.Show("progress----------------9"); + File.Delete(pdfName); + //MessageBox.Show("progress----------------10"); + if (File.Exists(pdfName)) { + MessageBox.Show("导出PDF失败1!"); + result = false; + progress.EndPart(true); + return result; + } + Export export = new Export(); + //MessageBox.Show("progress----------------11"); + export.PdfProject(currentProject, "", pdfName, Export.DegreeOfColor.BlackAndWhite, true, "", true); + // MessageBox.Show("progress----------------12"); + if (!File.Exists(pdfName)) { + MessageBox.Show("导出PDF失败2!"); + result = false; + progress.EndPart(true); + return result; + } + KUtil.Log(pdfName); + // MessageBox.Show("progress----------------13"); + if (!nameToPaths.ContainsKey(PROJ_NAME)) { + nameToPaths.Add(PROJ_NAME, pdfName); + } + // MessageBox.Show("progress----------------14"); + Page[] pages = currentProject.Pages; + int pageNum = pages.Length; + StringBuilder invalidCharSB = new StringBuilder(""); + for (int i = 0; i < pageNum; i++) { + string pageName = pages[i].Name; + if (!pageName.StartsWith("&")) { + string plant = ""; + if (!pages[i].Properties.DESIGNATION_PLANT.IsEmpty) { + plant = pages[i].Properties.get_DESIGNATION_FULLPLANT(0); + } + string plant_descr = ""; + if (!pages[i].Properties.DESIGNATION_PLANT_DESCR.IsEmpty) { + plant_descr = pages[i].Properties.DESIGNATION_PLANT_DESCR.ToString(EplanUtil.Language_CN); + } + string userDefiend = ""; + if (!pages[i].Properties.DESIGNATION_USERDEFINED.IsEmpty) { + userDefiend = pages[i].Properties.get_DESIGNATION_FULLUSERDEFINED(0); + } + string plantFullName = plant + " " + plant_descr; + if (plantFullName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) { + if (!invalidCharSB.ToString().Contains(plantFullName)) { + invalidCharSB.Append(plantFullName).Append(","); + } + continue; + } + //string pagePdfName = exportPath + plantFullName + ".pdf"; + ArrayList listPlant = new ArrayList(); + ArrayList listCnLocation = new ArrayList(); + ArrayList listCtLocation = new ArrayList(); + ArrayList listPreLocation = new ArrayList(); + StringBuilder cadPathSB = new StringBuilder(""); + //bool isDocument = false; + //if (!pages[i].Properties.PAGE_EXTDOCUMENT.IsEmpty) + //{ + // string docName = pages[i].Properties.PAGE_EXTDOCUMENT.ToString().Trim(); + // if (!docName.Equals("")) + // { + // isDocument = true; + // if (docName.EndsWith(".dwg")) + // { + // string cadPath = docName.Replace("$(DOC)", + // currentProject.ProjectDirectoryPath + + // "\\DOC"); + // if (File.Exists(cadPath)) + // { + // cadPathSB.Append(cadPath + ";"); + // } + // } + // } + //} + //if (!isDocument) + //{ + listPlant.Add(pages[i]); + //} + string location = ""; + string cnPdfName = ""; + string ctPdfName = ""; + if (!pages[i].Properties.DESIGNATION_LOCATION.IsEmpty) { + location = pages[i].Properties.DESIGNATION_LOCATION.ToString(); + if (location.Equals("CN")) { + string locationDescr = pages[i].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + listCnLocation.Add(pages[i]); + //cnPdfName = exportPath + plantFullName + "+" + location + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + else if (location.Equals("CT")) { + string locationDescr = pages[i].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + listCtLocation.Add(pages[i]); + //ctPdfName = exportPath + plantFullName + "+" + location + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + else { + listPreLocation.Add(pages[i]); + } + } + //export.DxfDwgPageToDisk(pages[i], "", exportPath, pages[i].Properties.PAGE_FULLNAME.ToString().Replace("/", "&")); + for (int j = (i + 1); j < pageNum; j++) { + string nextPageName = pages[j].Name; + + //bool isDocument2 = false; + //if (!pages[j].Properties.PAGE_EXTDOCUMENT.IsEmpty) + //{ + // string docName = pages[j].Properties.PAGE_EXTDOCUMENT.ToString().Trim(); + // if (!docName.Equals("")) + // { + // isDocument2 = true; + // if (docName.EndsWith(".dwg")) + // { + // string cadPath = docName.Replace("$(DOC)", currentProject.ProjectDirectoryPath + "\\DOC"); + // if (File.Exists(cadPath)) + // { + // cadPathSB.Append(cadPath + ";"); + // } + // } + // } + //} + string nextPlant = ""; + if (!pages[j].Properties.DESIGNATION_PLANT.IsEmpty) { + nextPlant = pages[j].Properties.get_DESIGNATION_FULLPLANT(0); + } + if (!nextPageName.StartsWith("&") && nextPlant.Equals(plant)) { + //export.DxfDwgPageToDisk(pages[j], "", exportPath, pages[j].Properties.PAGE_FULLNAME.ToString().Replace("/", "&")); + if (!pages[j].Properties.DESIGNATION_LOCATION.IsEmpty) { + string nextLocation = pages[j].Properties.DESIGNATION_LOCATION.ToString(); + if (nextLocation.Equals("CN")) { + listCnLocation.Add(pages[j]); + if (cnPdfName.Equals("")) { + string locationDescr = pages[j].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + //cnPdfName = exportPath + plantFullName + "+" + nextLocation + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + } + else if (nextLocation.Equals("CT")) { + listCtLocation.Add(pages[j]); + if (ctPdfName.Equals("")) { + string locationDescr = pages[j].Properties.DESIGNATION_LOCATION_DESCR.ToString(); + //ctPdfName = exportPath + plantFullName + "+" + nextLocation + " " + TcTool.getCNString(locationDescr) + ".pdf"; + } + } + else { + listPreLocation.Add(pages[j]); + } + } + //if (!isDocument2) + //{ + listPlant.Add(pages[j]); + //} + i++; + } + else { + //export.DxfDwgPageToDisk(pages[j], "", exportPath, pages[j].Properties.PAGE_FULLNAME.ToString().Replace("/", "&")); + break; + } + } + StringBuilder pdfPathSB = new StringBuilder(""); + if (listCnLocation.Count > 0) { + File.Delete(cnPdfName); + //export.PdfPages(listCnLocation, "", cnPdfName, Export.DegreeOfColor.Color, true, "", true); + //pdfPathSB.Append(cnPdfName).Append(";"); + } + if (listCtLocation.Count > 0) { + File.Delete(cnPdfName); + //export.PdfPages(listCtLocation, "", ctPdfName, Export.DegreeOfColor.Color, true, "", true); + //pdfPathSB.Append(ctPdfName).Append(";"); + } + if (!nameToPaths.ContainsKey(plantFullName)) { + if (pdfPathSB.ToString().Equals("")) { + if (listPlant.Count > 0) { + //File.Delete(pagePdfName); + //export.PdfPages(listPlant, "", pagePdfName, Export.DegreeOfColor.Color, true, "", true); + } + //MessageBox.Show("plantFullName=" + plantFullName + ",pagePdfName=" + pagePdfName); + //nameToPaths.Add(plantFullName, pagePdfName); + } + else { + if (listPreLocation.Count > 0) { + //File.Delete(pagePdfName); + //export.PdfPages(listPlant, "", pagePdfName, Export.DegreeOfColor.Color, true, "", true); + //pdfPathSB.Append(pagePdfName).Append(";"); + } + //MessageBox.Show("plantFullName=" + plantFullName + ",pagePdfName=" + pdfPathSB.ToString()); + //nameToPaths.Add(plantFullName, pdfPathSB.ToString()); + } + } + } + } + if (!invalidCharSB.ToString().Equals("")) { + MessageBox.Show("高层" + invalidCharSB.ToString().Substring(0, invalidCharSB.ToString().Length - 1) + "含有非法字符,请修改后再保存!"); + result = false; + progress.EndPart(true); + return result; + } + if (!File.Exists(pdfName)) { + MessageBox.Show("导出PDF失败!"); + result = false; + progress.EndPart(true); + return result; + } + } + progress.EndPart(); + } + progress.EndPart(true); + } + catch (Exception ex) { + MessageBox.Show("Error!!!" + ex.Message); + result = false; + } + return result; + } + + public bool ReadXMLFile(String url) { + //MessageBox.Show("progress----------------7"); + XmlTextReader xtr = new XmlTextReader(url); + try { + while (xtr.Read()) { + + if (xtr.NodeType == XmlNodeType.Element) { + String element_name = xtr.Name; + if (xtr.HasAttributes) { + if (element_name == "part") { + return true; + } + } + } + } + xtr.Close(); + } + catch (XmlException ex) { + MessageBox.Show(ex.Message); + } + return false; + } + } +} diff --git a/KPlan/App.config b/KPlan/App.config new file mode 100644 index 0000000..785de05 --- /dev/null +++ b/KPlan/App.config @@ -0,0 +1,62 @@ + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KPlan/ClientX/AppXCredentialManager.cs b/KPlan/ClientX/AppXCredentialManager.cs new file mode 100644 index 0000000..1f788db --- /dev/null +++ b/KPlan/ClientX/AppXCredentialManager.cs @@ -0,0 +1,146 @@ +//================================================== +// +// Copyright 2017 Siemens Product Lifecycle Management Software Inc. All Rights Reserved. +// +//================================================== + + + +using System; +using System.IO; + +using Teamcenter.Schemas.Soa._2006_03.Exceptions; +using Teamcenter.Soa; +using Teamcenter.Soa.Common; +using Teamcenter.Soa.Client; +using Teamcenter.Soa.Exceptions; + +namespace Teamcenter.ClientX +{ + +/** + * The CredentialManager is used by the Teamcenter Services framework to get the + * user's credentials when challanged by the server. This can occur after a period + * of inactivity and the server has timed-out the user's session, at which time + * the client application will need to re-authenitcate. The framework will + * call one of the getCredentials methods (depending on circumstances) and will + * send the SessionService.login service request. Upon successfull completion of + * the login service request. The last service request (one that cuased the challange) + * will be resent. + * + * The framework will also call the setUserPassword setGroupRole methods when ever + * these credentials change, thus allowing this implementation of the CredentialManager + * to cache these values so prompting of the user is not requried for re-authentication. + * + */ +public class AppXCredentialManager : CredentialManager +{ + + private String name = null; + private String password = null; + private String group = ""; // default group + private String role = ""; // default role + private String discriminator = "SoaAppX"; // always connect same user + // to same instance of server + + /** + * Return the type of credentials this implementation provides, + * standard (user/password) or Single-Sign-On. In this case + * Standard credentials are returned. + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentialType() + */ + public int CredentialType + { + get { return SoaConstants.CLIENT_CREDENTIAL_TYPE_STD; } + } + + /** + * Prompt's the user for credentials. + * This method will only be called by the framework when a login attempt has + * failed. + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentials(com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException) + */ + public string[] GetCredentials(InvalidCredentialsException e) + //throws CanceledOperationException + { + Console.WriteLine(e.Message); + return PromptForCredentials(); + } + + /** + * Return the cached credentials. + * This method will be called when a service request is sent without a valid + * session ( session has expired on the server). + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentials(com.teamcenter.schemas.soa._2006_03.exceptions.InvalidUserException) + */ + public String[] GetCredentials(InvalidUserException e) + //throws CanceledOperationException + { + // Have not logged in yet, shoult not happen but just in case + if (name == null) return PromptForCredentials(); + + // Return cached credentials + String[] tokens = { name, password, group, role, discriminator }; + return tokens; + } + + /** + * Cache the group and role + * This is called after the SessionService.setSessionGroupMember service + * operation is called. + * + * @see com.teamcenter.soa.client.CredentialManager#setGroupRole(java.lang.String, + * java.lang.String) + */ + public void SetGroupRole(String group, String role) + { + this.group = group; + this.role = role; + } + + /** + * Cache the User and Password + * This is called after the SessionService.login service operation is called. + * + * @see com.teamcenter.soa.client.CredentialManager#setUserPassword(java.lang.String, + * java.lang.String, java.lang.String) + */ + public void SetUserPassword(String user, String password, String discriminator) + { + this.name = user; + this.password = password; + this.discriminator = discriminator; + } + + + public String[] PromptForCredentials() + //throws CanceledOperationException + { + try + { + Console.WriteLine("Please enter user credentials (return to quit):"); + Console.Write("User Name: "); + name = Console.ReadLine(); + + if (name.Length == 0) + throw new CanceledOperationException(""); + + Console.Write("Password: "); + password = Console.ReadLine(); + } + catch (IOException e) + { + String message = "Failed to get the name and password.\n" + e.Message; + Console.WriteLine(message); + throw new CanceledOperationException(message); + } + + String[] tokens = { name, password, group, role, discriminator }; + return tokens; + } + +} +} diff --git a/KPlan/ClientX/AppXExceptionHandler.cs b/KPlan/ClientX/AppXExceptionHandler.cs new file mode 100644 index 0000000..10e7190 --- /dev/null +++ b/KPlan/ClientX/AppXExceptionHandler.cs @@ -0,0 +1,101 @@ +//================================================== +// +// Copyright 2017 Siemens Product Lifecycle Management Software Inc. All Rights Reserved. +// +//================================================== + + +using System; +using System.IO; + +using Teamcenter.Schemas.Soa._2006_03.Exceptions; +using Teamcenter.Soa.Client; +using Teamcenter.Soa.Exceptions; + +namespace Teamcenter.ClientX +{ + + + /** + * Implementation of the ExceptionHandler. For ConnectionExceptions (server + * temporarily down .etc) prompts the user to retry the last request. For other + * exceptions convert to a RunTime exception. + */ + public class AppXExceptionHandler : ExceptionHandler + { + + /* + * (non-Javadoc) + * + * @see com.teamcenter.soa.client.ExceptionHandler#handleException(com.teamcenter.schemas.soa._2006_03.exceptions.InternalServerException) + */ + public void HandleException(InternalServerException ise) + { + Console.WriteLine(""); + Console.WriteLine("*****"); + Console.WriteLine("Exception caught in com.teamcenter.clientx.AppXExceptionHandler.handleException(InternalServerException)."); + KPlan.Util.KUtil.LogErr(ise); + throw new System.Exception(ise.Message); + if (ise is ConnectionException) + { + // ConnectionException are typically due to a network error (server + // down .etc) and can be recovered from (the last request can be sent again, + // after the problem is corrected). + Console.Write("\nThe server returned an connection error.\n" + ise.Message + + "\nDo you wish to retry the last service request?[y/n]"); + } + else if (ise is ProtocolException) + { + // ProtocolException are typically due to programming errors + // (content of HTTP + // request is incorrect). These are generally can not be + // recovered from. + Console.Write("\nThe server returned an protocol error.\n" + ise.Message + + "\nThis is most likely the result of a programming error." + + "\nDo you wish to retry the last service request?[y/n]"); + } + else + { + Console.WriteLine("\nThe server returned an internal server error.\n" + + ise.Message + + "\nThis is most likely the result of a programming error." + + "\nA RuntimeException will be thrown."); + throw new SystemException(ise.Message); + } + + try + { + String retry = Console.ReadLine(); + // If yes, return to the calling SOA client framework, where the + // last service request will be resent. + if (retry.ToLower().Equals("y") || retry.ToLower().Equals("yes")) + return; + + throw new SystemException("The user has opted not to retry the last request"); + } + catch (IOException e) + { + Console.Error.WriteLine("Failed to read user response.\nA RuntimeException will be thrown."); + throw new SystemException(e.Message); + } + } + + /* + * (non-Javadoc) + * + * @see com.teamcenter.soa.client.ExceptionHandler#handleException(com.teamcenter.soa.exceptions.CanceledOperationException) + */ + public void HandleException(CanceledOperationException coe) + { + Console.WriteLine(""); + Console.WriteLine("*****"); + Console.WriteLine("Exception caught in com.teamcenter.clientx.AppXExceptionHandler.handleException(CanceledOperationException)."); + + // Expecting this from the login tests with bad credentials, and the + // AnyUserCredentials class not + // prompting for different credentials + throw new SystemException(coe.Message); + } + + } +} diff --git a/KPlan/ClientX/AppXModelEventListener.cs b/KPlan/ClientX/AppXModelEventListener.cs new file mode 100644 index 0000000..f081663 --- /dev/null +++ b/KPlan/ClientX/AppXModelEventListener.cs @@ -0,0 +1,65 @@ +//================================================== +// +// Copyright 2017 Siemens Product Lifecycle Management Software Inc. All Rights Reserved. +// +//================================================== + +using System; + +using Teamcenter.Soa.Client.Model; +using Teamcenter.Soa.Exceptions; + +namespace Teamcenter.ClientX +{ + + +/** + * Implementation of the ChangeListener. Print out all objects that have been updated. + * + */ + public class AppXModelEventListener : ModelEventListener + { + + override public void LocalObjectChange(ModelObject[] objects) + { + if (objects.Length == 0) return; + System.Console.WriteLine(""); + System.Console.WriteLine("Modified Objects handled in com.teamcenter.clientx.AppXUpdateObjectListener.modelObjectChange"); + System.Console.WriteLine("The following objects have been updated in the client data model:"); + for (int i = 0; i < objects.Length; i++) + { + String uid = objects[i].Uid; + String type = objects[i].GetType().Name; + String name = ""; + if (objects[i].GetType().Name.Equals("WorkspaceObject")) + { + ModelObject wo = objects[i]; + try + { + name = wo.GetProperty("object_string").StringValue; + } + catch (NotLoadedException /*e*/) {} // just ignore + } + System.Console.WriteLine(" " + uid + " " + type + " " + name); + } + } + + + override public void LocalObjectDelete(string[] uids) + { + if (uids.Length == 0) + return; + + System.Console.WriteLine(""); + System.Console.WriteLine("Deleted Objects handled in com.teamcenter.clientx.AppXDeletedObjectListener.modelObjectDelete"); + System.Console.WriteLine("The following objects have been deleted from the server and removed from the client data model:"); + for (int i = 0; i < uids.Length; i++) + { + System.Console.WriteLine(" " + uids[i]); + } + + } + + + } +} diff --git a/KPlan/ClientX/AppXPartialErrorListener.cs b/KPlan/ClientX/AppXPartialErrorListener.cs new file mode 100644 index 0000000..0d3fb92 --- /dev/null +++ b/KPlan/ClientX/AppXPartialErrorListener.cs @@ -0,0 +1,68 @@ +//================================================== +// +// Copyright 2017 Siemens Product Lifecycle Management Software Inc. All Rights Reserved. +// +//================================================== + +using System; + +using Teamcenter.Soa.Client.Model; + + +namespace Teamcenter.ClientX +{ + +/** + * Implementation of the PartialErrorListener. Print out any partial errors + * returned. + * + */ +public class AppXPartialErrorListener : PartialErrorListener +{ + + /* + * (non-Javadoc) + * + * @see com.teamcenter.soa.client.model.PartialErrorListener#handlePartialError(com.teamcenter.soa.client.model.ErrorStack[]) + */ + public void HandlePartialError(ErrorStack[] stacks) + { + if (stacks.Length == 0) return; + + Console.WriteLine(""); + Console.WriteLine("*****"); + Console.WriteLine("Partial Errors caught in com.teamcenter.clientx.AppXPartialErrorListener."); + + + for (int i = 0; i < stacks.Length; i++) + { + ErrorValue[] errors = stacks[i].ErrorValues; + Console.Write("Partial Error for "); + + // The different service implementation may optionally associate + // an ModelObject, client ID, or nothing, with each partial error + if (stacks[i].HasAssociatedObject() ) + { + Console.WriteLine("object "+ stacks[i].AssociatedObject.Uid); + } + else if (stacks[i].HasClientId()) + { + Console.WriteLine("client id "+ stacks[i].ClientId); + } + else if (stacks[i].HasClientIndex()) + { + Console.WriteLine("client index " + stacks[i].ClientIndex); + } + + // Each Partial Error will have one or more contributing error messages + for (int j = 0; j < errors.Length; j++) + { + Console.WriteLine(" Code: " + errors[j].Code + "\tSeverity: " + + errors[j].Level + "\t" + errors[j].Message); + } + } + + } + +} +} diff --git a/KPlan/ClientX/AppXRequestListener.cs b/KPlan/ClientX/AppXRequestListener.cs new file mode 100644 index 0000000..80aef51 --- /dev/null +++ b/KPlan/ClientX/AppXRequestListener.cs @@ -0,0 +1,42 @@ +//================================================== +// +// Copyright 2017 Siemens Product Lifecycle Management Software Inc. All Rights Reserved. +// +//================================================== + +using System; + +using Teamcenter.Soa.Client; + + +namespace Teamcenter.ClientX +{ + + /** + * This implemenation of the RequestListener, logs each service request + * to the console. + * + */ + public class AppXRequestListener : RequestListener + { + + + /** + * Called before each request is sent to the server. + */ + public void ServiceRequest(ServiceInfo info) + { + // will log the service name when done + } + + /** + * Called after each response from the server. + * Log the service operation to the console. + */ + public void ServiceResponse(ServiceInfo info) + { + Console.WriteLine(info.Id + ": " + info.Service + "." + info.Operation); + } + + } +} diff --git a/KPlan/ClientX/Session.cs b/KPlan/ClientX/Session.cs new file mode 100644 index 0000000..bfee6f8 --- /dev/null +++ b/KPlan/ClientX/Session.cs @@ -0,0 +1,266 @@ +//================================================== +// +// Copyright 2017 Siemens Product Lifecycle Management Software Inc. All Rights Reserved. +// +//================================================== + + + + +using System; +using System.Collections; +using System.Net; + +using Teamcenter.Schemas.Soa._2006_03.Exceptions; +using Teamcenter.Services.Strong.Core; +using Teamcenter.Services.Strong.Core._2006_03.Session; +using Teamcenter.Soa; +using Teamcenter.Soa.Client; +using Teamcenter.Soa.Client.Model; +using Teamcenter.Soa.Exceptions; + +using WorkspaceObject = Teamcenter.Soa.Client.Model.Strong.WorkspaceObject; +using User = Teamcenter.Soa.Client.Model.Strong.User; + +using KPlan.Util; + +namespace Teamcenter.ClientX +{ + + + public class Session + { + /** + * Single instance of the Connection object that is shared throughtout + * the application. This Connection object is needed whenever a Service + * stub is instantiated. + */ + private static Connection connection; + + /** + * The credentialManager is used both by the Session class and the Teamcenter + * Services Framework to get user credentials. + * + */ + private static AppXCredentialManager credentialManager; + + /** + * Create an instance of the Session with a connection to the specified + * server. + * + * Add implementations of the ExceptionHandler, PartialErrorListener, + * ChangeListener, and DeleteListeners. + * + * @param host Address of the host to connect to, http://serverName:port/tc + */ + public Session(String host) + { + // Create an instance of the CredentialManager, this is used + // by the SOA Framework to get the user's credentials when + // challanged by the server (sesioin timeout on the web tier). + credentialManager = new AppXCredentialManager(); + string proto = null; + string envNameTccs = null; + if (host.StartsWith("http")) + { + proto = SoaConstants.HTTP; + } + else if (host.StartsWith("tccs")) + { + proto = SoaConstants.TCCS; + int envNameStart = host.IndexOf('/') + 2; + envNameTccs = host.Substring(envNameStart, host.Length - envNameStart); + + } + + // Create the Connection object, no contact is made with the server + // until a service request is made + connection = new Connection(host, new System.Net.CookieCollection(), credentialManager, SoaConstants.REST, proto, false); + if (proto == SoaConstants.TCCS) + connection.SetOption(Connection.TCCS_ENV_NAME, envNameTccs); + + + // Add an ExceptionHandler to the Connection, this will handle any + // InternalServerException, communication errors, xml marshalling errors + // .etc + connection.ExceptionHandler = new AppXExceptionHandler(); + + // While the above ExceptionHandler is required, all of the following + // Listeners are optional. Client application can add as many or as few Listeners + // of each type that they want. + + // Add a Partial Error Listener, this will be notified when ever a + // a service returns partial errors. + connection.ModelManager.AddPartialErrorListener(new AppXPartialErrorListener()); + + // Add a Change and Delete Listener, this will be notified when ever a + // a service returns model objects that have been updated or deleted. + connection.ModelManager.AddModelEventListener(new AppXModelEventListener()); + + // Add a Request Listener, this will be notified before and after each + // service request is sent to the server. + Connection.AddRequestListener(new AppXRequestListener()); + } + + /** + * Get the single Connection object for the application + * + * @return connection + */ + public static Connection getConnection() + { + return connection; + } + + public User Login2(string username, string password, string usergroup, string userrole) { + // Get the service stub + SessionService sessionService = SessionService.getService(connection); + LoginResponse resp = sessionService.Login(username, password, usergroup, userrole, "", ""); + TCUtil.ThrowServiceDataError(resp.ServiceData); + //LoginResponse resp = sessionService.Login(username, password, usergroup, userrole, "", ""); + return resp.User; + } + + /** + * Login to the Teamcenter Server + * + */ + public User login() + { + // Get the service stub + SessionService sessionService = SessionService.getService(connection); + + try + { + // Prompt for credentials until they are right, or until user + // cancels + String[] credentials = credentialManager.PromptForCredentials(); + while (true) + { + try + { + + // ***************************** + // Execute the service operation + // ***************************** + LoginResponse resp = sessionService.Login(credentials[0], credentials[1], + credentials[2], credentials[3],"",credentials[4]); + + return resp.User; + } + catch (InvalidCredentialsException e) + { + credentials = credentialManager.GetCredentials(e); + } + } + } + // User canceled the operation, don't need to tell him again + catch (CanceledOperationException /*e*/) {} + + // Exit the application + //System.exit(0); + return null; + } + + /** + * Terminate the session with the Teamcenter Server + * + */ + public void logout() + { + // Get the service stub + SessionService sessionService = SessionService.getService(connection); + try + { + // ***************************** + // Execute the service operation + // ***************************** + sessionService.Logout(); + } + catch (ServiceException /*e*/) { } + } + + /** + * Print some basic information for a list of objects + * + * @param objects + */ + public static void printObjects(ModelObject[] objects) + { + if(objects == null) + return; + + + // Ensure that the referenced User objects that we will use below are loaded + getUsers( objects ); + + Console.WriteLine("Name\t\tOwner\t\tLast Modified"); + Console.WriteLine("====\t\t=====\t\t============="); + for (int i = 0; i < objects.Length; i++) + { + if(!(objects[i] is WorkspaceObject )) + continue; + + WorkspaceObject wo = (WorkspaceObject)objects[i]; + try + { + String name = wo.Object_string; + User owner = (User) wo.Owning_user; + DateTime lastModified =wo.Last_mod_date; + + Console.WriteLine(name + "\t" + owner.User_name + "\t" + lastModified.ToString()); + } + catch (NotLoadedException e) + { + // Print out a message, and skip to the next item in the folder + // Could do a DataManagementService.getProperties call at this point + Console.WriteLine(e.Message); + Console.WriteLine("The Object Property Policy ($TC_DATA/soa/policies/Default.xml) is not configured with this property."); + } + } + + } + + + private static void getUsers(ModelObject[] objects) + { + if(objects == null) + return; + + DataManagementService dmService = DataManagementService.getService(Session.getConnection()); + ArrayList unKnownUsers = new ArrayList(); + for (int i = 0; i < objects.Length; i++) + { + if(!(objects[i] is WorkspaceObject )) + continue; + + WorkspaceObject wo = (WorkspaceObject)objects[i]; + + User owner = null; + try + { + owner = (User) wo.Owning_user; + String userName = owner.User_name; + } + catch (NotLoadedException /*e*/) + { + if(owner != null) + unKnownUsers.Add(owner); + } + } + User[] users = new User[unKnownUsers.Count]; + unKnownUsers.CopyTo( users ); + String[] attributes = { "user_name" }; + + + // ***************************** + // Execute the service operation + // ***************************** + dmService.GetProperties(users, attributes); + + + } + + + } +} diff --git a/KPlan/Forms/Bean/CheckTableRowData.cs b/KPlan/Forms/Bean/CheckTableRowData.cs new file mode 100644 index 0000000..c5002f6 --- /dev/null +++ b/KPlan/Forms/Bean/CheckTableRowData.cs @@ -0,0 +1,203 @@ +using Eplan.EplApi.Base; +using KPlan.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using Teamcenter.Services.Strong.Cad._2007_01.StructureManagement; + +namespace KPlan.Forms.Bean { + + public class CheckTableRowData { + public const string INDEX = "INDEX"; + public const string CHECK = "CHECK"; + public const string COUNT = "P_ARTICLEREF_COUNT"; + public const string ITEMID = "P_ARTICLE_ERPNR"; + public const string ORDERNR = "P_ARTICLE_ORDERNR"; + public const string DEVICETAG = "P_FUNC_IDENTDEVICETAG"; + + private string title = ""; + private XmlNode node2; + public bool checkOK = false; + public object[] rowData; + public string itemId; + public string orderNo; + public string itemUid; + public string deviceTag; + private List nodeToCombine = new List(); + private bool itemExist; + + public CheckTableRowData(string itemId,string orderNo, XmlNode node, bool itemExist, string itemUid) { + this.node2 = node; + if (!string.IsNullOrWhiteSpace(itemId)) { + this.itemId = itemId; + } + else { + this.itemId = GetPropValue(ITEMID, -1)?.ToString(); + } + if (!string.IsNullOrWhiteSpace(orderNo)) { + this.orderNo = orderNo; + } + else { + this.orderNo = GetPropValue(ORDERNR, -1)?.ToString(); + } + this.deviceTag = GetPropValue(DEVICETAG, -1)?.ToString(); + this.itemExist = itemExist; + this.itemUid = itemUid; + } + + public void addCombineNode(CheckTableRowData bean) { + if (bean.node2 != null) { + nodeToCombine.Add(bean.node2); + } + } + + public bool CheckOK() { + return checkOK; + } + + public override bool Equals(object obj) { + CheckTableRowData bean = obj as CheckTableRowData; + if (bean == null) { return false; } + if (!this.itemId.Equals(bean.itemId)){ + return false; + } + if (this.deviceTag == null) { + return bean.deviceTag == null; + } + else { + return this.deviceTag.Equals(bean.deviceTag); + } + } + + + public object[] GetRowData(int index, List config) { + int len = config.Count; + object[] res = new object[len]; + /*if (len > 0) { + title = GetPropValue(config[0], index); + res[0] = this; + }*/ + for (int i = 0; i < len; i++) { + + res[i] = GetPropValue(config[i], index); + // KUtil.DispatcherShow(kCheckProject_Ex, "i:" + i + "config[i]:"+ config[i] + " res[i]:" + res[i]); + } + rowData = res; + + return res; + } + + public AttributesInfo[] GetBomProp(Dictionary saveConfig) { + if (saveConfig == null) { + return null; + } + List res = new List(); + foreach (string tc in saveConfig.Keys) { + string eplan = saveConfig[tc]; + string val = GetPropValue(eplan,-1)?.ToString(); + AttributesInfo info = new AttributesInfo(); + info.Name = tc; + info.Value = val == null ? "" : val; + res.Add(info); + } + return res.ToArray(); + } + + private object GetPropValue(string config, int index) { + if (INDEX.Equals(config)) { + return index; + } + if (CHECK.Equals(config)) { + return Check(); + } + if (COUNT.Equals(config)) { + return Count(); + } + if (ITEMID.Equals(config)) { + return itemId; + } + if (ORDERNR.Equals(config)) { + return orderNo; + } + int ind = config.IndexOf('@'); + string language = null; + if (ind > 0) { + language = config.Substring(ind + 1); + config = config.Substring(0, ind); + } + string val = null; + if (node2 != null) { + val = node2.Attributes[config]?.InnerText; + if (!KUtil.IsEmpty(val) && !KUtil.IsEmpty(language)) { + MultiLangString multiLangString = new MultiLangString(); + multiLangString.SetAsString(val); + val = multiLangString.GetString((ISOCode.Language)Enum.Parse(typeof(ISOCode.Language), language)); + } + } + //XmlAttribute attr = node.Attributes[config]; + return val == null ? "" : val; + } + + private string Count() { + if (node2 == null) { + return ""; + } + double total = 0; + string refCount = node2.Attributes["P_ARTICLEREF_COUNT"]?.InnerText; + string lenth = node2.Attributes["P_ARTICLE_PARTIAL_LENGTH_VALUE"]?.InnerText; + if (KUtil.IsEmpty(lenth)) { + lenth = "1"; + } + if (!KUtil.IsEmpty(refCount) && !KUtil.IsEmpty(lenth)) { + double dwire_length = Convert.ToDouble(lenth); + if (dwire_length != 0.0) { + double drecord_num = Convert.ToDouble(refCount); + drecord_num = dwire_length * drecord_num; + total += drecord_num; + } + } + foreach(XmlNode node in nodeToCombine) { + refCount = node.Attributes["P_ARTICLEREF_COUNT"]?.InnerText; + lenth = node.Attributes["P_ARTICLE_PARTIAL_LENGTH_VALUE"]?.InnerText; + if (KUtil.IsEmpty(lenth)) { + lenth = "1"; + } + if (!KUtil.IsEmpty(refCount) && !KUtil.IsEmpty(lenth)) { + double dwire_length = Convert.ToDouble(lenth); + if (dwire_length != 0.0) { + double drecord_num = Convert.ToDouble(refCount); + drecord_num = dwire_length * drecord_num; + total += drecord_num; + } + } + } + return total.ToString(); + } + + + private string Check() { + if (node2 != null) { + XmlAttribute discontinue = node2.Attributes["P_ARTICLE_DISCONTINUED"];//?.InnerText; + if (discontinue != null && !"0".Equals(discontinue.InnerText)) { + return "停产部件"; + } + } + //string itemId = node.Attributes["P_ARTICLE_ERPNR"]?.InnerText; + //string itemId = erpAttr == null ? "" : erpAttr.Value; + if (itemExist) { + //if (TCUtil.ItemExist(itemId)) { + checkOK = true; + return "TC存在"; + } + return "TC不存在"; + } + + public override string ToString() { + return title; + } + } +} diff --git a/KPlan/Forms/Bean/DuplicateOrderNrBean.cs b/KPlan/Forms/Bean/DuplicateOrderNrBean.cs new file mode 100644 index 0000000..493854a --- /dev/null +++ b/KPlan/Forms/Bean/DuplicateOrderNrBean.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms.Bean { + class DuplicateOrderNrBean { + + public string orderNr { get; set; } + public string partNr { get; set; } + public string manufacturer { get; set; } + public string reason = "TC中存在多个相同 Order Number 的物料"; + } +} diff --git a/KPlan/Forms/Bean/EPlanPropBean.cs b/KPlan/Forms/Bean/EPlanPropBean.cs new file mode 100644 index 0000000..8ba03e8 --- /dev/null +++ b/KPlan/Forms/Bean/EPlanPropBean.cs @@ -0,0 +1,36 @@ +using Eplan.EplApi.Base; +using Eplan.EplApi.DataModel; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using KPlan.Util; + +namespace KPlan.Forms.Bean { + class EPlanPropBean { + public string disName { get; set; } + public string realName { get; set; } + public string type { get; set; } + public string language { get; set; } + public bool isComboReadOnly { get; set; } + + public EPlanPropBean(string type) { + this.type = type; + this.isComboReadOnly = PropertyDefinition.PropertyType.MultilangString.ToString().Equals(type); + } + + public string getConfigValue() { + if ("MultilangString".Equals(type)){ + if (KUtil.IsEmpty(language)){ + return ""; + // throw new Exception("未选择语言环境:"+disName+"/"+realName+"/"+type); + } + return realName + "@" + language; + } + return realName; + } + + } +} diff --git a/KPlan/Forms/Bean/EPlanTreeItem.cs b/KPlan/Forms/Bean/EPlanTreeItem.cs new file mode 100644 index 0000000..46ff6b2 --- /dev/null +++ b/KPlan/Forms/Bean/EPlanTreeItem.cs @@ -0,0 +1,67 @@ +using Eplan.EplApi.MasterData; +using KPlan.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Media.Imaging; + +namespace KPlan.Forms { + public class EPlanTreeItem : TreeViewItem { + + public string object_string { get; set; } + public MDPart part { get; set; } + public bool isLoadMark = false; + public int groupId { get; set; } + /// + /// 分类用 + /// + public MDPartsDatabaseItem.Enums.ProductGroup productGroup { get; set; } + public MDPartsDatabaseItem.Enums.ProductTopGroup productTopGroup { get; set; } + public bool isProductGroup = false; + + + public EPlanTreeItem() { + Header = "Loading"; + isLoadMark = true; + } + + public EPlanTreeItem(MDPart obj,string groupName) { + if (obj == null) { + Header = "Loading"; + } + else { + this.part = obj; + this.object_string = this.part.PartNr; + Header = this.object_string; + Resources["ICON"] = TCUtil.GetIcon(groupName); + } + } + + public EPlanTreeItem(MDPartsDatabaseItem.Enums.ProductTopGroup topGroup) { + this.groupId = (int)topGroup; + string header = MDPartsDatabaseItem.GetProductTopGroupName(topGroup); + if (KUtil.IsEmpty(header)) { header = topGroup.ToString(); } + Header = header; + Resources["ICON"] = new BitmapImage(new Uri("pack://application:,,,/EPLAN.EplAddin.KPlan;component/Resources_EPLAN/e_folder.png")); + } + + public EPlanTreeItem(MDPartsDatabaseItem.Enums.ProductTopGroup topGroup,MDPartsDatabaseItem.Enums.ProductGroup group) { + this.groupId = (int)group; + this.productGroup = group;//分类用 + this.productTopGroup = topGroup; + this.isProductGroup = true; + string header = MDPartsDatabaseItem.GetProductGroupName(group); + Header = header; + Resources["ICON"] = TCUtil.GetIcon(header); + } + + public EPlanTreeItem(string header) { + Header = header; + Resources["ICON"] = new BitmapImage(new Uri("pack://application:,,,/EPLAN.EplAddin.KPlan;component/Resources_EPLAN/e_folder.png")); + } + + } +} diff --git a/KPlan/Forms/Bean/KPartSyncDataRow.cs b/KPlan/Forms/Bean/KPartSyncDataRow.cs new file mode 100644 index 0000000..943b8df --- /dev/null +++ b/KPlan/Forms/Bean/KPartSyncDataRow.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms.Bean { + public class KPartSyncDataRow { + + public int index { get; set; } + public string eplan_orderno { get; set; } + public string eplan_partno { get; set; } + public string eplan_erpno { get; set; } + public string eplan_name { get; set; } + public string eplan_desc { get; set; } + public string eplan_manufacturer { get; set; } + public string tc_itemid { get; set; } + public string tc_name { get; set; } + public string tc_revid { get; set; } + public string tc_desc { get; set; } + public string tc_manufacturer { get; set; } + public string tc_releasestatus { get; set; } + public string sync_status { get; set; } + + public Eplan.EplApi.MasterData.MDPart part {get;set;} + public Teamcenter.Soa.Client.Model.Strong.ItemRevision rev { get; set; } + + public override bool Equals(object obj) { + KPartSyncDataRow row = obj as KPartSyncDataRow; + if (row == null) { + return false; + } + if (this == obj) { + return true; + } + string partNr1 = eplan_partno == null ? "" : eplan_partno; + string partNr2 = row.eplan_partno == null ? "" : row.eplan_partno; + string itemId1 = tc_itemid == null ? "" : tc_itemid; + string itemId2 = row.tc_itemid == null ? "" : row.tc_itemid; + string rev1 = tc_revid == null ? "" : tc_revid; + string rev2 = row.tc_revid == null ? "" : row.tc_revid; + return partNr1.Equals(partNr2) && itemId1.Equals(itemId2) && rev1.Equals(rev2); + } + + } +} diff --git a/KPlan/Forms/Bean/ModelObjectBean.cs b/KPlan/Forms/Bean/ModelObjectBean.cs new file mode 100644 index 0000000..dd57b1a --- /dev/null +++ b/KPlan/Forms/Bean/ModelObjectBean.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Teamcenter.Soa.Client.Model; + +namespace KPlan.Forms.Bean { + class ModelObjectBean { + public ModelObject mo { get; set; } + public string objectString { get; set; } + + public ModelObjectBean(ModelObject mo,string objectString) { + this.mo = mo; + this.objectString = objectString; + } + + public override string ToString() { + return objectString; + } + + } +} diff --git a/KPlan/Forms/Bean/PartSyncClassConfigBean.cs b/KPlan/Forms/Bean/PartSyncClassConfigBean.cs new file mode 100644 index 0000000..2e84046 --- /dev/null +++ b/KPlan/Forms/Bean/PartSyncClassConfigBean.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms.Bean { + class PartSyncClassConfigBean { + public string from { get; set; } + public string to { get; set; } + + public override bool Equals(object obj) { + if (obj != null && obj.GetType() == typeof(PartSyncClassConfigBean)) { + PartSyncClassConfigBean b = (PartSyncClassConfigBean)obj; + if (from != null) { + return from.Equals(b.from); + } + } + return false; + } + } +} diff --git a/KPlan/Forms/Bean/PartSyncConfigBean.cs b/KPlan/Forms/Bean/PartSyncConfigBean.cs new file mode 100644 index 0000000..b6fc539 --- /dev/null +++ b/KPlan/Forms/Bean/PartSyncConfigBean.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms.Bean { + class PartSyncConfigBean { + + public string from { get; set; } + public string to { get; set; } + + public override bool Equals(object obj) { + if (obj != null && obj.GetType() == typeof(PartSyncConfigBean)) { + PartSyncConfigBean b = (PartSyncConfigBean)obj; + if (to != null) { + return to.Equals(b.to); + } + } + return false; + } + } +} diff --git a/KPlan/Forms/Bean/PartSyncDataRow.cs b/KPlan/Forms/Bean/PartSyncDataRow.cs new file mode 100644 index 0000000..2ace7f8 --- /dev/null +++ b/KPlan/Forms/Bean/PartSyncDataRow.cs @@ -0,0 +1,29 @@ +using Eplan.EplApi.MasterData; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms { + class PartSyncDataRow { + public int index { get; set; } + public string partNr { get; set; } + public string name { get; set; } + public string itemID { get; set; } + public string itemName { get; set; } + public string itemRev { get; set; } + public string type { get; set; } + public string releaseStatus { get; set; } + public string syncStatus { get; set; } + public MDPart part { get; set; } + public Teamcenter.Soa.Client.Model.Strong.ItemRevision tcRev { get; set; } + + public override bool Equals(object obj) { + if (partNr!= null&&obj.GetType() == typeof(PartSyncDataRow)) { + return partNr.Equals(((PartSyncDataRow)obj).partNr); + } + return false; + } + } +} diff --git a/KPlan/Forms/Bean/SyncResult.cs b/KPlan/Forms/Bean/SyncResult.cs new file mode 100644 index 0000000..c3eb450 --- /dev/null +++ b/KPlan/Forms/Bean/SyncResult.cs @@ -0,0 +1,25 @@ +using Eplan.EplApi.MasterData; +using KPlan.Forms.Bean; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms { + public class SyncResult { + + public SyncResult(KPartSyncDataRow dataRow) { + this.dataRow = dataRow; + } + public KPartSyncDataRow dataRow { get; set; } + public string partNr { get; set; } + public string orderNr { get; set; } + public string name { get; set; } + public string jldw { get; set; } + public string desc_cn { get; set; } + public string desc_en { get; set; } + public string reason { get; set; } + + } +} diff --git a/KPlan/Forms/Bean/TCPropBean.cs b/KPlan/Forms/Bean/TCPropBean.cs new file mode 100644 index 0000000..995736c --- /dev/null +++ b/KPlan/Forms/Bean/TCPropBean.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KPlan.Forms.Bean { + class TCPropBean { + + public string location { get; set; } + public string disName { get; set; } + public string realName { get; set; } + public string typeName { get; set; } + } +} diff --git a/KPlan/Forms/Bean/TCTreeItem.cs b/KPlan/Forms/Bean/TCTreeItem.cs new file mode 100644 index 0000000..a0cb6f3 --- /dev/null +++ b/KPlan/Forms/Bean/TCTreeItem.cs @@ -0,0 +1,39 @@ +using KPlan.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Media.Imaging; +using Teamcenter.Soa.Client.Model; + +namespace KPlan.Forms { + class TCTreeItem : TreeViewItem{ + + public ModelObject mo { get; set; } + public string object_string { get; set; } + + public TCTreeItem(ModelObject obj) { + if (obj == null) { + Header = "Loading"; + } + else { + this.mo = obj; + ModelObject[] objs = TCUtil.Refresh(mo); + TCUtil.GetProperties(false, objs, "object_string"); + this.object_string = "[" + mo.SoaType.Name + "]" + mo.GetPropertyDisplayableValue("object_string"); + Header = this.object_string; + Resources["ICON"] = new BitmapImage(new Uri("pack://application:,,,/EPLAN.EplAddin.KPlan;component/Resources/" + TCUtil.GetIconName(mo))); + } + + } + + public TCTreeItem(ModelObject mo, string folderName,string iconName) { + Header = folderName; + this.mo = mo; + Resources["ICON"] = new BitmapImage(new Uri("pack://application:,,,/EPLAN.EplAddin.KPlan;component/Resources/"+iconName)); + } + + } +} diff --git a/KPlan/Forms/Bean/TableRowData.cs b/KPlan/Forms/Bean/TableRowData.cs new file mode 100644 index 0000000..fcbef9b --- /dev/null +++ b/KPlan/Forms/Bean/TableRowData.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Teamcenter.Soa.Client.Model; +using KPlan.Util; + +namespace KPlan.Forms { + class TableRowData { + + private const string INDEX = "INDEX"; + + public ModelObject mo { get; set; } + private string title = ""; + + public TableRowData(ModelObject mo) { + this.mo = mo; + } + + public object[] GetRowData(int index,List config) { + int len = config.Count; + object[] res = new object[len]; + if (len > 0) { + title = GetPropValue(mo, config[0], index); + res[0] = this; + } + for (int i = 1; i < len; i++) { + res[i] = GetPropValue(mo, config[i],index); + } + return res; + } + + private string GetPropValue(ModelObject mo, string config, int index) { + if (INDEX.Equals(config)) { + return index + ""; + } + return TCUtil.GetPropValue(mo, config); + } + + public override string ToString() { + return title; + } + } +} diff --git a/KPlan/Forms/Config_Classification.xaml b/KPlan/Forms/Config_Classification.xaml new file mode 100644 index 0000000..811cda4 --- /dev/null +++ b/KPlan/Forms/Config_Classification.xaml @@ -0,0 +1,37 @@ + + + + + + + + EPLAN元器件组 + + + + 分类映射关系 + + + + + + + + + + + + + + + + + diff --git a/KPlan/Forms/Config_Classification.xaml.cs b/KPlan/Forms/Config_Classification.xaml.cs new file mode 100644 index 0000000..a54e17f --- /dev/null +++ b/KPlan/Forms/Config_Classification.xaml.cs @@ -0,0 +1,105 @@ +using Eplan.EplApi.MasterData; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using KPlan.Forms.Bean; +using KPlan.Util; + +namespace KPlan.Forms { + /// + /// Interaction logic for Config_Classification.xaml + /// + public partial class Config_Classification : UserControl { + + private ObservableCollection class_config = new ObservableCollection(); + public Config_Classification() { + InitializeComponent(); + this.table_Class.ItemsSource = class_config; + } + + public void LoadPartGroups() { + EPlanTreeItem tree_home = new EPlanTreeItem("Parts"); + tree_Part_Groups.Items.Add(tree_home); + Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup.Electric, tree_home); + Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup.Mechanic, tree_home); + Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup.Fluid, tree_home); + Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup.Process, tree_home); + Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup.Invaild, tree_home); + Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup.Undefined, tree_home); + this.Dispatcher.Invoke(new Action(delegate { + tree_home.IsExpanded = true; + })); + } + + + + private void Init_TopGroup(MDPartsDatabaseItem.Enums.ProductTopGroup topGroup, EPlanTreeItem tree_home) { + EPlanTreeItem tree_TopGroup = new EPlanTreeItem(topGroup); + //KUtil.Log(tree_TopGroup.Header.ToString()); + tree_home.Items.Add(tree_TopGroup); + //加载Group + MDPartsDatabaseItem.Enums.ProductGroup[] groups = MDPartsDatabaseItem.GetAvailableProductGroups(topGroup); + for (int i = 0; i < groups.Length; i++) { + MDPartsDatabaseItem.Enums.ProductGroup group = groups[i]; + EPlanTreeItem tree_Group = new EPlanTreeItem(topGroup,group); + tree_TopGroup.Items.Add(tree_Group); + } + tree_TopGroup.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending)); + tree_TopGroup.Items.Refresh(); + } + + public void SaveConfiguration() { + table_Class.Items.Refresh(); + KUtil.ClearConfigSection(KConfigure.PART_SYNC_CLASSIFICATION); + //eplan to tc + Dictionary classMap = new Dictionary(); + for (int i = 0; i < class_config.Count; i++) { + PartSyncClassConfigBean bean = class_config[i]; + //KUtil.Log(bean.from+"->"+bean.to); + if (!KUtil.IsEmpty(bean.to) && !KUtil.IsEmpty(bean.from)) { + classMap.Add(bean.from, bean.to); + } + } + KUtil.SetConfigValue(KConfigure.PART_SYNC_CLASSIFICATION, classMap); + } + + public void LoadConfiguration() { + Dictionary eplan_to_tc = KUtil.GetConfigValue(KConfigure.PART_SYNC_CLASSIFICATION); + foreach (string key in eplan_to_tc.Keys) { + string val = eplan_to_tc[key]; + //KUtil.Log(key + "->" + val); + if (!KUtil.IsEmpty(key) && !KUtil.IsEmpty(val)) { + PartSyncClassConfigBean bean = new PartSyncClassConfigBean() { from = key, to = val }; + class_config.Add(bean); + } + } + } + + private void Tree_Part_Groups_MouseDoubleClick(object sender, MouseButtonEventArgs e) { + EPlanTreeItem selectedItem = tree_Part_Groups.SelectedItem as EPlanTreeItem; + if (selectedItem == null || !selectedItem.isProductGroup) { + return; + } + PartSyncClassConfigBean bean = new PartSyncClassConfigBean() { from = selectedItem.productTopGroup.ToString() + "." + selectedItem.productGroup.ToString() }; + if (!class_config.Contains(bean)) { + class_config.Add(bean); + } + table_Class.Items.Refresh(); + table_Class.SelectedItem = bean; + table_Class.ScrollIntoView(bean); + } + } +} diff --git a/KPlan/Forms/Config_Others.xaml b/KPlan/Forms/Config_Others.xaml new file mode 100644 index 0000000..d93f9b8 --- /dev/null +++ b/KPlan/Forms/Config_Others.xaml @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + 打开配置 + + + + + + + + + + + + + + + + + + 文件服务 + + + + + + + + + + + + + + + + + EPLAN数据 + + + + + + + + + + + + + + + + + + + + + + + + TC to Eplan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KPlan/Forms/Config_PartSync.xaml.cs b/KPlan/Forms/Config_PartSync.xaml.cs new file mode 100644 index 0000000..1248fa8 --- /dev/null +++ b/KPlan/Forms/Config_PartSync.xaml.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using KPlan.Util; +using KPlan.Forms.Bean; +using System.Collections.ObjectModel; +using Eplan.EplApi.MasterData; +using Eplan.EplApi.Base; + +namespace KPlan.Forms { + /// + /// Interaction logic for Config_PartSync.xaml + /// + public partial class Config_PartSync : Grid { + private string loadedType; + private List ePlanPropBeanList = new List(); + private ObservableCollection ePlanPropBeanData = new ObservableCollection(); + private ObservableCollection tcPropBeanData = new ObservableCollection(); + private ObservableCollection eplan_to_tc_config = new ObservableCollection(); + private ObservableCollection tc_to_eplan_config = new ObservableCollection(); + private Dictionary> tcPropMap = new Dictionary>(); + public ObservableCollection language_list = new ObservableCollection(); + + public Config_PartSync() { + InitializeComponent(); + ReadEplanProperty(); + table_Eplan_Prop.ItemsSource = ePlanPropBeanData; + table_TC_Prop.ItemsSource = tcPropBeanData; + table_EPLAN_TO_TC.ItemsSource = eplan_to_tc_config; + table_TC_TO_EPLAN.ItemsSource = tc_to_eplan_config; + string[] ENUM_LANGUAGES = Enum.GetNames(typeof(ISOCode.Language)); + Array.Sort(ENUM_LANGUAGES); + foreach (string l in ENUM_LANGUAGES) { + language_list.Add(l); + } + col_language.ItemsSource = language_list; + try { + string itemTypeName = KUtil.GetConfigValue(KConfigure.PART_SYNC_SECTION, KConfigure.PART_SYNC_TC_ITEM_TYPE); + TCUtil.GetDefinedProperties(itemTypeName); + ReadTcProperty(itemTypeName); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + //MessageBox.Show("加载数据出错:" + ex.Message); + } + } + + + private void ChangeType() { + string newType = tb_ObjectType.Text; + if (KUtil.IsEmpty(newType)) { + MessageBox.Show("请输入对象类型"); + return; + } + if (newType.Equals(loadedType)) { + return; + } + MessageBoxResult res = MessageBox.Show("重新加载对象类型将清空当前映射配置,是否继续?", "", MessageBoxButton.YesNo); + if (res != MessageBoxResult.Yes) { + return; + } + //清空 + ClearPropConfig(); + //加载TC属性 + ReadTcProperty(newType); + loadedType = newType; + } + + private void ReadTcProperty(string itemTypeName) { + tcPropBeanData.Clear(); + cb_Location.Items.Clear(); + cb_Location.Items.Add(""); + this.tcPropMap = TCUtil.GetDefinedProperties(itemTypeName); + foreach (string key in tcPropMap.Keys) { + cb_Location.Items.Add(key); + List list = tcPropMap[key]; + foreach (TCPropBean b in list) { + tcPropBeanData.Add(b); + } + } + } + + private void ReadEplanProperty() { + ePlanPropBeanList.Clear(); + ePlanPropBeanData.Clear(); + Eplan.EplApi.DataModel.AnyPropertyId[] props = Eplan.EplApi.DataModel.Properties.AllArticlePropIDs; + for (int i = 0; i < props.Length; i++) { + Eplan.EplApi.DataModel.AnyPropertyId prop = props[i]; + //MessageBox.Show("disName:"+ prop.Definition.Name+ " realName:"+ prop.AsArticle.ToString()); + if (prop.Definition.IsReadOnly) { + continue; + } + EPlanPropBean bean = new EPlanPropBean(prop.Definition.Type.ToString()) { disName = prop.Definition.Name, realName = prop.AsArticle.ToString() }; + ePlanPropBeanList.Add(bean); + ePlanPropBeanData.Add(bean); + } + } + + private void ClearPropConfig() { + eplan_to_tc_config.Clear(); + tc_to_eplan_config.Clear(); + } + + private void Remove_Config(DataGrid dataGrid, ObservableCollection data) { + try { + System.Collections.IList selectedItems = dataGrid.SelectedItems; + if (selectedItems == null || selectedItems.Count == 0) { + return; + } + while (selectedItems.Count > 0) { + data.Remove((PartSyncConfigBean)selectedItems[0]); + dataGrid.Items.Refresh(); + } + dataGrid.Items.Refresh(); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show(ex.Message); + } + } + + private void Modify_Config(DataGrid dataGrid, ObservableCollection data, string from, string to) { + if (KUtil.IsEmpty(from) || KUtil.IsEmpty(to)) { + return; + } + PartSyncConfigBean selectedBean = dataGrid.SelectedItem as PartSyncConfigBean; + if (selectedBean == null) { + return; + } + int existInd = data.IndexOf(new PartSyncConfigBean() { from = from, to = to }); + if (existInd >= 0 && !to.Equals(selectedBean.to)) { + MessageBox.Show("已存在属性映射到"+to); + return; + } + //PartSyncConfigBean bean = (PartSyncConfigBean)dataGrid.Items[ind]; + selectedBean.from = from; + selectedBean.to = to; + dataGrid.Items.Refresh(); + dataGrid.SelectedItem = selectedBean; + + } + + private void Add_Config(DataGrid dataGrid, ObservableCollection data, string from, string to) { + if (KUtil.IsEmpty(from) || KUtil.IsEmpty(to)) { + return; + } + PartSyncConfigBean bean = new PartSyncConfigBean() { from = from, to = to }; + if (!data.Contains(bean)) { + data.Add(bean); + } + dataGrid.SelectedItem = bean; + dataGrid.ScrollIntoView(bean); + } + + private void Read_Prop_Refection_to_Textbox() { + EPlanPropBean eplanBean = table_Eplan_Prop.SelectedItem as EPlanPropBean; + TCPropBean tcBean = table_TC_Prop.SelectedItem as TCPropBean; + string eplanConfig = ""; + string tcConfig = ""; + if (eplanBean != null) { + eplanConfig = eplanBean.getConfigValue(); + } + if (tcBean != null) { + tcConfig = tcBean.location + "." + tcBean.realName; + } + tb_TC_TO_EPLAN_tc.Text = tcConfig; + tb_TC_TO_EPLAN_eplan.Text = eplanConfig; + tb_EPLAN_TO_TC_eplan.Text = eplanConfig; + tb_EPLAN_TO_TC_tc.Text = tcConfig; + } + + private void Find_TC_Props() { + string text = tb_TCProp.Text; + string type = cb_Location.SelectedItem as string; + tcPropBeanData.Clear(); + if (KUtil.IsEmpty(type) && KUtil.IsEmpty(text)) { + foreach (List list in tcPropMap.Values) { + foreach (TCPropBean b in list) { + tcPropBeanData.Add(b); + } + } + } + else { + text = text.ToLower(); + foreach (List list in tcPropMap.Values) { + foreach (TCPropBean b in list) { + if (KUtil.RegexMatch(b.disName.ToLower(), text) || KUtil.RegexMatch(b.realName.ToLower(), text)) { + //if (b.disName.ToLower().Contains(text) || b.realName.ToLower().Contains(text)) { + if (KUtil.IsEmpty(type) || b.typeName.Equals(type)) { + tcPropBeanData.Add(b); + } + } + } + } + } + } + + private void Find_EPlan_Props() { + string text = tb_EPlanProp.Text; + ePlanPropBeanData.Clear(); + if (KUtil.IsEmpty(text)) { + foreach (EPlanPropBean bean in ePlanPropBeanList) { + ePlanPropBeanData.Add(bean); + } + } + else { + text = text.ToLower(); + foreach (EPlanPropBean bean in ePlanPropBeanList) { + if (KUtil.RegexMatch(bean.disName.ToLower(), text) || KUtil.RegexMatch(bean.realName.ToLower(), text)) { + //if (bean.disName.ToLower().Contains(text) || bean.realName.ToLower().Contains(text)) { + ePlanPropBeanData.Add(bean); + } + } + } + } + + + + public void SaveConfiguration() { + Dictionary syncConfig = new Dictionary(); + syncConfig.Add(KConfigure.PART_SYNC_TC_ITEM_TYPE, tb_ObjectType.Text); + syncConfig.Add(KConfigure.PART_SYNC_OrderNr_TC, tb_OrderNr_Prop.Text); + //syncConfig.Add(KConfigure.PART_SYNC_ItemID_EPlan, tb_ItemID_Prop.Text); + KUtil.SetConfigValue(KConfigure.PART_SYNC_SECTION, syncConfig); + KUtil.ClearConfigSection(KConfigure.PART_SYNC_EPLAN_TO_TC_SECTION); + KUtil.ClearConfigSection(KConfigure.PART_SYNC_TC_TO_EPLAN_SECTION); + //eplan to tc + Dictionary eplan_to_tc = new Dictionary(); + for(int i=0;i< eplan_to_tc_config.Count;i++) { + PartSyncConfigBean bean = eplan_to_tc_config[i]; + eplan_to_tc.Add(bean.to, bean.from); + } + KUtil.SetConfigValue(KConfigure.PART_SYNC_EPLAN_TO_TC_SECTION, eplan_to_tc); + //tc to eplan + Dictionary tc_to_eplan = new Dictionary(); + for(int i = 0; i < tc_to_eplan_config.Count; i++) { + PartSyncConfigBean bean = tc_to_eplan_config[i]; + tc_to_eplan.Add(bean.to, bean.from); + } + KUtil.SetConfigValue(KConfigure.PART_SYNC_TC_TO_EPLAN_SECTION, tc_to_eplan); + } + + public void LoadConfiguration() { + this.loadedType = KUtil.GetConfigValue(KConfigure.PART_SYNC_SECTION, KConfigure.PART_SYNC_TC_ITEM_TYPE); + tb_ObjectType.Text = this.loadedType; + tb_OrderNr_Prop.Text = KUtil.GetConfigValue(KConfigure.PART_SYNC_SECTION, KConfigure.PART_SYNC_OrderNr_TC); + //tb_ItemID_Prop.Text = KUtil.GetConfigValue(KConfigure.PART_SYNC_SECTION, KConfigure.PART_SYNC_ItemID_EPlan); + //eplan to tc + Dictionary eplan_to_tc = KUtil.GetConfigValue(KConfigure.PART_SYNC_EPLAN_TO_TC_SECTION); + foreach(string key in eplan_to_tc.Keys) { + PartSyncConfigBean bean = new PartSyncConfigBean() { from=eplan_to_tc[key],to = key }; + eplan_to_tc_config.Add(bean); + } + //tc to eplan + Dictionary tc_to_eplan = KUtil.GetConfigValue(KConfigure.PART_SYNC_TC_TO_EPLAN_SECTION); + foreach(string key in tc_to_eplan.Keys) { + PartSyncConfigBean bean = new PartSyncConfigBean() { from = tc_to_eplan[key], to = key }; + tc_to_eplan_config.Add(bean); + } + } + + private void Find_EPlan_Prop_Button_Click(object sender, RoutedEventArgs e) { + Find_EPlan_Props(); + } + + private void Tb_EPlanProp_KeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Return) { + Find_EPlan_Props(); + } + } + + private void Find_TC_PropButton_Click(object sender, RoutedEventArgs e) { + Find_TC_Props(); + } + + private void Tb_TCProp_KeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Return) { + Find_TC_Props(); + } + } + + private void ChangeType_Button_Click(object sender, RoutedEventArgs e) { + try { + ChangeType(); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show("加载数据出错:" + ex.Message); + } + } + + private void Tb_ObjectType_KeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Return) { + try { + ChangeType(); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show("加载数据出错:" + ex.Message); + } + } + } + + private void Cb_Location_SelectionChanged(object sender, SelectionChangedEventArgs e) { + Find_TC_Props(); + } + + private void PropTable_SelectionChanged(object sender, SelectionChangedEventArgs e) { + Read_Prop_Refection_to_Textbox(); + } + + private void EPLAN_TO_TC_ADD_Button_Click(object sender, RoutedEventArgs e) { + Add_Config(table_EPLAN_TO_TC, eplan_to_tc_config, tb_EPLAN_TO_TC_eplan.Text, tb_EPLAN_TO_TC_tc.Text); + } + + private void TC_TO_EPLAN_ADD_Button_Click(object sender, RoutedEventArgs e) { + Add_Config(table_TC_TO_EPLAN, tc_to_eplan_config, tb_TC_TO_EPLAN_tc.Text, tb_TC_TO_EPLAN_eplan.Text); + } + + private void EPLAN_TO_TC_REMOVE_Button_Click(object sender, RoutedEventArgs e) { + Remove_Config(table_EPLAN_TO_TC, eplan_to_tc_config); + } + + private void TC_TO_EPLAN_REMOVE_Button_Click(object sender, RoutedEventArgs e) { + Remove_Config(table_TC_TO_EPLAN, tc_to_eplan_config); + } + + private void EPLAN_TO_TC_MODIFY_Button_Click(object sender, RoutedEventArgs e) { + Modify_Config(table_EPLAN_TO_TC, eplan_to_tc_config, tb_EPLAN_TO_TC_eplan.Text, tb_EPLAN_TO_TC_tc.Text); + } + + private void TC_TO_EPLAN_MODIFY_Button_Click(object sender, RoutedEventArgs e) { + Modify_Config(table_TC_TO_EPLAN, tc_to_eplan_config, tb_TC_TO_EPLAN_tc.Text, tb_TC_TO_EPLAN_eplan.Text); + } + + private void Clear_All_Button_Click(object sender, RoutedEventArgs e) { + MessageBoxResult res = MessageBox.Show("确认清空?", "", MessageBoxButton.YesNo); + if (res != MessageBoxResult.Yes) { + return; + } + ClearPropConfig(); + } + + private void Add_All_Button_Click(object sender, RoutedEventArgs e) { + Add_Config(table_EPLAN_TO_TC, eplan_to_tc_config, tb_EPLAN_TO_TC_eplan.Text, tb_EPLAN_TO_TC_tc.Text); + Add_Config(table_TC_TO_EPLAN, tc_to_eplan_config, tb_TC_TO_EPLAN_tc.Text, tb_TC_TO_EPLAN_eplan.Text); + } + + private void COL_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { + EPlanPropBean eplanBean = table_Eplan_Prop.SelectedItem as EPlanPropBean; + ComboBox cb = e.Source as ComboBox; + if (eplanBean == null||cb==null) { + return; + } + eplanBean.language = cb.SelectedItem as string; + } + } +} diff --git a/KPlan/Forms/Config_ProjSync.xaml b/KPlan/Forms/Config_ProjSync.xaml new file mode 100644 index 0000000..cf59391 --- /dev/null +++ b/KPlan/Forms/Config_ProjSync.xaml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + 其他 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KPlan/Forms/Config_ProjSync.xaml.cs b/KPlan/Forms/Config_ProjSync.xaml.cs new file mode 100644 index 0000000..66675e8 --- /dev/null +++ b/KPlan/Forms/Config_ProjSync.xaml.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using KPlan.Util; +using KPlan.Forms.Bean; +using System.Collections.ObjectModel; + +namespace KPlan.Forms { + /// + /// Interaction logic for Config_ProjSync.xaml + /// + public partial class Config_ProjSync : Grid { + private string loadedType; + private List ePlanPropBeanList = new List(); + private ObservableCollection ePlanPropBeanData = new ObservableCollection(); + private ObservableCollection tcPropBeanData = new ObservableCollection(); + private ObservableCollection eplan_to_tc_config = new ObservableCollection(); + private Dictionary> tcPropMap = new Dictionary>(); + public ObservableCollection language_list = new ObservableCollection(); + + public Config_ProjSync() { + InitializeComponent(); + ReadEplanProperty(); + table_Eplan_Prop.ItemsSource = ePlanPropBeanData; + table_TC_Prop.ItemsSource = tcPropBeanData; + table_EPLAN_TO_TC.ItemsSource = eplan_to_tc_config; + string[] ENUM_LANGUAGES = Enum.GetNames(typeof(Eplan.EplApi.Base.ISOCode.Language)); + Array.Sort(ENUM_LANGUAGES); + foreach (string l in ENUM_LANGUAGES) { + language_list.Add(l); + } + col_language.ItemsSource = language_list; + try { + string itemTypeName = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_TC_ITEM_TYPE); + TCUtil.GetDefinedProperties(itemTypeName); + ReadTcProperty(itemTypeName); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + //MessageBox.Show("加载数据出错:" + ex.Message); + } + } + + + private void ChangeType() { + string newType = tb_ObjectType.Text; + if (KUtil.IsEmpty(newType)) { + MessageBox.Show("请输入对象类型"); + return; + } + if (newType.Equals(loadedType)) { + return; + } + MessageBoxResult res = MessageBox.Show("重新加载对象类型将清空当前映射配置,是否继续?", "", MessageBoxButton.YesNo); + if (res != MessageBoxResult.Yes) { + return; + } + //清空 + ClearPropConfig(); + //加载TC属性 + ReadTcProperty(newType); + loadedType = newType; + } + + private void ReadTcProperty(string itemTypeName) { + tcPropBeanData.Clear(); + cb_Location.Items.Clear(); + cb_Location.Items.Add(""); + this.tcPropMap = TCUtil.GetDefinedProperties(itemTypeName); + foreach (string key in tcPropMap.Keys) { + cb_Location.Items.Add(key); + List list = tcPropMap[key]; + foreach (TCPropBean b in list) { + tcPropBeanData.Add(b); + } + } + } + + private void ReadEplanProperty() { + ePlanPropBeanList.Clear(); + ePlanPropBeanData.Clear(); + Eplan.EplApi.DataModel.AnyPropertyId[] props = Eplan.EplApi.DataModel.Properties.AllProjectPropIDs; + for (int i = 0; i < props.Length; i++) { + Eplan.EplApi.DataModel.AnyPropertyId prop = props[i]; + if (prop.Definition.IsReadOnly) { + continue; + } + EPlanPropBean bean = new EPlanPropBean(prop.Definition.Type.ToString()) { realName = prop.AsProject.ToString(), disName = prop.Definition.Name, type = prop.Definition.Type.ToString() }; + ePlanPropBeanList.Add(bean); + ePlanPropBeanData.Add(bean); + } + } + + private void ClearPropConfig() { + eplan_to_tc_config.Clear(); + } + + private void Remove_Config(DataGrid dataGrid, ObservableCollection data) { + try { + System.Collections.IList selectedItems = dataGrid.SelectedItems; + if (selectedItems == null || selectedItems.Count == 0) { + return; + } + while (selectedItems.Count > 0) { + data.Remove((PartSyncConfigBean)selectedItems[0]); + dataGrid.Items.Refresh(); + } + dataGrid.Items.Refresh(); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show(ex.Message); + } + } + + private void Modify_Config(DataGrid dataGrid, ObservableCollection data, string from, string to) { + if (KUtil.IsEmpty(from) || KUtil.IsEmpty(to)) { + return; + } + PartSyncConfigBean selectedBean = dataGrid.SelectedItem as PartSyncConfigBean; + if (selectedBean == null) { + return; + } + int existInd = data.IndexOf(new PartSyncConfigBean() { from = from, to = to }); + if (existInd >= 0 && !to.Equals(selectedBean.to)) { + MessageBox.Show("已存在属性映射到" + to); + return; + } + //PartSyncConfigBean bean = (PartSyncConfigBean)dataGrid.Items[ind]; + selectedBean.from = from; + selectedBean.to = to; + dataGrid.Items.Refresh(); + dataGrid.SelectedItem = selectedBean; + + } + + private void Add_Config(DataGrid dataGrid, ObservableCollection data, string from, string to) { + if (KUtil.IsEmpty(from) || KUtil.IsEmpty(to)) { + return; + } + PartSyncConfigBean bean = new PartSyncConfigBean() { from = from, to = to }; + if (!data.Contains(bean)) { + data.Add(bean); + } + dataGrid.SelectedItem = bean; + dataGrid.ScrollIntoView(bean); + } + + private void Read_Prop_Refection_to_Textbox() { + EPlanPropBean eplanBean = table_Eplan_Prop.SelectedItem as EPlanPropBean; + TCPropBean tcBean = table_TC_Prop.SelectedItem as TCPropBean; + string eplanConfig = ""; + string tcConfig = ""; + if (eplanBean != null) { + eplanConfig = eplanBean.getConfigValue(); + } + if (tcBean != null) { + tcConfig = tcBean.location + "." + tcBean.realName; + } + tb_EPLAN_TO_TC_eplan.Text = eplanConfig; + tb_EPLAN_TO_TC_tc.Text = tcConfig; + } + + private void Find_TC_Props() { + string text = tb_TCProp.Text; + string type = cb_Location.SelectedItem as string; + tcPropBeanData.Clear(); + if (KUtil.IsEmpty(type) && KUtil.IsEmpty(text)) { + foreach (List list in tcPropMap.Values) { + foreach (TCPropBean b in list) { + tcPropBeanData.Add(b); + } + } + } + else { + text = text.ToLower(); + foreach (List list in tcPropMap.Values) { + foreach (TCPropBean b in list) { + if (KUtil.RegexMatch(b.disName.ToLower(),text) || KUtil.RegexMatch(b.realName.ToLower(), text)) { + //if (b.disName.ToLower().Contains(text) || b.realName.ToLower().Contains(text)) { + if (KUtil.IsEmpty(type) || b.typeName.Equals(type)) { + tcPropBeanData.Add(b); + } + } + } + } + } + } + + private void Find_EPlan_Props() { + string text = tb_EPlanProp.Text; + ePlanPropBeanData.Clear(); + if (KUtil.IsEmpty(text)) { + foreach (EPlanPropBean bean in ePlanPropBeanList) { + ePlanPropBeanData.Add(bean); + } + } + else { + text = text.ToLower(); + foreach (EPlanPropBean bean in ePlanPropBeanList) { + if (KUtil.RegexMatch(bean.disName.ToLower(),text) || KUtil.RegexMatch(bean.realName.ToLower(), text)){ + //if (bean.disName.ToLower().Contains(text) || bean.realName.ToLower().Contains(text)) { + ePlanPropBeanData.Add(bean); + } + } + } + } + + + + public void SaveConfiguration() { + Dictionary syncConfig = new Dictionary(); + syncConfig.Add(KConfigure.PROJ_SYNC_TC_ITEM_TYPE, tb_ObjectType.Text); + // syncConfig.Add(KConfigure.PROJ_SYNC_TEMPLATE_ID, tb_templateid.Text); + syncConfig.Add(KConfigure.PROJ_SYNC_PDF_DSTYPE, tb_pdftype.Text); + syncConfig.Add(KConfigure.PROJ_SYNC_PDF_DSREF, tb_pdfref.Text); + syncConfig.Add(KConfigure.PROJ_SYNC_ZW_DSTYPE, tb_zwtype.Text); + syncConfig.Add(KConfigure.PROJ_SYNC_ZW_DSREF, tb_zwref.Text); + //syncConfig.Add(KConfigure.PROJ_SYNC_ItemID_EPlan, tb_ItemID_Prop.Text); + KUtil.SetConfigValue(KConfigure.PROJ_SYNC_SECTION, syncConfig); + KUtil.ClearConfigSection(KConfigure.PROJ_SYNC_EPLAN_TO_TC_SECTION); + //eplan to tc + Dictionary eplan_to_tc = new Dictionary(); + for (int i = 0; i < eplan_to_tc_config.Count; i++) { + PartSyncConfigBean bean = eplan_to_tc_config[i]; + eplan_to_tc.Add(bean.to, bean.from); + } + KUtil.SetConfigValue(KConfigure.PROJ_SYNC_EPLAN_TO_TC_SECTION, eplan_to_tc); + } + + public void LoadConfiguration() { + this.loadedType = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_TC_ITEM_TYPE); + tb_ObjectType.Text = this.loadedType; + //tb_templateid.Text = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_TEMPLATE_ID); + tb_pdftype.Text = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_PDF_DSTYPE); + tb_pdfref.Text = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_PDF_DSREF); + tb_zwtype.Text = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_ZW_DSTYPE); + tb_zwref.Text = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_ZW_DSREF); + //tb_ItemID_Prop.Text = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_SECTION, KConfigure.PROJ_SYNC_ItemID_EPlan); + //eplan to tc + Dictionary eplan_to_tc = KUtil.GetConfigValue(KConfigure.PROJ_SYNC_EPLAN_TO_TC_SECTION); + foreach (string key in eplan_to_tc.Keys) { + PartSyncConfigBean bean = new PartSyncConfigBean() { from = eplan_to_tc[key], to = key }; + eplan_to_tc_config.Add(bean); + } + } + + private void Find_EPlan_Prop_Button_Click(object sender, RoutedEventArgs e) { + Find_EPlan_Props(); + } + + private void Tb_EPlanProp_KeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Return) { + Find_EPlan_Props(); + } + } + + private void Find_TC_PropButton_Click(object sender, RoutedEventArgs e) { + Find_TC_Props(); + } + + private void Tb_TCProp_KeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Return) { + Find_TC_Props(); + } + } + + private void ChangeType_Button_Click(object sender, RoutedEventArgs e) { + try { + ChangeType(); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show("加载数据出错:" + ex.Message); + } + } + + private void Tb_ObjectType_KeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Return) { + try { + ChangeType(); + } + catch (System.Exception ex) { + KUtil.LogErr(ex); + MessageBox.Show("加载数据出错:" + ex.Message); + } + } + } + + private void Cb_Location_SelectionChanged(object sender, SelectionChangedEventArgs e) { + Find_TC_Props(); + } + + private void PropTable_SelectionChanged(object sender, SelectionChangedEventArgs e) { + Read_Prop_Refection_to_Textbox(); + } + + private void EPLAN_TO_TC_ADD_Button_Click(object sender, RoutedEventArgs e) { + Add_Config(table_EPLAN_TO_TC, eplan_to_tc_config, tb_EPLAN_TO_TC_eplan.Text, tb_EPLAN_TO_TC_tc.Text); + } + + private void EPLAN_TO_TC_REMOVE_Button_Click(object sender, RoutedEventArgs e) { + Remove_Config(table_EPLAN_TO_TC, eplan_to_tc_config); + } + + private void EPLAN_TO_TC_MODIFY_Button_Click(object sender, RoutedEventArgs e) { + Modify_Config(table_EPLAN_TO_TC, eplan_to_tc_config, tb_EPLAN_TO_TC_eplan.Text, tb_EPLAN_TO_TC_tc.Text); + } + + private void Clear_All_Button_Click(object sender, RoutedEventArgs e) { + MessageBoxResult res = MessageBox.Show("确认清空?", "", MessageBoxButton.YesNo); + if (res != MessageBoxResult.Yes) { + return; + } + ClearPropConfig(); + } + + private void COL_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { + EPlanPropBean eplanBean = table_Eplan_Prop.SelectedItem as EPlanPropBean; + ComboBox cb = e.Source as ComboBox; + if (eplanBean == null || cb == null) { + return; + } + eplanBean.language = cb.SelectedItem as string; + } + } +} diff --git a/KPlan/Forms/Configure.xaml b/KPlan/Forms/Configure.xaml new file mode 100644 index 0000000..7185d34 --- /dev/null +++ b/KPlan/Forms/Configure.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 待同步元器件库 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +