From b533627f0aed089ae2dc20e46e2dffe312989d99 Mon Sep 17 00:00:00 2001 From: apeiris Date: Wed, 27 Jan 2021 16:48:10 -0500 Subject: [PATCH 01/22] Deleted redundent class1.cs --- X12UtilsFRM/Class1.cs | 10 ---------- X12UtilsFRM/X12UtilsFRM.csproj | 1 - 2 files changed, 11 deletions(-) delete mode 100644 X12UtilsFRM/Class1.cs diff --git a/X12UtilsFRM/Class1.cs b/X12UtilsFRM/Class1.cs deleted file mode 100644 index 098329a5..00000000 --- a/X12UtilsFRM/Class1.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace X12UtilsFRM { - class Class1 { - } -} diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 2dc7de94..e7c2dad8 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -61,7 +61,6 @@ - Form From 297fdb189c20b3027e0cc9222b4fd2af69e6c782 Mon Sep 17 00:00:00 2001 From: anthony peiris Date: Mon, 3 Oct 2022 10:10:50 -0400 Subject: [PATCH 02/22] recreating local --- src/X12.Hipaa.ClaimParser/Program.cs | 2 -- src/X12.ImportX12/App.config | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/X12.Hipaa.ClaimParser/Program.cs b/src/X12.Hipaa.ClaimParser/Program.cs index 4da02ab0..f61f77cf 100644 --- a/src/X12.Hipaa.ClaimParser/Program.cs +++ b/src/X12.Hipaa.ClaimParser/Program.cs @@ -7,8 +7,6 @@ using System.Linq; using System.Xml; - using Fonet; - using X12.Hipaa.Claims.Services; using X12.Parsing; diff --git a/src/X12.ImportX12/App.config b/src/X12.ImportX12/App.config index 934eb855..01587923 100644 --- a/src/X12.ImportX12/App.config +++ b/src/X12.ImportX12/App.config @@ -20,7 +20,8 @@ - + + From 214d18c94b72554ada36641430550ef79ce1d483 Mon Sep 17 00:00:00 2001 From: anthony peiris Date: Tue, 20 Dec 2022 20:15:17 -0500 Subject: [PATCH 03/22] Added HIPPA parsing and PDF generator to test UI --- X12UtilsFRM/App.config | 2 +- X12UtilsFRM/Properties/Settings.Designer.cs | 4 +- X12UtilsFRM/Properties/Settings.settings | 2 +- X12UtilsFRM/X12UtilsFRM.Designer.cs | 175 +++++++++++------ X12UtilsFRM/X12UtilsFRM.cs | 177 +++++++++++++----- X12UtilsFRM/X12UtilsFRM.csproj | 11 ++ X12UtilsFRM/X12UtilsFRM.resx | 10 +- src/X12.Hipaa.ClaimParser/Program.cs | 1 + src/X12.ImportX12/App.config | 1 - .../Claims/ClaimFormTester.cs | 11 +- .../TestData/InstitutionalClaim4010.txt | 12 +- 11 files changed, 280 insertions(+), 126 deletions(-) diff --git a/X12UtilsFRM/App.config b/X12UtilsFRM/App.config index 0e32d12e..83136c94 100644 --- a/X12UtilsFRM/App.config +++ b/X12UtilsFRM/App.config @@ -23,7 +23,7 @@ HTML - C:\Users\mapei\source\repos\X12Parser\OopFactory.X12.Test + C:\EDI\TestCases diff --git a/X12UtilsFRM/Properties/Settings.Designer.cs b/X12UtilsFRM/Properties/Settings.Designer.cs index ccaa4043..0211504b 100644 --- a/X12UtilsFRM/Properties/Settings.Designer.cs +++ b/X12UtilsFRM/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace X12UtilsFRM.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -73,7 +73,7 @@ public string TransformFormat { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("C:\\Users\\mapei\\source\\repos\\X12Parser\\OopFactory.X12.Test")] + [global::System.Configuration.DefaultSettingValueAttribute("C:\\EDI\\TestCases")] public string X12Folder { get { return ((string)(this["X12Folder"])); diff --git a/X12UtilsFRM/Properties/Settings.settings b/X12UtilsFRM/Properties/Settings.settings index 80e71efa..13c6e680 100644 --- a/X12UtilsFRM/Properties/Settings.settings +++ b/X12UtilsFRM/Properties/Settings.settings @@ -15,7 +15,7 @@ HTML - C:\Users\mapei\source\repos\X12Parser\OopFactory.X12.Test + C:\EDI\TestCases diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 5436e4e1..87ae470f 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -29,6 +29,9 @@ private void InitializeComponent() { this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.btnHippaParse = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.btnParse = new System.Windows.Forms.Button(); this.lblInterchangeCount = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.lblSelectedFile = new System.Windows.Forms.Label(); @@ -38,11 +41,10 @@ private void InitializeComponent() { this.rbXml = new System.Windows.Forms.RadioButton(); this.btnAddFiles = new System.Windows.Forms.Button(); this.lbxFileList = new System.Windows.Forms.ListBox(); - this.browser = new System.Windows.Forms.TabPage(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); - this.btnParse = new System.Windows.Forms.Button(); + this.browser = new System.Windows.Forms.TabPage(); this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -56,9 +58,10 @@ private void InitializeComponent() { // statusStrip1 // this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.statusStrip1.Location = new System.Drawing.Point(0, 676); + this.statusStrip1.Location = new System.Drawing.Point(0, 545); this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(1731, 22); + this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); + this.statusStrip1.Size = new System.Drawing.Size(1298, 22); this.statusStrip1.TabIndex = 0; this.statusStrip1.Text = "statusStrip1"; // @@ -68,18 +71,20 @@ private void InitializeComponent() { this.tabControl1.Controls.Add(this.browser); this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Margin = new System.Windows.Forms.Padding(2); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1731, 676); + this.tabControl1.Size = new System.Drawing.Size(1298, 545); this.tabControl1.TabIndex = 1; // // parse // this.parse.Controls.Add(this.splitContainer1); - this.parse.Location = new System.Drawing.Point(4, 25); + this.parse.Location = new System.Drawing.Point(4, 22); + this.parse.Margin = new System.Windows.Forms.Padding(2); this.parse.Name = "parse"; - this.parse.Padding = new System.Windows.Forms.Padding(3); - this.parse.Size = new System.Drawing.Size(1723, 647); + this.parse.Padding = new System.Windows.Forms.Padding(2); + this.parse.Size = new System.Drawing.Size(1290, 519); this.parse.TabIndex = 0; this.parse.Text = "Parse"; this.parse.UseVisualStyleBackColor = true; @@ -87,11 +92,14 @@ private void InitializeComponent() { // splitContainer1 // this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(3, 3); + this.splitContainer1.Location = new System.Drawing.Point(2, 2); + this.splitContainer1.Margin = new System.Windows.Forms.Padding(2); this.splitContainer1.Name = "splitContainer1"; // // splitContainer1.Panel1 // + this.splitContainer1.Panel1.Controls.Add(this.btnHippaParse); + this.splitContainer1.Panel1.Controls.Add(this.button1); this.splitContainer1.Panel1.Controls.Add(this.btnParse); this.splitContainer1.Panel1.Controls.Add(this.lblInterchangeCount); this.splitContainer1.Panel1.Controls.Add(this.label3); @@ -104,18 +112,61 @@ private void InitializeComponent() { // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); - this.splitContainer1.Size = new System.Drawing.Size(1717, 641); - this.splitContainer1.SplitterDistance = 487; + this.splitContainer1.Size = new System.Drawing.Size(1286, 515); + this.splitContainer1.SplitterDistance = 364; + this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // + // btnHippaParse + // + this.btnHippaParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnHippaParse.Location = new System.Drawing.Point(19, 438); + this.btnHippaParse.Margin = new System.Windows.Forms.Padding(2); + this.btnHippaParse.Name = "btnHippaParse"; + this.btnHippaParse.Size = new System.Drawing.Size(161, 34); + this.btnHippaParse.TabIndex = 9; + this.btnHippaParse.Text = "Parse Hippa"; + this.btnHippaParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnHippaParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnHippaParse.UseVisualStyleBackColor = true; + this.btnHippaParse.Click += new System.EventHandler(this.btnHippaParse_Click); + // + // button1 + // + this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button1.Location = new System.Drawing.Point(15, 345); + this.button1.Margin = new System.Windows.Forms.Padding(2); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(182, 34); + this.button1.TabIndex = 8; + this.button1.Text = "Any Xml to HTML"; + this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.button1.UseVisualStyleBackColor = true; + // + // btnParse + // + this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnParse.Location = new System.Drawing.Point(210, 295); + this.btnParse.Margin = new System.Windows.Forms.Padding(2); + this.btnParse.Name = "btnParse"; + this.btnParse.Size = new System.Drawing.Size(122, 25); + this.btnParse.TabIndex = 7; + this.btnParse.Text = "<< Parse"; + this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnParse.UseVisualStyleBackColor = true; + this.btnParse.Click += new System.EventHandler(this.btnParse_Click); + // // lblInterchangeCount // this.lblInterchangeCount.AutoSize = true; this.lblInterchangeCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lblInterchangeCount.ForeColor = System.Drawing.Color.Red; - this.lblInterchangeCount.Location = new System.Drawing.Point(149, 105); + this.lblInterchangeCount.Location = new System.Drawing.Point(112, 85); + this.lblInterchangeCount.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.lblInterchangeCount.Name = "lblInterchangeCount"; - this.lblInterchangeCount.Size = new System.Drawing.Size(24, 25); + this.lblInterchangeCount.Size = new System.Drawing.Size(19, 20); this.lblInterchangeCount.TabIndex = 6; this.lblInterchangeCount.Text = "0"; this.lblInterchangeCount.TextChanged += new System.EventHandler(this.lblInterchangeCount_TextChanged); @@ -124,9 +175,10 @@ private void InitializeComponent() { // this.label3.AutoSize = true; this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label3.Location = new System.Drawing.Point(6, 105); + this.label3.Location = new System.Drawing.Point(4, 85); + this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(137, 25); + this.label3.Size = new System.Drawing.Size(115, 20); this.label3.TabIndex = 5; this.label3.Text = "Interchanges"; // @@ -135,18 +187,20 @@ private void InitializeComponent() { this.lblSelectedFile.AutoSize = true; this.lblSelectedFile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lblSelectedFile.ForeColor = System.Drawing.Color.Red; - this.lblSelectedFile.Location = new System.Drawing.Point(109, 80); + this.lblSelectedFile.Location = new System.Drawing.Point(82, 65); + this.lblSelectedFile.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.lblSelectedFile.Name = "lblSelectedFile"; - this.lblSelectedFile.Size = new System.Drawing.Size(0, 25); + this.lblSelectedFile.Size = new System.Drawing.Size(0, 20); this.lblSelectedFile.TabIndex = 4; // // label1 // this.label1.AutoSize = true; this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(6, 80); + this.label1.Location = new System.Drawing.Point(4, 65); + this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(97, 25); + this.label1.Size = new System.Drawing.Size(80, 20); this.label1.TabIndex = 3; this.label1.Text = "Selected"; // @@ -155,9 +209,11 @@ private void InitializeComponent() { this.groupBox1.Controls.Add(this.rbHtml); this.groupBox1.Controls.Add(this.rbXml); this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.groupBox1.Location = new System.Drawing.Point(20, 335); + this.groupBox1.Location = new System.Drawing.Point(15, 272); + this.groupBox1.Margin = new System.Windows.Forms.Padding(2); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(243, 65); + this.groupBox1.Padding = new System.Windows.Forms.Padding(2); + this.groupBox1.Size = new System.Drawing.Size(182, 53); this.groupBox1.TabIndex = 2; this.groupBox1.TabStop = false; this.groupBox1.Text = "Transform.."; @@ -166,9 +222,10 @@ private void InitializeComponent() { // this.rbHtml.AutoSize = true; this.rbHtml.Checked = true; - this.rbHtml.Location = new System.Drawing.Point(90, 29); + this.rbHtml.Location = new System.Drawing.Point(68, 24); + this.rbHtml.Margin = new System.Windows.Forms.Padding(2); this.rbHtml.Name = "rbHtml"; - this.rbHtml.Size = new System.Drawing.Size(92, 29); + this.rbHtml.Size = new System.Drawing.Size(74, 24); this.rbHtml.TabIndex = 1; this.rbHtml.TabStop = true; this.rbHtml.Text = "HTML"; @@ -178,9 +235,10 @@ private void InitializeComponent() { // rbXml // this.rbXml.AutoSize = true; - this.rbXml.Location = new System.Drawing.Point(6, 29); + this.rbXml.Location = new System.Drawing.Point(4, 24); + this.rbXml.Margin = new System.Windows.Forms.Padding(2); this.rbXml.Name = "rbXml"; - this.rbXml.Size = new System.Drawing.Size(78, 29); + this.rbXml.Size = new System.Drawing.Size(63, 24); this.rbXml.TabIndex = 0; this.rbXml.TabStop = true; this.rbXml.Text = "XML"; @@ -190,9 +248,10 @@ private void InitializeComponent() { // btnAddFiles // this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnAddFiles.Location = new System.Drawing.Point(5, 37); + this.btnAddFiles.Location = new System.Drawing.Point(4, 30); + this.btnAddFiles.Margin = new System.Windows.Forms.Padding(2); this.btnAddFiles.Name = "btnAddFiles"; - this.btnAddFiles.Size = new System.Drawing.Size(163, 31); + this.btnAddFiles.Size = new System.Drawing.Size(122, 25); this.btnAddFiles.TabIndex = 1; this.btnAddFiles.Text = "Add files.."; this.btnAddFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -203,64 +262,56 @@ private void InitializeComponent() { // lbxFileList // this.lbxFileList.FormattingEnabled = true; - this.lbxFileList.ItemHeight = 16; - this.lbxFileList.Location = new System.Drawing.Point(11, 133); + this.lbxFileList.Location = new System.Drawing.Point(8, 108); + this.lbxFileList.Margin = new System.Windows.Forms.Padding(2); this.lbxFileList.Name = "lbxFileList"; this.lbxFileList.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; - this.lbxFileList.Size = new System.Drawing.Size(473, 196); + this.lbxFileList.Size = new System.Drawing.Size(356, 160); this.lbxFileList.TabIndex = 0; this.lbxFileList.SelectedIndexChanged += new System.EventHandler(this.lbxFileList_SelectedIndexChanged); // - // browser - // - this.browser.Controls.Add(this.webBrowser1); - this.browser.Location = new System.Drawing.Point(4, 25); - this.browser.Name = "browser"; - this.browser.Padding = new System.Windows.Forms.Padding(3); - this.browser.Size = new System.Drawing.Size(1723, 647); - this.browser.TabIndex = 1; - this.browser.Text = "Browser"; - this.browser.UseVisualStyleBackColor = true; - // // rtxInterchangeFile // this.rtxInterchangeFile.Dock = System.Windows.Forms.DockStyle.Fill; this.rtxInterchangeFile.Location = new System.Drawing.Point(0, 0); + this.rtxInterchangeFile.Margin = new System.Windows.Forms.Padding(2); this.rtxInterchangeFile.Name = "rtxInterchangeFile"; - this.rtxInterchangeFile.Size = new System.Drawing.Size(1226, 641); + this.rtxInterchangeFile.Size = new System.Drawing.Size(919, 515); this.rtxInterchangeFile.TabIndex = 0; this.rtxInterchangeFile.Text = ""; // - // btnParse + // browser // - this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnParse.Location = new System.Drawing.Point(296, 362); - this.btnParse.Name = "btnParse"; - this.btnParse.Size = new System.Drawing.Size(163, 31); - this.btnParse.TabIndex = 7; - this.btnParse.Text = "<< Parse"; - this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnParse.UseVisualStyleBackColor = true; - this.btnParse.Click += new System.EventHandler(this.btnParse_Click); + this.browser.Controls.Add(this.webBrowser1); + this.browser.Location = new System.Drawing.Point(4, 22); + this.browser.Margin = new System.Windows.Forms.Padding(2); + this.browser.Name = "browser"; + this.browser.Padding = new System.Windows.Forms.Padding(2); + this.browser.Size = new System.Drawing.Size(1290, 519); + this.browser.TabIndex = 1; + this.browser.Text = "Browser"; + this.browser.UseVisualStyleBackColor = true; // // webBrowser1 // + this.webBrowser1.AllowWebBrowserDrop = false; this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; - this.webBrowser1.Location = new System.Drawing.Point(3, 3); - this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); + this.webBrowser1.Location = new System.Drawing.Point(2, 2); + this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); + this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(1717, 641); + this.webBrowser1.Size = new System.Drawing.Size(1286, 515); this.webBrowser1.TabIndex = 0; // - // Form1 + // X12UtilsFRM // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1731, 698); + this.ClientSize = new System.Drawing.Size(1298, 567); this.Controls.Add(this.tabControl1); this.Controls.Add(this.statusStrip1); - this.Name = "Form1"; + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "X12UtilsFRM"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.tabControl1.ResumeLayout(false); @@ -298,6 +349,8 @@ private void InitializeComponent() { private System.Windows.Forms.RichTextBox rtxInterchangeFile; private System.Windows.Forms.Button btnParse; private System.Windows.Forms.WebBrowser webBrowser1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button btnHippaParse; } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 8a3d3382..3fbfe444 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -13,27 +13,41 @@ using System.Diagnostics; using X12.Transformations; using X12.Parsing; - -namespace X12UtilsFRM { - public enum enmTabPages { +using X12.Hipaa.Claims; +using X12.Hipaa.Claims.Services; +using System.Reflection; +using System.Xml; + +namespace X12UtilsFRM +{ + public enum enmTabPages + { parse, browser } - public partial class X12UtilsFRM : Form { + public partial class X12UtilsFRM : Form + { List interchanges = null; ToolTip tt = null; - static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") { + + private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; + + static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") + { Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); Trace.Flush(); } - public string X12Tohtml(string x12) { + public string X12Tohtml(string x12) + { var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); return htmlService.Transform(x12); } - public string X12ToXml(string x12) { - using (MemoryStream memStream = new MemoryStream(1000)) { + public string X12ToXml(string x12) + { + using (MemoryStream memStream = new MemoryStream(1000)) + { interchanges.First().Serialize(memStream); memStream.Seek(0, 0); StreamReader sr = new StreamReader(memStream); @@ -41,15 +55,18 @@ public string X12ToXml(string x12) { } } - public X12UtilsFRM() { + public X12UtilsFRM() + { InitializeComponent(); } - private void Form1_Load(object sender, EventArgs e) { + private void Form1_Load(object sender, EventArgs e) + { rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; tt = new ToolTip(); tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder} to the Listbox below.."); - if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) { + if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) + { btnAddFiles_Click(null, null); } @@ -57,46 +74,64 @@ private void Form1_Load(object sender, EventArgs e) { btnParse.Enabled = false; } - private void DisplayHtml(string html) { + private void DisplayHtml(string html) + { webBrowser1.Navigate("about:blank"); webBrowser1.AllowWebBrowserDrop = false; webBrowser1.AllowNavigation = false; - try { - if (webBrowser1.Document != null) { + try + { + if (webBrowser1.Document != null) + { webBrowser1.Document.Write(string.Empty); } - } catch (Exception e) { + } + catch (Exception e) + { } webBrowser1.DocumentText = html; webBrowser1.AllowNavigation = true; } + private void displayPdf(string file) + { + webBrowser1.AllowNavigation = true; + + if(this.webBrowser1.Document!=null) + { + this.webBrowser1.Navigate(file); + } + } - - private void rbXml_CheckedChanged(object sender, EventArgs e) { + private void rbXml_CheckedChanged(object sender, EventArgs e) + { RadioButton r = (RadioButton)sender; Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); Properties.Settings.Default.Save(); } - private void rbHtml_CheckedChanged(object sender, EventArgs e) { + private void rbHtml_CheckedChanged(object sender, EventArgs e) + { RadioButton r = (RadioButton)sender; Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); Properties.Settings.Default.Save(); } - private void btnAddFiles_Click(object sender, EventArgs e) { - //OpenFileDialog fd = new OpenFileDialog(); - //fd.InitialDirectory = Properties.Settings.Default.X12Folder; - //fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; - //fd.FilterIndex = 0; + private void btnAddFiles_Click(object sender, EventArgs e) + { + OpenFileDialog fd = new OpenFileDialog(); + fd.InitialDirectory = Properties.Settings.Default.X12Folder; + fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; + fd.FilterIndex = 0; + lbxFileList.Items.Clear(); lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); + lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); string[] ss = new string[lbxFileList.Items.Count]; lbxFileList.Items.CopyTo(ss, 0); Properties.Settings.Default.fileList = String.Join(",", ss); @@ -106,27 +141,33 @@ private void btnAddFiles_Click(object sender, EventArgs e) { } - public string ContentFromFile(string filename/*fullPath*/) { - using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) { + public string ContentFromFile(string filename/*fullPath*/) + { + using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) + { return new StreamReader(filename).ReadToEnd(); } } - private Encoding GetEncoding(string fname) { + private Encoding GetEncoding(string fname) + { byte[] header = new byte[6]; - using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) { + using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) + { fs.Read(header, 0, 6);// peak 6 characters to detemind encoding fs.Close(); } return (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; } - public string ReadFromStream(Stream strm) { + public string ReadFromStream(Stream strm) + { // Log(strm.Position.ToString()); using (StreamReader sr = new StreamReader(strm)) return sr.ReadToEnd(); } - private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) { + private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) + { string fileName = ((ListBox)sender).Text; tt.SetToolTip(lbxFileList, fileName + " is Selected now.."); @@ -140,39 +181,85 @@ private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) { rtxInterchangeFile.Text = ContentFromFile(fileName); X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); - parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); - - interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); - lblInterchangeCount.Text = interchanges.Count.ToString(); - + + parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); + interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); + lblInterchangeCount.Text = interchanges.Count.ToString(); + + } private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args)// => throw new NotImplementedException(); - { + { Log($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); } - private void lblInterchangeCount_TextChanged(object sender, EventArgs e) { + private void lblInterchangeCount_TextChanged(object sender, EventArgs e) + { int fcount = int.Parse(((Label)sender).Text); btnParse.Enabled = fcount == 1 ? true : false; } - private void btnParse_Click(object sender, EventArgs e) { + private void btnParse_Click(object sender, EventArgs e) + { string x = ""; - switch (Properties.Settings.Default.TransformFormat) { - - case "HTML": - x = X12Tohtml(rtxInterchangeFile.Text); - break; - case "XML": - x = X12ToXml(rtxInterchangeFile.Text); - break; + switch (Properties.Settings.Default.TransformFormat) + { + + case "HTML": + x = X12Tohtml(rtxInterchangeFile.Text); + break; + case "XML": + x = X12ToXml(rtxInterchangeFile.Text); + break; } DisplayHtml(x); tabControl1.SelectedIndex = (int)enmTabPages.browser; } + + static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; + + + private void btnHippaParse_Click(object sender, EventArgs e) + { + // C:\Temp is a standard folder for Windows. However, we'll + // want to verify that the \Pdfs folder exists and is empty + + // Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("X12.Hipaa.Tests.Unit.Claims.TestData.ProfessionalClaim1.txt"); + + //Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{lbxFileList.SelectedItem}"); + Stream stream = new FileStream($"{ lbxFileList.SelectedItem }", FileMode.Open, FileAccess.Read); + + // new up a ClaimTransformationService object + var service = new ClaimFormTransformationService( + new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif"), + new InstitutionalClaimToUb04ClaimFormTransformation($"{TestImageDirectory}\\UB04_Red.gif"), + new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif")); + String outfile = $"{lbxFileList.SelectedItem}.pdf"; + if (File.Exists(outfile)) File.Delete(outfile); + using (FileStream pdfoutput = new FileStream(outfile, FileMode.Create, FileAccess.Write)) + { + ClaimDocument document = service.Transform837ToClaimDocument(stream); + + var fonetDocument = new XmlDocument(); + string fonetXml = service.TransformClaimDocumentToFoXml(document); + fonetDocument.LoadXml(fonetXml); + + Fonet.FonetDriver driver = Fonet.FonetDriver.Make(); + driver.CloseOnExit = true; + driver.Render(fonetDocument, pdfoutput); + pdfoutput.Close(); + + + } + string pdfout = $"file:///{outfile}"; + webBrowser1.Navigate(pdfout); + //displayPdf(pdfout); + } + } } + diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index e7c2dad8..35dbf7b8 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -48,6 +48,9 @@ 4 + + ..\..\..\Users\mapei\source\repos\X12.NET\packages\Fonet.1.0\lib\net20\Fonet.dll + @@ -98,6 +101,14 @@ + + {1e3bd8a3-21ea-4b71-8a55-31910211a316} + X12.Hipaa.ClaimParser + + + {203c0f4b-d1f0-4c20-8968-7dbd84f4a815} + X12.Hipaa + {29eeaa38-bfb2-4732-a286-eb91355f9bcd} X12.Parsing diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 8e608ad8..935065a9 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -117,8 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Resources\GeorgiaPacific-856-4010-Specification.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - + + 17, 17 + + + 133, 17 + \ No newline at end of file diff --git a/src/X12.Hipaa.ClaimParser/Program.cs b/src/X12.Hipaa.ClaimParser/Program.cs index f61f77cf..46489adc 100644 --- a/src/X12.Hipaa.ClaimParser/Program.cs +++ b/src/X12.Hipaa.ClaimParser/Program.cs @@ -9,6 +9,7 @@ using X12.Hipaa.Claims.Services; using X12.Parsing; + using Fonet; /// /// Primary driver for the Hippa.ClaimParser diff --git a/src/X12.ImportX12/App.config b/src/X12.ImportX12/App.config index 01587923..6528516c 100644 --- a/src/X12.ImportX12/App.config +++ b/src/X12.ImportX12/App.config @@ -20,7 +20,6 @@ - diff --git a/tests/X12.Hipaa.Tests.Unit/Claims/ClaimFormTester.cs b/tests/X12.Hipaa.Tests.Unit/Claims/ClaimFormTester.cs index 13f2720c..17fc5d17 100644 --- a/tests/X12.Hipaa.Tests.Unit/Claims/ClaimFormTester.cs +++ b/tests/X12.Hipaa.Tests.Unit/Claims/ClaimFormTester.cs @@ -49,15 +49,15 @@ public void X12ToClaimModelTest() // send the x12 stream in to obtain a claim object var document = service.Transform837ToClaimDocument(stream); var hcfaclaim = service.TransformClaimToHcfa1500(document.Claims.First()); - Assert.AreEqual("SMITH, TED", hcfaclaim.Field02_PatientsName); + Assert.AreEqual("Sterling, Joe", hcfaclaim.Field02_PatientsName); Assert.IsFalse(hcfaclaim.Field01_TypeOfCoverageIsMedicare); Assert.IsFalse(hcfaclaim.Field01_TypeOfCoverageIsMedicaid); Assert.IsFalse(hcfaclaim.Field03_PatientsSexFemale); Assert.IsTrue(hcfaclaim.Field03_PatientsSexMale); - Assert.AreEqual("99213", hcfaclaim.Field24_ServiceLines.First().ProcedureCode); - Assert.AreEqual("87070", hcfaclaim.Field24_ServiceLines[1].ProcedureCode); - Assert.AreEqual("99214", hcfaclaim.Field24_ServiceLines[2].ProcedureCode); - Assert.AreEqual("86663", hcfaclaim.Field24_ServiceLines[3].ProcedureCode); + Assert.AreEqual("89313", hcfaclaim.Field24_ServiceLines.First().ProcedureCode); + Assert.AreEqual("77070", hcfaclaim.Field24_ServiceLines[1].ProcedureCode); + Assert.AreEqual("96213", hcfaclaim.Field24_ServiceLines[2].ProcedureCode); + Assert.AreEqual("56663", hcfaclaim.Field24_ServiceLines[3].ProcedureCode); } /// @@ -79,6 +79,7 @@ public void X12ToHcfaPdfTest() var fonetDocument = new XmlDocument(); string fonetXml = service.TransformClaimDocumentToFoXml(document); fonetDocument.LoadXml(fonetXml); + } /// diff --git a/tests/X12.Hipaa.Tests.Unit/Claims/TestData/InstitutionalClaim4010.txt b/tests/X12.Hipaa.Tests.Unit/Claims/TestData/InstitutionalClaim4010.txt index 8f0a961c..0645a8d7 100644 --- a/tests/X12.Hipaa.Tests.Unit/Claims/TestData/InstitutionalClaim4010.txt +++ b/tests/X12.Hipaa.Tests.Unit/Claims/TestData/InstitutionalClaim4010.txt @@ -4,21 +4,21 @@ BHT*0019*00*0123*19960918*0932*CH~ REF*87*004010X096~ NM1*40*2*MEDICARE*****46*00120~ - PER*IC*JANE DOE*TE*9005555555~ - NM1*41*2*JONES HOSPITAL*****46*12345~ + PER*IC*Upwork Joe*TE*9005555555~ + NM1*41*2*Janes HOSPITAL*****46*12345~ HL*1**20*1~ PRV*BI*ZZ*203BA0200N~ - NM1*85*2*JONES HOSPITAL*****XX*330127~ + NM1*85*2*Upwork HOSPITAL*****XX*330127~ PRV*AT*ZZ*363LP0200N~ N3*225 MAIN STREET BARKLEY BUILDING~ - N4*CENTERVILLE*PA*17111~ + N4*Sterling*VA*17111~ REF*G2*987654080~ REF*EI*123456789~ HL*2*1*22*0~ SBR*P*18*******MB~ - NM1*IL*1*DOE*JOHN*T***MI*030005074A~ + NM1*IL*1*UPWORK*JOHN*T***MI*030005074A~ N3*125 CITY AVENUE~ - N4*CENTERVILLE*PA*17111~ + N4*Sterling*VA*17111~ DMG*D8*19261111*M~ NM1*PR*2*MEDICARE B*****PI*00435~ CLM*756048Q*89.93***14:A:1**Y*Y*Y~ From 1659e4a7d412a8c42594e9630a8f1ac6c3f18dcf Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 4 Mar 2024 09:17:11 -0500 Subject: [PATCH 04/22] Framework 4.7.1 port --- X12UtilsFRM/X12UtilsFRM.csproj | 5 +++-- X12UtilsFRM/packages.config | 4 ++++ src/X12.AcknowledgeX12/App.config | 2 +- .../X12.AcknowledgeX12.csproj | 2 +- src/X12.Hipaa.ClaimParser/App.config | 2 +- .../X12.Hipaa.ClaimParser.csproj | 2 +- src/X12.Hipaa/Properties/Resources.Designer.cs | 2 +- src/X12.Hipaa/X12.Hipaa.csproj | 2 +- src/X12.ImportX12/App.config | 2 +- src/X12.ImportX12/X12.ImportX12.csproj | 2 +- .../Properties/Resources.Designer.cs | 2 +- src/X12.Parsing/X12.Parsing.csproj | 3 ++- .../Properties/Resources.Designer.cs | 2 +- src/X12.Shared/X12.Shared.csproj | 3 ++- .../Properties/Resources.Designer.cs | 2 +- .../X12.Specifications.csproj | 3 ++- src/X12.Sql/Properties/Resources.Designer.cs | 2 +- src/X12.Sql/X12.Sql.csproj | 2 +- .../X12.TransformToX12.csproj | 2 +- src/X12.TransformToX12/app.config | 2 +- .../X12.Transformations.csproj | 3 ++- src/X12.UnbundleX12/X12.UnbundleX12.csproj | 2 +- src/X12.UnbundleX12/app.config | 2 +- src/X12.Validation/X12.Validation.csproj | 2 +- .../Properties/Resources.Designer.cs | 2 +- src/X12.X12Parser/X12.X12Parser.csproj | 6 +++++- src/X12.X12Parser/app.config | 18 ++++++++++++++++-- src/X12.X12Parser/packages.config | 1 + .../X12.Hipaa.Tests.Unit.csproj | 2 +- .../X12.Tests.Integration.csproj | 2 +- tests/X12.Tests.Unit/X12.Tests.Unit.csproj | 2 +- .../X12.Validation.Tests.Unit.csproj | 2 +- 32 files changed, 60 insertions(+), 32 deletions(-) create mode 100644 X12UtilsFRM/packages.config diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 35dbf7b8..856eb4b2 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -48,8 +48,8 @@ 4 - - ..\..\..\Users\mapei\source\repos\X12.NET\packages\Fonet.1.0\lib\net20\Fonet.dll + + ..\packages\Fonet.1.0\lib\net20\Fonet.dll @@ -87,6 +87,7 @@ X12UtilsFRM.cs Designer + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/X12UtilsFRM/packages.config b/X12UtilsFRM/packages.config new file mode 100644 index 00000000..7121b5b4 --- /dev/null +++ b/X12UtilsFRM/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/X12.AcknowledgeX12/App.config b/src/X12.AcknowledgeX12/App.config index 63e4aab5..cf52bd13 100644 --- a/src/X12.AcknowledgeX12/App.config +++ b/src/X12.AcknowledgeX12/App.config @@ -8,4 +8,4 @@ - + diff --git a/src/X12.AcknowledgeX12/X12.AcknowledgeX12.csproj b/src/X12.AcknowledgeX12/X12.AcknowledgeX12.csproj index 6e9aa465..77176708 100644 --- a/src/X12.AcknowledgeX12/X12.AcknowledgeX12.csproj +++ b/src/X12.AcknowledgeX12/X12.AcknowledgeX12.csproj @@ -10,7 +10,7 @@ Properties X12.AcknowledgeX12 X12.AcknowledgeX12 - v4.6.1 + v4.7.2 512 diff --git a/src/X12.Hipaa.ClaimParser/App.config b/src/X12.Hipaa.ClaimParser/App.config index 71cd2ba5..93448e65 100644 --- a/src/X12.Hipaa.ClaimParser/App.config +++ b/src/X12.Hipaa.ClaimParser/App.config @@ -5,4 +5,4 @@ - + diff --git a/src/X12.Hipaa.ClaimParser/X12.Hipaa.ClaimParser.csproj b/src/X12.Hipaa.ClaimParser/X12.Hipaa.ClaimParser.csproj index 4c0fb39f..1cf22a14 100644 --- a/src/X12.Hipaa.ClaimParser/X12.Hipaa.ClaimParser.csproj +++ b/src/X12.Hipaa.ClaimParser/X12.Hipaa.ClaimParser.csproj @@ -10,7 +10,7 @@ Properties X12.Hipaa.ClaimParser X12.Hipaa.ClaimParser - v4.6.1 + v4.7.2 512 diff --git a/src/X12.Hipaa/Properties/Resources.Designer.cs b/src/X12.Hipaa/Properties/Resources.Designer.cs index ec077160..5eaf7ec5 100644 --- a/src/X12.Hipaa/Properties/Resources.Designer.cs +++ b/src/X12.Hipaa/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace X12.Hipaa.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/X12.Hipaa/X12.Hipaa.csproj b/src/X12.Hipaa/X12.Hipaa.csproj index 6a46bed0..059ae3b7 100644 --- a/src/X12.Hipaa/X12.Hipaa.csproj +++ b/src/X12.Hipaa/X12.Hipaa.csproj @@ -10,7 +10,7 @@ Properties X12.Hipaa X12.Hipaa - v4.6.1 + v4.7.2 512 %24/x12parser/trunk/src/OopFactory.X12.Hipaa . diff --git a/src/X12.ImportX12/App.config b/src/X12.ImportX12/App.config index 6528516c..f09adf9f 100644 --- a/src/X12.ImportX12/App.config +++ b/src/X12.ImportX12/App.config @@ -31,4 +31,4 @@ - + diff --git a/src/X12.ImportX12/X12.ImportX12.csproj b/src/X12.ImportX12/X12.ImportX12.csproj index dd58772f..3617515b 100644 --- a/src/X12.ImportX12/X12.ImportX12.csproj +++ b/src/X12.ImportX12/X12.ImportX12.csproj @@ -10,7 +10,7 @@ Properties X12.ImportX12 X12.ImportX12 - v4.6.1 + v4.7.2 512 diff --git a/src/X12.Parsing/Properties/Resources.Designer.cs b/src/X12.Parsing/Properties/Resources.Designer.cs index ab29041e..9059b783 100644 --- a/src/X12.Parsing/Properties/Resources.Designer.cs +++ b/src/X12.Parsing/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace X12.Parsing.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/X12.Parsing/X12.Parsing.csproj b/src/X12.Parsing/X12.Parsing.csproj index 18d4957c..7cf2cfdb 100644 --- a/src/X12.Parsing/X12.Parsing.csproj +++ b/src/X12.Parsing/X12.Parsing.csproj @@ -9,8 +9,9 @@ Properties X12.Parsing X12.Parsing - v4.6.1 + v4.7.2 512 + true diff --git a/src/X12.Shared/Properties/Resources.Designer.cs b/src/X12.Shared/Properties/Resources.Designer.cs index 57b3cacb..870ddbef 100644 --- a/src/X12.Shared/Properties/Resources.Designer.cs +++ b/src/X12.Shared/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace X12.Shared.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/X12.Shared/X12.Shared.csproj b/src/X12.Shared/X12.Shared.csproj index 27546544..d08559ed 100644 --- a/src/X12.Shared/X12.Shared.csproj +++ b/src/X12.Shared/X12.Shared.csproj @@ -9,8 +9,9 @@ Properties X12.Shared X12.Shared - v4.6.1 + v4.7.2 512 + true diff --git a/src/X12.Specifications/Properties/Resources.Designer.cs b/src/X12.Specifications/Properties/Resources.Designer.cs index 211bfa7c..4929beaf 100644 --- a/src/X12.Specifications/Properties/Resources.Designer.cs +++ b/src/X12.Specifications/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace X12.Specifications.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/X12.Specifications/X12.Specifications.csproj b/src/X12.Specifications/X12.Specifications.csproj index 34293f00..2e72e852 100644 --- a/src/X12.Specifications/X12.Specifications.csproj +++ b/src/X12.Specifications/X12.Specifications.csproj @@ -9,8 +9,9 @@ Properties X12.Specifications X12.Specifications - v4.6.1 + v4.7.2 512 + true diff --git a/src/X12.Sql/Properties/Resources.Designer.cs b/src/X12.Sql/Properties/Resources.Designer.cs index 0536fdbf..853bbad8 100644 --- a/src/X12.Sql/Properties/Resources.Designer.cs +++ b/src/X12.Sql/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace X12.Sql.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/X12.Sql/X12.Sql.csproj b/src/X12.Sql/X12.Sql.csproj index 6e7c5f0b..d7a033ee 100644 --- a/src/X12.Sql/X12.Sql.csproj +++ b/src/X12.Sql/X12.Sql.csproj @@ -10,7 +10,7 @@ Properties X12.Sql X12.Sql - v4.6.1 + v4.7.2 512 diff --git a/src/X12.TransformToX12/X12.TransformToX12.csproj b/src/X12.TransformToX12/X12.TransformToX12.csproj index d265a4e8..6550ee7c 100644 --- a/src/X12.TransformToX12/X12.TransformToX12.csproj +++ b/src/X12.TransformToX12/X12.TransformToX12.csproj @@ -10,7 +10,7 @@ Properties X12.TransformToX12 TransformToX12 - v4.6.1 + v4.7.2 512 diff --git a/src/X12.TransformToX12/app.config b/src/X12.TransformToX12/app.config index 3dbff35f..312bb3f2 100644 --- a/src/X12.TransformToX12/app.config +++ b/src/X12.TransformToX12/app.config @@ -1,3 +1,3 @@ - + diff --git a/src/X12.Transformations/X12.Transformations.csproj b/src/X12.Transformations/X12.Transformations.csproj index aa1af15c..454caa8f 100644 --- a/src/X12.Transformations/X12.Transformations.csproj +++ b/src/X12.Transformations/X12.Transformations.csproj @@ -9,8 +9,9 @@ Properties X12.Transformations X12.Transformations - v4.6.1 + v4.7.2 512 + true diff --git a/src/X12.UnbundleX12/X12.UnbundleX12.csproj b/src/X12.UnbundleX12/X12.UnbundleX12.csproj index d4705282..6147083a 100644 --- a/src/X12.UnbundleX12/X12.UnbundleX12.csproj +++ b/src/X12.UnbundleX12/X12.UnbundleX12.csproj @@ -10,7 +10,7 @@ Properties X12.UnbundleX12 UnbundleX12 - v4.6.1 + v4.7.2 512 diff --git a/src/X12.UnbundleX12/app.config b/src/X12.UnbundleX12/app.config index 3dbff35f..312bb3f2 100644 --- a/src/X12.UnbundleX12/app.config +++ b/src/X12.UnbundleX12/app.config @@ -1,3 +1,3 @@ - + diff --git a/src/X12.Validation/X12.Validation.csproj b/src/X12.Validation/X12.Validation.csproj index c370cceb..62f91118 100644 --- a/src/X12.Validation/X12.Validation.csproj +++ b/src/X12.Validation/X12.Validation.csproj @@ -10,7 +10,7 @@ Properties X12.Validation X12.Validation - v4.6.1 + v4.7.2 512 SAK SAK diff --git a/src/X12.X12Parser/Properties/Resources.Designer.cs b/src/X12.X12Parser/Properties/Resources.Designer.cs index cc7d6b20..72384fa3 100644 --- a/src/X12.X12Parser/Properties/Resources.Designer.cs +++ b/src/X12.X12Parser/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace X12.X12Parser.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/X12.X12Parser/X12.X12Parser.csproj b/src/X12.X12Parser/X12.X12Parser.csproj index 6c229ebf..ca628ca9 100644 --- a/src/X12.X12Parser/X12.X12Parser.csproj +++ b/src/X12.X12Parser/X12.X12Parser.csproj @@ -10,7 +10,7 @@ Properties X12.X12Parser X12Parser - v4.6.1 + v4.7.2 512 @@ -41,6 +41,9 @@ false + + ..\..\packages\Fonet.1.0\lib\net20\Fonet.dll + @@ -61,6 +64,7 @@ + diff --git a/src/X12.X12Parser/app.config b/src/X12.X12Parser/app.config index f59cc1d2..2d5091a4 100644 --- a/src/X12.X12Parser/app.config +++ b/src/X12.X12Parser/app.config @@ -1,10 +1,24 @@ - + + + - + + + + + + + + + + + + + diff --git a/src/X12.X12Parser/packages.config b/src/X12.X12Parser/packages.config index ab7e0f18..b1ec2543 100644 --- a/src/X12.X12Parser/packages.config +++ b/src/X12.X12Parser/packages.config @@ -1,5 +1,6 @@  + diff --git a/tests/X12.Hipaa.Tests.Unit/X12.Hipaa.Tests.Unit.csproj b/tests/X12.Hipaa.Tests.Unit/X12.Hipaa.Tests.Unit.csproj index 282a9b87..c614b107 100644 --- a/tests/X12.Hipaa.Tests.Unit/X12.Hipaa.Tests.Unit.csproj +++ b/tests/X12.Hipaa.Tests.Unit/X12.Hipaa.Tests.Unit.csproj @@ -13,7 +13,7 @@ Properties X12.Hipaa.Tests.Unit X12.Hipaa.Tests.Unit - v4.6.1 + v4.8 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} SAK diff --git a/tests/X12.Tests.Integration/X12.Tests.Integration.csproj b/tests/X12.Tests.Integration/X12.Tests.Integration.csproj index a6589750..8dd3f776 100644 --- a/tests/X12.Tests.Integration/X12.Tests.Integration.csproj +++ b/tests/X12.Tests.Integration/X12.Tests.Integration.csproj @@ -13,7 +13,7 @@ Properties X12.Tests.Integration X12.Tests.Integration - v4.6.1 + v4.8 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} SAK diff --git a/tests/X12.Tests.Unit/X12.Tests.Unit.csproj b/tests/X12.Tests.Unit/X12.Tests.Unit.csproj index b81abea1..9f63ad65 100644 --- a/tests/X12.Tests.Unit/X12.Tests.Unit.csproj +++ b/tests/X12.Tests.Unit/X12.Tests.Unit.csproj @@ -13,7 +13,7 @@ Properties X12.Tests.Unit X12.Tests.Unit - v4.6.1 + v4.8 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} SAK diff --git a/tests/X12.Validation.Tests.Unit/X12.Validation.Tests.Unit.csproj b/tests/X12.Validation.Tests.Unit/X12.Validation.Tests.Unit.csproj index c14539f8..856dd641 100644 --- a/tests/X12.Validation.Tests.Unit/X12.Validation.Tests.Unit.csproj +++ b/tests/X12.Validation.Tests.Unit/X12.Validation.Tests.Unit.csproj @@ -13,7 +13,7 @@ Properties X12.Validation.Tests.Unit X12.Validation.Tests.Unit - v4.6.1 + v4.8 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} SAK From e22bbdf789349eca8021f4f59659283fd77652c2 Mon Sep 17 00:00:00 2001 From: apeiris Date: Wed, 10 Sep 2025 11:37:44 -0400 Subject: [PATCH 05/22] refactor(X12UtilsFRM): apply consistent brace style and improve error handling in PDF export - Converted namespace, class, and method declarations to single-line brace style - Simplified formatting for readability and consistency - Improved error handling in btnHippaParse_Click: - Added try/catch around file delete with user-friendly MessageBox - Removed redundant whitespace and streamlined method bodies --- X12UtilsFRM/X12UtilsFRM.cs | 460 +++++++++++++++++-------------------- 1 file changed, 216 insertions(+), 244 deletions(-) diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 3fbfe444..06688a5b 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -18,248 +18,220 @@ using System.Reflection; using System.Xml; -namespace X12UtilsFRM -{ - public enum enmTabPages - { - parse, - browser - } - public partial class X12UtilsFRM : Form - { - List interchanges = null; - ToolTip tt = null; - - private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; - - static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") - { - - Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); - Trace.Flush(); - } - - public string X12Tohtml(string x12) - { - var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); - return htmlService.Transform(x12); - } - public string X12ToXml(string x12) - { - using (MemoryStream memStream = new MemoryStream(1000)) - { - interchanges.First().Serialize(memStream); - memStream.Seek(0, 0); - StreamReader sr = new StreamReader(memStream); - return sr.ReadToEnd(); - } - } - - public X12UtilsFRM() - { - InitializeComponent(); - } - - private void Form1_Load(object sender, EventArgs e) - { - rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; - tt = new ToolTip(); - tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder} to the Listbox below.."); - if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) - { - btnAddFiles_Click(null, null); - - } - lbxFileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); - btnParse.Enabled = false; - } - - private void DisplayHtml(string html) - { - - webBrowser1.Navigate("about:blank"); - webBrowser1.AllowWebBrowserDrop = false; - webBrowser1.AllowNavigation = false; - - try - { - if (webBrowser1.Document != null) - { - webBrowser1.Document.Write(string.Empty); - } - } - catch (Exception e) - { - - } - webBrowser1.DocumentText = html; - webBrowser1.AllowNavigation = true; - } - - private void displayPdf(string file) - { - webBrowser1.AllowNavigation = true; - - if(this.webBrowser1.Document!=null) - { - this.webBrowser1.Navigate(file); - } - } - - private void rbXml_CheckedChanged(object sender, EventArgs e) - { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - - private void rbHtml_CheckedChanged(object sender, EventArgs e) - { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - - private void btnAddFiles_Click(object sender, EventArgs e) - { - OpenFileDialog fd = new OpenFileDialog(); - fd.InitialDirectory = Properties.Settings.Default.X12Folder; - fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; - fd.FilterIndex = 0; - - lbxFileList.Items.Clear(); - lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); - lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); - string[] ss = new string[lbxFileList.Items.Count]; - lbxFileList.Items.CopyTo(ss, 0); - Properties.Settings.Default.fileList = String.Join(",", ss); - Properties.Settings.Default.Save(); - - - - - } - public string ContentFromFile(string filename/*fullPath*/) - { - using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) - { - return new StreamReader(filename).ReadToEnd(); - } - } - private Encoding GetEncoding(string fname) - { - byte[] header = new byte[6]; - using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) - { - fs.Read(header, 0, 6);// peak 6 characters to detemind encoding - fs.Close(); - } - return (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; - } - public string ReadFromStream(Stream strm) - { - - // Log(strm.Position.ToString()); - - using (StreamReader sr = new StreamReader(strm)) - return sr.ReadToEnd(); - } - private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) - { - string fileName = ((ListBox)sender).Text; - tt.SetToolTip(lbxFileList, fileName + " is Selected now.."); - - - lblSelectedFile.Text = Path.GetFileName(fileName); - Log($"fileName={fileName}"); - if (String.IsNullOrEmpty(fileName)) return;// can not parse empty file - - - bool throwException = Properties.Settings.Default.throwExceptions; - rtxInterchangeFile.Text = ContentFromFile(fileName); - - X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); - - parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); - - interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); - lblInterchangeCount.Text = interchanges.Count.ToString(); - - - - } - - private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args)// => throw new NotImplementedException(); - { - Log($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); - } - - private void lblInterchangeCount_TextChanged(object sender, EventArgs e) - { - int fcount = int.Parse(((Label)sender).Text); - btnParse.Enabled = fcount == 1 ? true : false; - } - - private void btnParse_Click(object sender, EventArgs e) - { - string x = ""; - switch (Properties.Settings.Default.TransformFormat) - { - - case "HTML": - x = X12Tohtml(rtxInterchangeFile.Text); - break; - case "XML": - x = X12ToXml(rtxInterchangeFile.Text); - break; - } - DisplayHtml(x); - tabControl1.SelectedIndex = (int)enmTabPages.browser; - - } - - static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; - - - private void btnHippaParse_Click(object sender, EventArgs e) - { - // C:\Temp is a standard folder for Windows. However, we'll - // want to verify that the \Pdfs folder exists and is empty - - // Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("X12.Hipaa.Tests.Unit.Claims.TestData.ProfessionalClaim1.txt"); - - //Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{lbxFileList.SelectedItem}"); - Stream stream = new FileStream($"{ lbxFileList.SelectedItem }", FileMode.Open, FileAccess.Read); - - // new up a ClaimTransformationService object - var service = new ClaimFormTransformationService( - new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif"), - new InstitutionalClaimToUb04ClaimFormTransformation($"{TestImageDirectory}\\UB04_Red.gif"), - new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif")); - String outfile = $"{lbxFileList.SelectedItem}.pdf"; - if (File.Exists(outfile)) File.Delete(outfile); - using (FileStream pdfoutput = new FileStream(outfile, FileMode.Create, FileAccess.Write)) - { - ClaimDocument document = service.Transform837ToClaimDocument(stream); - - var fonetDocument = new XmlDocument(); - string fonetXml = service.TransformClaimDocumentToFoXml(document); - fonetDocument.LoadXml(fonetXml); - - Fonet.FonetDriver driver = Fonet.FonetDriver.Make(); - driver.CloseOnExit = true; - driver.Render(fonetDocument, pdfoutput); - pdfoutput.Close(); - - - } - string pdfout = $"file:///{outfile}"; - webBrowser1.Navigate(pdfout); - //displayPdf(pdfout); - } - - } -} +namespace X12UtilsFRM { + public enum enmTabPages { + parse, + browser + } + public partial class X12UtilsFRM : Form { + List interchanges = null; + ToolTip tt = null; + + private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; + + static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") { + + Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); + Trace.Flush(); + } + + public string X12Tohtml(string x12) { + var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); + return htmlService.Transform(x12); + } + public string X12ToXml(string x12) { + using (MemoryStream memStream = new MemoryStream(1000)) { + interchanges.First().Serialize(memStream); + memStream.Seek(0, 0); + StreamReader sr = new StreamReader(memStream); + return sr.ReadToEnd(); + } + } + + public X12UtilsFRM() { + InitializeComponent(); + } + + private void Form1_Load(object sender, EventArgs e) { + rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; + tt = new ToolTip(); + tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder} to the Listbox below.."); + if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) { + btnAddFiles_Click(null, null); + + } + lbxFileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); + btnParse.Enabled = false; + } + + private void DisplayHtml(string html) { + + webBrowser1.Navigate("about:blank"); + webBrowser1.AllowWebBrowserDrop = false; + webBrowser1.AllowNavigation = false; + + try { + if (webBrowser1.Document != null) { + webBrowser1.Document.Write(string.Empty); + } + } catch (Exception e) { + + } + webBrowser1.DocumentText = html; + webBrowser1.AllowNavigation = true; + } + + private void displayPdf(string file) { + webBrowser1.AllowNavigation = true; + + if (this.webBrowser1.Document != null) { + this.webBrowser1.Navigate(file); + } + } + + private void rbXml_CheckedChanged(object sender, EventArgs e) { + RadioButton r = (RadioButton)sender; + Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; + Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); + Properties.Settings.Default.Save(); + } + + private void rbHtml_CheckedChanged(object sender, EventArgs e) { + RadioButton r = (RadioButton)sender; + Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; + Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); + Properties.Settings.Default.Save(); + } + + private void btnAddFiles_Click(object sender, EventArgs e) { + OpenFileDialog fd = new OpenFileDialog(); + fd.InitialDirectory = Properties.Settings.Default.X12Folder; + fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; + fd.FilterIndex = 0; + + lbxFileList.Items.Clear(); + lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); + lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); + string[] ss = new string[lbxFileList.Items.Count]; + lbxFileList.Items.CopyTo(ss, 0); + Properties.Settings.Default.fileList = String.Join(",", ss); + Properties.Settings.Default.Save(); + + + + + } + public string ContentFromFile(string filename/*fullPath*/) { + using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) { + return new StreamReader(filename).ReadToEnd(); + } + } + private Encoding GetEncoding(string fname) { + byte[] header = new byte[6]; + using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) { + fs.Read(header, 0, 6);// peak 6 characters to detemind encoding + fs.Close(); + } + return (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; + } + public string ReadFromStream(Stream strm) { + + // Log(strm.Position.ToString()); + + using (StreamReader sr = new StreamReader(strm)) + return sr.ReadToEnd(); + } + private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) { + string fileName = ((ListBox)sender).Text; + tt.SetToolTip(lbxFileList, fileName + " is Selected now.."); + + + lblSelectedFile.Text = Path.GetFileName(fileName); + Log($"fileName={fileName}"); + if (String.IsNullOrEmpty(fileName)) return;// can not parse empty file + + + bool throwException = Properties.Settings.Default.throwExceptions; + rtxInterchangeFile.Text = ContentFromFile(fileName); + + X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); + + parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); + + interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); + lblInterchangeCount.Text = interchanges.Count.ToString(); + + + + } + + private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args)// => throw new NotImplementedException(); + { + Log($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); + } + + private void lblInterchangeCount_TextChanged(object sender, EventArgs e) { + int fcount = int.Parse(((Label)sender).Text); + btnParse.Enabled = fcount == 1 ? true : false; + } + + private void btnParse_Click(object sender, EventArgs e) { + string x = ""; + switch (Properties.Settings.Default.TransformFormat) { + + case "HTML": + x = X12Tohtml(rtxInterchangeFile.Text); + break; + case "XML": + x = X12ToXml(rtxInterchangeFile.Text); + break; + } + DisplayHtml(x); + tabControl1.SelectedIndex = (int)enmTabPages.browser; + + } + + static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; + + + private void btnHippaParse_Click(object sender, EventArgs e) { + // C:\Temp is a standard folder for Windows. However, we'll + // want to verify that the \Pdfs folder exists and is empty + + // Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("X12.Hipaa.Tests.Unit.Claims.TestData.ProfessionalClaim1.txt"); + + //Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{lbxFileList.SelectedItem}"); + Stream stream = new FileStream($"{lbxFileList.SelectedItem}", FileMode.Open, FileAccess.Read); + + // new up a ClaimTransformationService object + var service = new ClaimFormTransformationService( + new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif"), + new InstitutionalClaimToUb04ClaimFormTransformation($"{TestImageDirectory}\\UB04_Red.gif"), + new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif")); + String outfile = $"{lbxFileList.SelectedItem}.pdf"; + try { + if (File.Exists(outfile)) + File.Delete(outfile); + } catch (Exception ex) { + MessageBox.Show($"Error deleting file {outfile}.\n{ex.Message}", "Error Deleting File", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + using (FileStream pdfoutput = new FileStream(outfile, FileMode.Create, FileAccess.Write)) { + ClaimDocument document = service.Transform837ToClaimDocument(stream); + var fonetDocument = new XmlDocument(); + string fonetXml = service.TransformClaimDocumentToFoXml(document); + fonetDocument.LoadXml(fonetXml); + Fonet.FonetDriver driver = Fonet.FonetDriver.Make(); + driver.CloseOnExit = true; + driver.Render(fonetDocument, pdfoutput); + pdfoutput.Close(); + } + string pdfout = $"file:///{outfile}"; + webBrowser1.Navigate(pdfout); + //displayPdf(pdfout); + } + + } + } From ca30ad6ab9558ea268d8c20800548bd85fdca47e Mon Sep 17 00:00:00 2001 From: apeiris Date: Thu, 11 Sep 2025 08:39:41 -0400 Subject: [PATCH 06/22] feat(ui): add logging tab and Find Spec button to X12UtilsFRM - Added new "Find Spec" button with click handler - Introduced RichTextBox log output (`rtLog`) - Added third tab (tabPage1) to TabControl for future extensions - Integrated NLog namespaces in Program.cs - Minor UI layout adjustments --- X12UtilsFRM/NLog.config | 45 ++ X12UtilsFRM/Program.cs | 6 +- X12UtilsFRM/X12UtilsFRM.Designer.cs | 650 +++++++++++++++------------- X12UtilsFRM/X12UtilsFRM.cs | 68 ++- X12UtilsFRM/X12UtilsFRM.csproj | 10 + X12UtilsFRM/X12UtilsFRM.resx | 3 + X12UtilsFRM/packages.config | 2 + 7 files changed, 470 insertions(+), 314 deletions(-) create mode 100644 X12UtilsFRM/NLog.config diff --git a/X12UtilsFRM/NLog.config b/X12UtilsFRM/NLog.config new file mode 100644 index 00000000..b6ffbd19 --- /dev/null +++ b/X12UtilsFRM/NLog.config @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/X12UtilsFRM/Program.cs b/X12UtilsFRM/Program.cs index cfae4a40..75948d8c 100644 --- a/X12UtilsFRM/Program.cs +++ b/X12UtilsFRM/Program.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; +using NLog; +using NLog.Config; namespace X12UtilsFRM { static class Program { @@ -13,7 +15,9 @@ static class Program { static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new X12UtilsFRM()); + + + Application.Run(new X12UtilsFRM()); } } } diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 87ae470f..ef8d227b 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -24,308 +24,346 @@ protected override void Dispose(bool disposing) { /// the contents of this method with the code editor. /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.parse = new System.Windows.Forms.TabPage(); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.btnHippaParse = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.btnParse = new System.Windows.Forms.Button(); - this.lblInterchangeCount = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.lblSelectedFile = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.rbHtml = new System.Windows.Forms.RadioButton(); - this.rbXml = new System.Windows.Forms.RadioButton(); - this.btnAddFiles = new System.Windows.Forms.Button(); - this.lbxFileList = new System.Windows.Forms.ListBox(); - this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); - this.browser = new System.Windows.Forms.TabPage(); - this.webBrowser1 = new System.Windows.Forms.WebBrowser(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.tabControl1.SuspendLayout(); - this.parse.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - this.groupBox1.SuspendLayout(); - this.browser.SuspendLayout(); - this.SuspendLayout(); - // - // statusStrip1 - // - this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.statusStrip1.Location = new System.Drawing.Point(0, 545); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); - this.statusStrip1.Size = new System.Drawing.Size(1298, 22); - this.statusStrip1.TabIndex = 0; - this.statusStrip1.Text = "statusStrip1"; - // - // tabControl1 - // - this.tabControl1.Controls.Add(this.parse); - this.tabControl1.Controls.Add(this.browser); - this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tabControl1.Location = new System.Drawing.Point(0, 0); - this.tabControl1.Margin = new System.Windows.Forms.Padding(2); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1298, 545); - this.tabControl1.TabIndex = 1; - // - // parse - // - this.parse.Controls.Add(this.splitContainer1); - this.parse.Location = new System.Drawing.Point(4, 22); - this.parse.Margin = new System.Windows.Forms.Padding(2); - this.parse.Name = "parse"; - this.parse.Padding = new System.Windows.Forms.Padding(2); - this.parse.Size = new System.Drawing.Size(1290, 519); - this.parse.TabIndex = 0; - this.parse.Text = "Parse"; - this.parse.UseVisualStyleBackColor = true; - // - // splitContainer1 - // - this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(2, 2); - this.splitContainer1.Margin = new System.Windows.Forms.Padding(2); - this.splitContainer1.Name = "splitContainer1"; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.Controls.Add(this.btnHippaParse); - this.splitContainer1.Panel1.Controls.Add(this.button1); - this.splitContainer1.Panel1.Controls.Add(this.btnParse); - this.splitContainer1.Panel1.Controls.Add(this.lblInterchangeCount); - this.splitContainer1.Panel1.Controls.Add(this.label3); - this.splitContainer1.Panel1.Controls.Add(this.lblSelectedFile); - this.splitContainer1.Panel1.Controls.Add(this.label1); - this.splitContainer1.Panel1.Controls.Add(this.groupBox1); - this.splitContainer1.Panel1.Controls.Add(this.btnAddFiles); - this.splitContainer1.Panel1.Controls.Add(this.lbxFileList); - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); - this.splitContainer1.Size = new System.Drawing.Size(1286, 515); - this.splitContainer1.SplitterDistance = 364; - this.splitContainer1.SplitterWidth = 3; - this.splitContainer1.TabIndex = 0; - // - // btnHippaParse - // - this.btnHippaParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnHippaParse.Location = new System.Drawing.Point(19, 438); - this.btnHippaParse.Margin = new System.Windows.Forms.Padding(2); - this.btnHippaParse.Name = "btnHippaParse"; - this.btnHippaParse.Size = new System.Drawing.Size(161, 34); - this.btnHippaParse.TabIndex = 9; - this.btnHippaParse.Text = "Parse Hippa"; - this.btnHippaParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnHippaParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnHippaParse.UseVisualStyleBackColor = true; - this.btnHippaParse.Click += new System.EventHandler(this.btnHippaParse_Click); - // - // button1 - // - this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button1.Location = new System.Drawing.Point(15, 345); - this.button1.Margin = new System.Windows.Forms.Padding(2); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(182, 34); - this.button1.TabIndex = 8; - this.button1.Text = "Any Xml to HTML"; - this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.button1.UseVisualStyleBackColor = true; - // - // btnParse - // - this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnParse.Location = new System.Drawing.Point(210, 295); - this.btnParse.Margin = new System.Windows.Forms.Padding(2); - this.btnParse.Name = "btnParse"; - this.btnParse.Size = new System.Drawing.Size(122, 25); - this.btnParse.TabIndex = 7; - this.btnParse.Text = "<< Parse"; - this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnParse.UseVisualStyleBackColor = true; - this.btnParse.Click += new System.EventHandler(this.btnParse_Click); - // - // lblInterchangeCount - // - this.lblInterchangeCount.AutoSize = true; - this.lblInterchangeCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblInterchangeCount.ForeColor = System.Drawing.Color.Red; - this.lblInterchangeCount.Location = new System.Drawing.Point(112, 85); - this.lblInterchangeCount.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.lblInterchangeCount.Name = "lblInterchangeCount"; - this.lblInterchangeCount.Size = new System.Drawing.Size(19, 20); - this.lblInterchangeCount.TabIndex = 6; - this.lblInterchangeCount.Text = "0"; - this.lblInterchangeCount.TextChanged += new System.EventHandler(this.lblInterchangeCount_TextChanged); - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label3.Location = new System.Drawing.Point(4, 85); - this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(115, 20); - this.label3.TabIndex = 5; - this.label3.Text = "Interchanges"; - // - // lblSelectedFile - // - this.lblSelectedFile.AutoSize = true; - this.lblSelectedFile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblSelectedFile.ForeColor = System.Drawing.Color.Red; - this.lblSelectedFile.Location = new System.Drawing.Point(82, 65); - this.lblSelectedFile.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.lblSelectedFile.Name = "lblSelectedFile"; - this.lblSelectedFile.Size = new System.Drawing.Size(0, 20); - this.lblSelectedFile.TabIndex = 4; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(4, 65); - this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(80, 20); - this.label1.TabIndex = 3; - this.label1.Text = "Selected"; - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.rbHtml); - this.groupBox1.Controls.Add(this.rbXml); - this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.groupBox1.Location = new System.Drawing.Point(15, 272); - this.groupBox1.Margin = new System.Windows.Forms.Padding(2); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(2); - this.groupBox1.Size = new System.Drawing.Size(182, 53); - this.groupBox1.TabIndex = 2; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Transform.."; - // - // rbHtml - // - this.rbHtml.AutoSize = true; - this.rbHtml.Checked = true; - this.rbHtml.Location = new System.Drawing.Point(68, 24); - this.rbHtml.Margin = new System.Windows.Forms.Padding(2); - this.rbHtml.Name = "rbHtml"; - this.rbHtml.Size = new System.Drawing.Size(74, 24); - this.rbHtml.TabIndex = 1; - this.rbHtml.TabStop = true; - this.rbHtml.Text = "HTML"; - this.rbHtml.UseVisualStyleBackColor = true; - this.rbHtml.CheckedChanged += new System.EventHandler(this.rbHtml_CheckedChanged); - // - // rbXml - // - this.rbXml.AutoSize = true; - this.rbXml.Location = new System.Drawing.Point(4, 24); - this.rbXml.Margin = new System.Windows.Forms.Padding(2); - this.rbXml.Name = "rbXml"; - this.rbXml.Size = new System.Drawing.Size(63, 24); - this.rbXml.TabIndex = 0; - this.rbXml.TabStop = true; - this.rbXml.Text = "XML"; - this.rbXml.UseVisualStyleBackColor = true; - this.rbXml.CheckedChanged += new System.EventHandler(this.rbXml_CheckedChanged); - // - // btnAddFiles - // - this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnAddFiles.Location = new System.Drawing.Point(4, 30); - this.btnAddFiles.Margin = new System.Windows.Forms.Padding(2); - this.btnAddFiles.Name = "btnAddFiles"; - this.btnAddFiles.Size = new System.Drawing.Size(122, 25); - this.btnAddFiles.TabIndex = 1; - this.btnAddFiles.Text = "Add files.."; - this.btnAddFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnAddFiles, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnAddFiles.UseVisualStyleBackColor = true; - this.btnAddFiles.Click += new System.EventHandler(this.btnAddFiles_Click); - // - // lbxFileList - // - this.lbxFileList.FormattingEnabled = true; - this.lbxFileList.Location = new System.Drawing.Point(8, 108); - this.lbxFileList.Margin = new System.Windows.Forms.Padding(2); - this.lbxFileList.Name = "lbxFileList"; - this.lbxFileList.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; - this.lbxFileList.Size = new System.Drawing.Size(356, 160); - this.lbxFileList.TabIndex = 0; - this.lbxFileList.SelectedIndexChanged += new System.EventHandler(this.lbxFileList_SelectedIndexChanged); - // - // rtxInterchangeFile - // - this.rtxInterchangeFile.Dock = System.Windows.Forms.DockStyle.Fill; - this.rtxInterchangeFile.Location = new System.Drawing.Point(0, 0); - this.rtxInterchangeFile.Margin = new System.Windows.Forms.Padding(2); - this.rtxInterchangeFile.Name = "rtxInterchangeFile"; - this.rtxInterchangeFile.Size = new System.Drawing.Size(919, 515); - this.rtxInterchangeFile.TabIndex = 0; - this.rtxInterchangeFile.Text = ""; - // - // browser - // - this.browser.Controls.Add(this.webBrowser1); - this.browser.Location = new System.Drawing.Point(4, 22); - this.browser.Margin = new System.Windows.Forms.Padding(2); - this.browser.Name = "browser"; - this.browser.Padding = new System.Windows.Forms.Padding(2); - this.browser.Size = new System.Drawing.Size(1290, 519); - this.browser.TabIndex = 1; - this.browser.Text = "Browser"; - this.browser.UseVisualStyleBackColor = true; - // - // webBrowser1 - // - this.webBrowser1.AllowWebBrowserDrop = false; - this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; - this.webBrowser1.Location = new System.Drawing.Point(2, 2); - this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); - this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); - this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(1286, 515); - this.webBrowser1.TabIndex = 0; - // - // X12UtilsFRM - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1298, 567); - this.Controls.Add(this.tabControl1); - this.Controls.Add(this.statusStrip1); - this.Margin = new System.Windows.Forms.Padding(2); - this.Name = "X12UtilsFRM"; - this.Text = "Form1"; - this.Load += new System.EventHandler(this.Form1_Load); - this.tabControl1.ResumeLayout(false); - this.parse.ResumeLayout(false); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel1.PerformLayout(); - this.splitContainer1.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.browser.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); + this.components = new System.ComponentModel.Container(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.parse = new System.Windows.Forms.TabPage(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.btnFindSpec = new System.Windows.Forms.Button(); + this.btnHippaParse = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.btnParse = new System.Windows.Forms.Button(); + this.lblInterchangeCount = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.lblSelectedFile = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rbHtml = new System.Windows.Forms.RadioButton(); + this.rbXml = new System.Windows.Forms.RadioButton(); + this.btnAddFiles = new System.Windows.Forms.Button(); + this.lbxFileList = new System.Windows.Forms.ListBox(); + this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); + this.browser = new System.Windows.Forms.TabPage(); + this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.rtLog = new System.Windows.Forms.RichTextBox(); + this.tabControl1.SuspendLayout(); + this.parse.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.browser.SuspendLayout(); + this.SuspendLayout(); + // + // statusStrip1 + // + this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.statusStrip1.Location = new System.Drawing.Point(0, 545); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); + this.statusStrip1.Size = new System.Drawing.Size(1298, 22); + this.statusStrip1.TabIndex = 0; + this.statusStrip1.Text = "statusStrip1"; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.parse); + this.tabControl1.Controls.Add(this.browser); + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Margin = new System.Windows.Forms.Padding(2); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(1079, 515); + this.tabControl1.TabIndex = 1; + // + // parse + // + this.parse.Controls.Add(this.splitContainer1); + this.parse.Location = new System.Drawing.Point(4, 22); + this.parse.Margin = new System.Windows.Forms.Padding(2); + this.parse.Name = "parse"; + this.parse.Padding = new System.Windows.Forms.Padding(2); + this.parse.Size = new System.Drawing.Size(1071, 489); + this.parse.TabIndex = 0; + this.parse.Text = "Parse"; + this.parse.UseVisualStyleBackColor = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(2, 2); + this.splitContainer1.Margin = new System.Windows.Forms.Padding(2); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.btnFindSpec); + this.splitContainer1.Panel1.Controls.Add(this.btnHippaParse); + this.splitContainer1.Panel1.Controls.Add(this.button1); + this.splitContainer1.Panel1.Controls.Add(this.btnParse); + this.splitContainer1.Panel1.Controls.Add(this.lblInterchangeCount); + this.splitContainer1.Panel1.Controls.Add(this.label3); + this.splitContainer1.Panel1.Controls.Add(this.lblSelectedFile); + this.splitContainer1.Panel1.Controls.Add(this.label1); + this.splitContainer1.Panel1.Controls.Add(this.groupBox1); + this.splitContainer1.Panel1.Controls.Add(this.btnAddFiles); + this.splitContainer1.Panel1.Controls.Add(this.lbxFileList); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.rtLog); + this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); + this.splitContainer1.Size = new System.Drawing.Size(1067, 485); + this.splitContainer1.SplitterDistance = 302; + this.splitContainer1.SplitterWidth = 3; + this.splitContainer1.TabIndex = 0; + // + // btnFindSpec + // + this.btnFindSpec.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnFindSpec.Location = new System.Drawing.Point(19, 434); + this.btnFindSpec.Margin = new System.Windows.Forms.Padding(2); + this.btnFindSpec.Name = "btnFindSpec"; + this.btnFindSpec.Size = new System.Drawing.Size(161, 34); + this.btnFindSpec.TabIndex = 10; + this.btnFindSpec.Text = "Find Spec"; + this.btnFindSpec.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnFindSpec, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnFindSpec.UseVisualStyleBackColor = true; + this.btnFindSpec.Click += new System.EventHandler(this.btnFindSpec_Click); + // + // btnHippaParse + // + this.btnHippaParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnHippaParse.Location = new System.Drawing.Point(19, 383); + this.btnHippaParse.Margin = new System.Windows.Forms.Padding(2); + this.btnHippaParse.Name = "btnHippaParse"; + this.btnHippaParse.Size = new System.Drawing.Size(161, 34); + this.btnHippaParse.TabIndex = 9; + this.btnHippaParse.Text = "Parse Hippa"; + this.btnHippaParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnHippaParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnHippaParse.UseVisualStyleBackColor = true; + this.btnHippaParse.Click += new System.EventHandler(this.btnHippaParse_Click); + // + // button1 + // + this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button1.Location = new System.Drawing.Point(15, 345); + this.button1.Margin = new System.Windows.Forms.Padding(2); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(182, 34); + this.button1.TabIndex = 8; + this.button1.Text = "Any Xml to HTML"; + this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.button1.UseVisualStyleBackColor = true; + // + // btnParse + // + this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnParse.Location = new System.Drawing.Point(210, 295); + this.btnParse.Margin = new System.Windows.Forms.Padding(2); + this.btnParse.Name = "btnParse"; + this.btnParse.Size = new System.Drawing.Size(122, 25); + this.btnParse.TabIndex = 7; + this.btnParse.Text = "<< Parse"; + this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnParse.UseVisualStyleBackColor = true; + this.btnParse.Click += new System.EventHandler(this.btnParse_Click); + // + // lblInterchangeCount + // + this.lblInterchangeCount.AutoSize = true; + this.lblInterchangeCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblInterchangeCount.ForeColor = System.Drawing.Color.Red; + this.lblInterchangeCount.Location = new System.Drawing.Point(112, 85); + this.lblInterchangeCount.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.lblInterchangeCount.Name = "lblInterchangeCount"; + this.lblInterchangeCount.Size = new System.Drawing.Size(19, 20); + this.lblInterchangeCount.TabIndex = 6; + this.lblInterchangeCount.Text = "0"; + this.lblInterchangeCount.TextChanged += new System.EventHandler(this.lblInterchangeCount_TextChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(4, 85); + this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(115, 20); + this.label3.TabIndex = 5; + this.label3.Text = "Interchanges"; + // + // lblSelectedFile + // + this.lblSelectedFile.AutoSize = true; + this.lblSelectedFile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblSelectedFile.ForeColor = System.Drawing.Color.Red; + this.lblSelectedFile.Location = new System.Drawing.Point(82, 65); + this.lblSelectedFile.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.lblSelectedFile.Name = "lblSelectedFile"; + this.lblSelectedFile.Size = new System.Drawing.Size(0, 20); + this.lblSelectedFile.TabIndex = 4; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(4, 65); + this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(80, 20); + this.label1.TabIndex = 3; + this.label1.Text = "Selected"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rbHtml); + this.groupBox1.Controls.Add(this.rbXml); + this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.groupBox1.Location = new System.Drawing.Point(15, 272); + this.groupBox1.Margin = new System.Windows.Forms.Padding(2); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Padding = new System.Windows.Forms.Padding(2); + this.groupBox1.Size = new System.Drawing.Size(182, 53); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Transform.."; + // + // rbHtml + // + this.rbHtml.AutoSize = true; + this.rbHtml.Checked = true; + this.rbHtml.Location = new System.Drawing.Point(68, 24); + this.rbHtml.Margin = new System.Windows.Forms.Padding(2); + this.rbHtml.Name = "rbHtml"; + this.rbHtml.Size = new System.Drawing.Size(74, 24); + this.rbHtml.TabIndex = 1; + this.rbHtml.TabStop = true; + this.rbHtml.Text = "HTML"; + this.rbHtml.UseVisualStyleBackColor = true; + this.rbHtml.CheckedChanged += new System.EventHandler(this.rbHtml_CheckedChanged); + // + // rbXml + // + this.rbXml.AutoSize = true; + this.rbXml.Location = new System.Drawing.Point(4, 24); + this.rbXml.Margin = new System.Windows.Forms.Padding(2); + this.rbXml.Name = "rbXml"; + this.rbXml.Size = new System.Drawing.Size(63, 24); + this.rbXml.TabIndex = 0; + this.rbXml.TabStop = true; + this.rbXml.Text = "XML"; + this.rbXml.UseVisualStyleBackColor = true; + this.rbXml.CheckedChanged += new System.EventHandler(this.rbXml_CheckedChanged); + // + // btnAddFiles + // + this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnAddFiles.Location = new System.Drawing.Point(4, 30); + this.btnAddFiles.Margin = new System.Windows.Forms.Padding(2); + this.btnAddFiles.Name = "btnAddFiles"; + this.btnAddFiles.Size = new System.Drawing.Size(122, 25); + this.btnAddFiles.TabIndex = 1; + this.btnAddFiles.Text = "Add files.."; + this.btnAddFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnAddFiles, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnAddFiles.UseVisualStyleBackColor = true; + this.btnAddFiles.Click += new System.EventHandler(this.btnAddFiles_Click); + // + // lbxFileList + // + this.lbxFileList.FormattingEnabled = true; + this.lbxFileList.Location = new System.Drawing.Point(8, 108); + this.lbxFileList.Margin = new System.Windows.Forms.Padding(2); + this.lbxFileList.Name = "lbxFileList"; + this.lbxFileList.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; + this.lbxFileList.Size = new System.Drawing.Size(356, 160); + this.lbxFileList.TabIndex = 0; + this.lbxFileList.SelectedIndexChanged += new System.EventHandler(this.lbxFileList_SelectedIndexChanged); + // + // rtxInterchangeFile + // + this.rtxInterchangeFile.Location = new System.Drawing.Point(0, 0); + this.rtxInterchangeFile.Margin = new System.Windows.Forms.Padding(2); + this.rtxInterchangeFile.Name = "rtxInterchangeFile"; + this.rtxInterchangeFile.Size = new System.Drawing.Size(682, 515); + this.rtxInterchangeFile.TabIndex = 0; + this.rtxInterchangeFile.Text = ""; + // + // browser + // + this.browser.Controls.Add(this.webBrowser1); + this.browser.Location = new System.Drawing.Point(4, 22); + this.browser.Margin = new System.Windows.Forms.Padding(2); + this.browser.Name = "browser"; + this.browser.Padding = new System.Windows.Forms.Padding(2); + this.browser.Size = new System.Drawing.Size(1071, 489); + this.browser.TabIndex = 1; + this.browser.Text = "Browser"; + this.browser.UseVisualStyleBackColor = true; + // + // webBrowser1 + // + this.webBrowser1.AllowWebBrowserDrop = false; + this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; + this.webBrowser1.Location = new System.Drawing.Point(2, 2); + this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); + this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); + this.webBrowser1.Name = "webBrowser1"; + this.webBrowser1.Size = new System.Drawing.Size(1067, 485); + this.webBrowser1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(1071, 489); + this.tabPage1.TabIndex = 2; + this.tabPage1.Text = "tabPage1"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // rtLog + // + this.rtLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtLog.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.rtLog.Location = new System.Drawing.Point(0, 0); + this.rtLog.Name = "rtLog"; + this.rtLog.Size = new System.Drawing.Size(762, 485); + this.rtLog.TabIndex = 1; + this.rtLog.Text = "aaaa"; + // + // X12UtilsFRM + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1298, 567); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.statusStrip1); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "X12UtilsFRM"; + this.Text = "Form1"; + this.Load += new System.EventHandler(this.Form1_Load); + this.tabControl1.ResumeLayout(false); + this.parse.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.browser.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -350,7 +388,11 @@ private void InitializeComponent() { private System.Windows.Forms.Button btnParse; private System.Windows.Forms.WebBrowser webBrowser1; private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button btnHippaParse; - } + private System.Windows.Forms.Button btnFindSpec; + private System.Windows.Forms.Button btnHippaParse; + private System.Windows.Forms.TabPage tabPage1; + //private NLog.Windows.Forms.RichTextBoxTarget rtLog; + private System.Windows.Forms.RichTextBox rtLog; + } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 06688a5b..2fbdc5b0 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -2,21 +2,26 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Data.SqlClient; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -using System.IO; -using System.Runtime.CompilerServices; -using X12.Shared.Models; -using System.Diagnostics; -using X12.Transformations; -using X12.Parsing; +using System.Xml; +using NLog; +using NLog.Config; +using NLog.Targets; +using NLog.Windows.Forms; using X12.Hipaa.Claims; using X12.Hipaa.Claims.Services; -using System.Reflection; -using System.Xml; +using X12.Parsing; +using X12.Shared.Models; +using X12.Transformations; namespace X12UtilsFRM { public enum enmTabPages { @@ -24,6 +29,7 @@ public enum enmTabPages { browser } public partial class X12UtilsFRM : Form { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); List interchanges = null; ToolTip tt = null; @@ -52,6 +58,24 @@ public X12UtilsFRM() { InitializeComponent(); } + protected override void OnLoad(EventArgs e) { + base.OnLoad(e); + + // Ensure RichTextBox target points to this form and control + //this also reroute the console to RTB + RichTextBoxTarget.ReInitializeAllTextboxes(this); + + // Test logging + Logger.Info("RichTextBox target initialized successfully, any existing Console logging will be routed to this RichTextBox "); + Logger.Debug("Debug message to RichTextBox"); + } + + protected override void OnShown(EventArgs e) { + base.OnShown(e); + RichTextBoxTarget.ReInitializeAllTextboxes(this); // In case form was not loaded when logging started */ + Logger.Info("RichTextBox logging attached (UI-safe)."); + } + private void Form1_Load(object sender, EventArgs e) { rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; tt = new ToolTip(); @@ -62,6 +86,12 @@ private void Form1_Load(object sender, EventArgs e) { } lbxFileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); btnParse.Enabled = false; + Logger.Trace("Trace message"); + Logger.Debug("Debug message"); + Logger.Info("Info message"); + Logger.Warn("Warning message"); + // Logger.Error("Error message"); + Logger.Fatal("Fatal message"); } private void DisplayHtml(string html) { @@ -231,7 +261,27 @@ private void btnHippaParse_Click(object sender, EventArgs e) { webBrowser1.Navigate(pdfout); //displayPdf(pdfout); } - + + + private void btnFindSpec_Click(object sender, EventArgs e) { + var finder = new x12Test.specFinder(); + var spec = finder.FindTransactionSpec("SH", "005010X222A1", "856"); + Logger.Info($"Spec Found for 856: {spec?.Name}"); + + Logger.Trace("Trace message"); + Logger.Debug("Debug message"); + Logger.Info("Info message"); + Logger.Warn("Warning message"); + Logger.Error("Error message"); + Logger.Fatal("Fatal message"); + + if (spec != null) { + + MessageBox.Show($"Spec Found for 856: {spec.Name}"); + } else { + MessageBox.Show($"Spec Not Found for 856"); + } + } } } diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 856eb4b2..90ce8d51 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -51,7 +51,14 @@ ..\packages\Fonet.1.0\lib\net20\Fonet.dll + + ..\packages\NLog.6.0.2\lib\net46\NLog.dll + + + ..\packages\NLog.Windows.Forms.6.0.2\lib\net35\NLog.Windows.Forms.dll + + @@ -87,6 +94,9 @@ X12UtilsFRM.cs Designer + + PreserveNewest + SettingsSingleFileGenerator diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 935065a9..22c85480 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -123,4 +123,7 @@ 133, 17 + + 133, 17 + \ No newline at end of file diff --git a/X12UtilsFRM/packages.config b/X12UtilsFRM/packages.config index 7121b5b4..541d0808 100644 --- a/X12UtilsFRM/packages.config +++ b/X12UtilsFRM/packages.config @@ -1,4 +1,6 @@  + + \ No newline at end of file From 19f8c4f9c751cb39fc54292a368848bcb92652da Mon Sep 17 00:00:00 2001 From: apeiris Date: Sat, 16 May 2026 10:44:51 -0400 Subject: [PATCH 07/22] wip --- .idea/.gitignore | 3 + .idea/X12.NET.iml | 9 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + X12UtilsFRM/App.config | 26 +- X12UtilsFRM/BiztalkFunctoidNode.cs | 99 ++ X12UtilsFRM/NLog.config | 2 +- X12UtilsFRM/OpenTK.dll.config | 25 + X12UtilsFRM/Program.cs | 5 +- X12UtilsFRM/Properties/Settings.Designer.cs | 26 +- X12UtilsFRM/Properties/Settings.settings | 6 + X12UtilsFRM/SchemaNodeItem.cs | 107 ++ X12UtilsFRM/SkiaMapper.cs | 208 +++ X12UtilsFRM/SkiaMapper.resx | 123 ++ X12UtilsFRM/ToolboxCategory.cs | 145 ++ X12UtilsFRM/X12UtilsFRM.Designer.cs | 813 ++++++----- X12UtilsFRM/X12UtilsFRM.cs | 1226 +++++++++++++---- X12UtilsFRM/X12UtilsFRM.csproj | 64 + X12UtilsFRM/X12UtilsFRM.resx | 3 - X12UtilsFRM/packages.config | 12 + .../Claims/Services/CompilerAttributes.cs | 13 + ...ionalClaimToUB04ClaimFormTransformation.cs | 755 +++++----- src/X12.Hipaa/X12.Hipaa.csproj | 34 + src/X12.Hipaa/packages.config | 13 + src/X12.Shared/Models/HierarchicalLoop.cs | 188 ++- .../MyCustom/Ansi-837I-5010Specification.dtd | 44 + .../MyCustom/Ansi-837I-5010Specification.xml | 477 +++++++ .../MyCustom/Ansi-837I-5010Specification.xsd | 74 + .../Ansi-837I-5010Specification.xsd.xml | 37 + .../X12.Specifications.csproj | 6 +- 31 files changed, 3445 insertions(+), 1118 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/X12.NET.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 X12UtilsFRM/BiztalkFunctoidNode.cs create mode 100644 X12UtilsFRM/OpenTK.dll.config create mode 100644 X12UtilsFRM/SchemaNodeItem.cs create mode 100644 X12UtilsFRM/SkiaMapper.cs create mode 100644 X12UtilsFRM/SkiaMapper.resx create mode 100644 X12UtilsFRM/ToolboxCategory.cs create mode 100644 src/X12.Hipaa/Claims/Services/CompilerAttributes.cs create mode 100644 src/X12.Hipaa/packages.config create mode 100644 src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.dtd create mode 100644 src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xml create mode 100644 src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd create mode 100644 src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/X12.NET.iml b/.idea/X12.NET.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/X12.NET.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..3c741df7 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..0c0d1469 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/X12UtilsFRM/App.config b/X12UtilsFRM/App.config index 83136c94..eb12900b 100644 --- a/X12UtilsFRM/App.config +++ b/X12UtilsFRM/App.config @@ -1,7 +1,7 @@ - + - +
@@ -31,6 +31,28 @@ False + + False + + + False + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/X12UtilsFRM/BiztalkFunctoidNode.cs b/X12UtilsFRM/BiztalkFunctoidNode.cs new file mode 100644 index 00000000..ecf70550 --- /dev/null +++ b/X12UtilsFRM/BiztalkFunctoidNode.cs @@ -0,0 +1,99 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace X12UtilsFRM +{ + public class BizTalkFunctoidNode : Panel + { + public string FunctoidName { get; private set; } + public string FunctoidCategory { get; private set; } + + public Label LblIcon { get; private set; } + public Label LblText { get; private set; } + + public BizTalkFunctoidNode(string text, Point location) + { + this.FunctoidName = text; + this.FunctoidCategory = DetermineCategory(text); + + // Configure the outer BizTalk block capsule size + this.Size = new Size(130, 36); + this.Location = location; + this.BorderStyle = BorderStyle.FixedSingle; + this.Cursor = Cursors.SizeAll; + + // Determine specific color schemes and symbols based on BizTalk categories + Color headerColor; + Color bodyColor; + string iconSymbol; + + switch (this.FunctoidCategory) + { + case "String": + headerColor = Color.FromArgb(0, 122, 204); // BizTalk Blue + bodyColor = Color.FromArgb(235, 245, 255); + iconSymbol = "ℱ"; // Math function script symbol + break; + case "Math": + headerColor = Color.FromArgb(220, 100, 0); // BizTalk Orange/Amber + bodyColor = Color.FromArgb(255, 242, 230); + iconSymbol = "∑"; // Sigma summation symbol + break; + case "Date": + headerColor = Color.FromArgb(16, 124, 65); // BizTalk Green + bodyColor = Color.FromArgb(230, 247, 236); + iconSymbol = "📅"; // Calendar block emoji/glyph + break; + default: + headerColor = Color.FromArgb(100, 100, 100); // Standard Gray + bodyColor = Color.FromArgb(240, 240, 240); + iconSymbol = "⚙"; + break; + } + + this.BackColor = bodyColor; + + // 1. Left Icon Anchor Bar Block + LblIcon = new Label + { + Text = iconSymbol, + Font = new Font("Segoe UI", 11f, FontStyle.Bold), + BackColor = headerColor, + ForeColor = Color.White, + Size = new Size(30, this.Height - 2), + Location = new Point(0, 0), + TextAlign = ContentAlignment.MiddleCenter, + Cursor = Cursors.SizeAll + }; + this.Controls.Add(LblIcon); + + // 2. Right Text Label Description Strip + LblText = new Label + { + Text = text, + Font = new Font("Segoe UI", 8.25f, FontStyle.Regular), + ForeColor = Color.FromArgb(30, 30, 30), + Size = new Size(95, this.Height - 2), + Location = new Point(32, 0), + TextAlign = ContentAlignment.MiddleLeft, + Cursor = Cursors.SizeAll + }; + this.Controls.Add(LblText); + } + + private string DetermineCategory(string functoidName) + { + // Auto-detect the classification group dynamically based on string naming patterns + string name = functoidName.ToLower(); + if (name.Contains("string") || name.Contains("concat") || name.Contains("trim") || name.Contains("case")) + return "String"; + if (name.Contains("add") || name.Contains("sub") || name.Contains("multiply") || name.Contains("divide") || name.Contains("mod") || name.Contains("abs")) + return "Math"; + if (name.Contains("date") || name.Contains("time") || name.Contains("diff")) + return "Date"; + + return "Custom"; + } + } +} \ No newline at end of file diff --git a/X12UtilsFRM/NLog.config b/X12UtilsFRM/NLog.config index b6ffbd19..64915387 100644 --- a/X12UtilsFRM/NLog.config +++ b/X12UtilsFRM/NLog.config @@ -19,7 +19,7 @@ layout="${longdate} [${level:uppercase=true}] ${logger}: ${message} ${exception:format=tostring}" autoScroll="true" maxLines="1000" - useDefaultRowColoringRules="true" /> + useDefaultRowColoringRules="false" /> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/X12UtilsFRM/Program.cs b/X12UtilsFRM/Program.cs index 75948d8c..845619fb 100644 --- a/X12UtilsFRM/Program.cs +++ b/X12UtilsFRM/Program.cs @@ -15,9 +15,8 @@ static class Program { static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - - - Application.Run(new X12UtilsFRM()); + + Application.Run(new X12UtilsFRM()); } } } diff --git a/X12UtilsFRM/Properties/Settings.Designer.cs b/X12UtilsFRM/Properties/Settings.Designer.cs index 0211504b..af15026e 100644 --- a/X12UtilsFRM/Properties/Settings.Designer.cs +++ b/X12UtilsFRM/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace X12UtilsFRM.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "18.6.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -106,5 +106,29 @@ public bool throwExceptions { this["throwExceptions"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool BrowseWhenClicked { + get { + return ((bool)(this["BrowseWhenClicked"])); + } + set { + this["BrowseWhenClicked"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool BrowseWhenSelected { + get { + return ((bool)(this["BrowseWhenSelected"])); + } + set { + this["BrowseWhenSelected"] = value; + } + } } } diff --git a/X12UtilsFRM/Properties/Settings.settings b/X12UtilsFRM/Properties/Settings.settings index 13c6e680..bbca507f 100644 --- a/X12UtilsFRM/Properties/Settings.settings +++ b/X12UtilsFRM/Properties/Settings.settings @@ -23,5 +23,11 @@ False + + False + + + False + \ No newline at end of file diff --git a/X12UtilsFRM/SchemaNodeItem.cs b/X12UtilsFRM/SchemaNodeItem.cs new file mode 100644 index 00000000..b4b43c6f --- /dev/null +++ b/X12UtilsFRM/SchemaNodeItem.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using System.Xml; + +namespace X12UtilsFRM +{ + public class SchemaNodeItem : Panel + { + public XmlNode XmlSourceNode { get; private set; } + public List ChildNodes { get; set; } = new List(); + public bool IsExpanded { get; private set; } = true; + public int IndentLevel { get; set; } = 0; + + private Label lblToggle; + private Label lblText; + private Action _onStateChanged; + private Point _mouseDownLocation; + private bool _isPotentialDrag = false; + + public SchemaNodeItem(XmlNode xmlNode, int indent, Action onStateChanged) + { + this.XmlSourceNode = xmlNode; + this.IndentLevel = indent; + this._onStateChanged = onStateChanged; + + this.Height = 28; + this.Width = 260; + this.BackColor = Color.Transparent; + + // 1. Expand / Collapse Toggle Button + if (xmlNode.HasChildNodes && xmlNode.FirstChild.NodeType == XmlNodeType.Element) + { + lblToggle = new Label + { + Text = "▼", + Font = new Font("Segoe UI", 8, FontStyle.Bold), + Size = new Size(16, 16), + Location = new Point(5 + (indent * 15), 6), + Cursor = Cursors.Hand, + TextAlign = ContentAlignment.MiddleCenter + }; + lblToggle.Click += Toggle_Click; + this.Controls.Add(lblToggle); + } + + // 2. Node Text Label (Acts as the Draggable handle) + lblText = new Label + { + Text = xmlNode.Name, + Font = new Font("Segoe UI", 9, FontStyle.Regular), + AutoSize = true, + Location = new Point((lblToggle != null ? 22 : 10) + (indent * 15), 5), + Cursor = Cursors.Hand + }; + + // --- REVISED DRAG INITIATION LOGIC --- + + // Step A: Record initial click coordinates + lblText.MouseDown += (s, e) => { + if (e.Button == MouseButtons.Left) + { + _isPotentialDrag = true; + _mouseDownLocation = e.Location; + } + }; + + // Step B: Only trigger DoDragDrop if the mouse actually moves beyond the OS drag threshold + lblText.MouseMove += (s, e) => { + if (_isPotentialDrag) + { + int deltaX = Math.Abs(e.X - _mouseDownLocation.X); + int deltaY = Math.Abs(e.Y - _mouseDownLocation.Y); + + // SystemInformation.DragSize prevents twitch-clicks from acting like drags + if (deltaX >= SystemInformation.DragSize.Width || deltaY >= SystemInformation.DragSize.Height) + { + _isPotentialDrag = false; // Drag recognized, clear intent flag + + // Package the layout snapshot payload + TreeNode dragSnapshot = new TreeNode(this.XmlSourceNode.Name) { Tag = this.XmlSourceNode }; + + // Fire the drag-drop execution sequence safely + this.DoDragDrop(dragSnapshot, DragDropEffects.Copy | DragDropEffects.Link); + } + } + }; + + // Step C: Cancel the drag sequence gracefully if mouse button is released early + lblText.MouseUp += (s, e) => { + if (e.Button == MouseButtons.Left) + { + _isPotentialDrag = false; + } + }; + + this.Controls.Add(lblText); + } + private void Toggle_Click(object sender, EventArgs e) + { + IsExpanded = !IsExpanded; + lblToggle.Text = IsExpanded ? "▼" : "►"; + _onStateChanged?.Invoke(this); + } + } +} \ No newline at end of file diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs new file mode 100644 index 00000000..2d3f8dbd --- /dev/null +++ b/X12UtilsFRM/SkiaMapper.cs @@ -0,0 +1,208 @@ +using SkiaSharp; +using SkiaSharp.Views.Desktop; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace X12UtilsFRM +{ + public class SkiaMapper : SKControl + { + public List Connections { get; set; } = new List(); + private ContextMenuStrip _lineContextMenu; + private MappingConnection _selectedConnectionForDelete; + + public SkiaMapper() + { + this.Dock = DockStyle.Fill; + InitializeLineContextMenu(); + } + + private void InitializeLineContextMenu() + { + _lineContextMenu = new ContextMenuStrip(); + var deleteItem = new ToolStripMenuItem("Delete Connection"); + deleteItem.Click += (s, e) => + { + if (_selectedConnectionForDelete != null) + { + Connections.Remove(_selectedConnectionForDelete); + _selectedConnectionForDelete = null; + this.Invalidate(); + } + }; + _lineContextMenu.Items.Add(deleteItem); + } + + protected override void WndProc(ref Message m) + { + const int WM_NCHITTEST = 0x0084; + const int HTTRANSPARENT = -1; + const int WM_RBUTTONDOWN = 0x0204; + + if (m.Msg == WM_RBUTTONDOWN) + { + Point clientPt = this.PointToClient(Cursor.Position); + CheckForLineRightClick(clientPt); + } + + if (m.Msg == WM_NCHITTEST) + { + m.Result = (IntPtr)HTTRANSPARENT; + } + else + { + base.WndProc(ref m); + } + } + + // NEW HELPER METHOD: Seamlessly finds the correct UI component to map paths to + private Control ResolveSourceControl(object source) + { + if (source is Control ctrl) return ctrl; + + // If it's tracking an XmlNode data instance, look into our side scroll container lane + if (source is System.Xml.XmlNode xmlNode && this.Parent != null) + { + foreach (Control c in this.Parent.Controls) + { + if (c is FlowLayoutPanel pnlScroll && (pnlScroll.Name == "pnlSchemaScrollContainer" || pnlScroll.Width == 285)) + { + foreach (Control subCtrl in pnlScroll.Controls) + { + if (subCtrl is SchemaNodeItem sni && sni.XmlSourceNode == xmlNode) + { + return sni; + } + } + } + } + } + return null; + } + + private void CheckForLineRightClick(Point clickPt) + { + SKPoint skClick = new SKPoint(clickPt.X, clickPt.Y); + + foreach (var conn in Connections) + { + // CRITICAL FIX: Resolve visual control reference dynamically + var visualSource = ResolveSourceControl(conn.Source); + var start = GetControlPoint(visualSource, isSource: true); + var end = GetControlPoint(conn.Target as Control, isSource: false); + + if (start != SKPoint.Empty && end != SKPoint.Empty) + { + if (IsPointNearBezier(skClick, start, end, 8.0f)) + { + _selectedConnectionForDelete = conn; + _lineContextMenu.Show(Cursor.Position); + break; + } + } + } + } + + private bool IsPointNearBezier(SKPoint clickPt, SKPoint start, SKPoint end, float tolerance) + { + float controlOffset = Math.Abs(start.X - end.X) / 2; + + SKPoint p0 = start; + SKPoint p1 = new SKPoint(start.X + controlOffset, start.Y); + SKPoint p2 = new SKPoint(end.X - controlOffset, end.Y); + SKPoint p3 = end; + + int samples = 20; + for (int i = 0; i <= samples; i++) + { + float t = (float)i / samples; + float u = 1 - t; + float tt = t * t; + float uu = u * u; + float uuu = uu * u; + float ttt = tt * t; + + float x = uuu * p0.X + 3 * uu * t * p1.X + 3 * u * tt * p2.X + ttt * p3.X; + float y = uuu * p0.Y + 3 * uu * t * p1.Y + 3 * u * tt * p2.Y + ttt * p3.Y; + + float dx = clickPt.X - x; + float dy = clickPt.Y - y; + float distance = (float)Math.Sqrt(dx * dx + dy * dy); + + if (distance <= tolerance) + { + return true; + } + } + + return false; + } + + protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) + { + var canvas = e.Surface.Canvas; + canvas.Clear(SKColors.Transparent); + + using (var paint = new SKPaint()) + { + paint.Style = SKPaintStyle.Stroke; + paint.StrokeWidth = 2; + paint.Color = SKColors.DodgerBlue; + paint.IsAntialias = true; + + foreach (var conn in Connections) + { + // CRITICAL FIX: Resolve visual control reference dynamically + var visualSource = ResolveSourceControl(conn.Source); + var start = GetControlPoint(visualSource, isSource: true); + var end = GetControlPoint(conn.Target as Control, isSource: false); + + if (start != SKPoint.Empty && end != SKPoint.Empty) + { + DrawBezierLine(canvas, paint, start, end); + } + } + } + } + + private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPoint start, SKPoint end) + { + using (var path = new SKPath()) + { + path.MoveTo(start); + float controlOffset = Math.Abs(start.X - end.X) / 2; + path.CubicTo(start.X + controlOffset, start.Y, end.X - controlOffset, end.Y, end.X, end.Y); + canvas.DrawPath(path, paint); + } + } + + private SKPoint GetControlPoint(Control ctrl, bool isSource) + { + if (ctrl == null || ctrl.Parent == null) return SKPoint.Empty; + + try + { + int targetX = isSource ? ctrl.Width : 0; + Point localAnchorPt = new Point(targetX, ctrl.Height / 2); + Point screenPt = ctrl.PointToScreen(localAnchorPt); + Point localPt = this.PointToClient(screenPt); + + return new SKPoint(localPt.X, localPt.Y); + } + catch (Exception) + { + return SKPoint.Empty; + } + } + } + + public class MappingConnection + { + // REVERTED TO OBJECT: Restores perfect compilation type safety across files + public object Source { get; set; } + public object Target { get; set; } + public SKColor LineColor { get; set; } = SKColors.DodgerBlue; + } +} \ No newline at end of file diff --git a/X12UtilsFRM/SkiaMapper.resx b/X12UtilsFRM/SkiaMapper.resx new file mode 100644 index 00000000..e5858cc2 --- /dev/null +++ b/X12UtilsFRM/SkiaMapper.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/X12UtilsFRM/ToolboxCategory.cs b/X12UtilsFRM/ToolboxCategory.cs new file mode 100644 index 00000000..0516574c --- /dev/null +++ b/X12UtilsFRM/ToolboxCategory.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace X12UtilsFRM +{ + public class ToolboxCategory : Panel + { + public string CategoryName { get; private set; } + public bool IsExpanded { get; private set; } = false; + public List FunctoidTemplates { get; set; } = new List(); + + private Label lblHeader; + private FlowLayoutPanel pnlContent; + private Action _onStateChanged; + + public ToolboxCategory(string name, List functoids, Action onStateChanged) + { + this.CategoryName = name; + this.FunctoidTemplates = functoids; + this._onStateChanged = onStateChanged; + + this.Width = 220; // Slightly narrower to safely clear parent scrollbars + this.BackColor = Color.Transparent; + + // 1. Category Header Label + lblHeader = new Label + { + Text = "► " + name, + Font = new Font("Segoe UI", 9, FontStyle.Bold), + BackColor = Color.FromArgb(230, 235, 245), + ForeColor = Color.FromArgb(50, 50, 80), + Dock = DockStyle.Top, + Height = 26, + TextAlign = ContentAlignment.MiddleLeft, + Cursor = Cursors.Hand, + Padding = new Padding(5, 0, 0, 0) + }; + lblHeader.Click += Header_Click; + this.Controls.Add(lblHeader); + + // 2. Content Flow Panel for Functoids + pnlContent = new FlowLayoutPanel + { + // FIX A: Remove DockStyle.Fill! Use Top anchoring and manual positioning instead. + Location = new Point(0, lblHeader.Height), + Width = this.Width, + BackColor = Color.FromArgb(250, 250, 252), + Padding = new Padding(6), + FlowDirection = FlowDirection.LeftToRight, + WrapContents = true, + AutoSize = true, // FIX B: Let it resize itself naturally to fit its rows! + AutoSizeMode = AutoSizeMode.GrowAndShrink, + Visible = false + }; + + foreach (var templateName in functoids) + { + Label btnTemplate = CreateTemplateItem(templateName); + pnlContent.Controls.Add(btnTemplate); + } + + this.Controls.Add(pnlContent); + + // Explicitly force layout tree depth stacking ordering + this.Controls.SetChildIndex(lblHeader, 0); + this.Controls.SetChildIndex(pnlContent, 1); + + UpdateHeight(); + } + + private Label CreateTemplateItem(string text) + { + Label lbl = new Label + { + Text = text, + Font = new Font("Segoe UI", 8.5f, FontStyle.Regular), + BackColor = Color.LightSteelBlue, + BorderStyle = BorderStyle.FixedSingle, + TextAlign = ContentAlignment.MiddleCenter, + Size = new Size(92, 28), // Safe button size matrix + Margin = new Padding(4), + Cursor = Cursors.Hand + }; + + // Smart Drag-Size Threshold Logic + Point mouseDownLocation = Point.Empty; + bool isPotentialDrag = false; + + lbl.MouseDown += (s, e) => { + if (e.Button == MouseButtons.Left) + { + isPotentialDrag = true; + mouseDownLocation = e.Location; + } + }; + + lbl.MouseMove += (s, e) => { + if (isPotentialDrag) + { + int deltaX = Math.Abs(e.X - mouseDownLocation.X); + int deltaY = Math.Abs(e.Y - mouseDownLocation.Y); + + if (deltaX >= SystemInformation.DragSize.Width || deltaY >= SystemInformation.DragSize.Height) + { + isPotentialDrag = false; + TreeNode dragSnapshot = new TreeNode(text) { Tag = "FUNCTOID_TEMPLATE" }; + this.DoDragDrop(dragSnapshot, DragDropEffects.Copy | DragDropEffects.Link); + } + } + }; + + lbl.MouseUp += (s, e) => { if (e.Button == MouseButtons.Left) isPotentialDrag = false; }; + + return lbl; + } + + private void Header_Click(object sender, EventArgs e) + { + IsExpanded = !IsExpanded; + lblHeader.Text = (IsExpanded ? "▼ " : "► ") + CategoryName; + pnlContent.Visible = IsExpanded; + + UpdateHeight(); + _onStateChanged?.Invoke(); + } + + public void UpdateHeight() + { + if (!IsExpanded) + { + this.Height = lblHeader.Height; + } + else + { + // Force the layout engine to resolve auto-size parameters instantly + pnlContent.PerformLayout(); + + // FIX C: Calculate height strictly based on the real size of the auto-sized content panel + this.Height = lblHeader.Height + pnlContent.Height + 4; + } + } + } +} \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index ef8d227b..1be23bdd 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -1,6 +1,7 @@  namespace X12UtilsFRM { - partial class X12UtilsFRM { + partial class X12UtilsFRM + { /// /// Required designer variable. /// @@ -10,8 +11,10 @@ partial class X12UtilsFRM { /// Clean up any resources being used. ///
/// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { components.Dispose(); } base.Dispose(disposing); @@ -23,347 +26,450 @@ protected override void Dispose(bool disposing) { /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///
- private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.parse = new System.Windows.Forms.TabPage(); - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.btnFindSpec = new System.Windows.Forms.Button(); - this.btnHippaParse = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); - this.btnParse = new System.Windows.Forms.Button(); - this.lblInterchangeCount = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.lblSelectedFile = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.rbHtml = new System.Windows.Forms.RadioButton(); - this.rbXml = new System.Windows.Forms.RadioButton(); - this.btnAddFiles = new System.Windows.Forms.Button(); - this.lbxFileList = new System.Windows.Forms.ListBox(); - this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); - this.browser = new System.Windows.Forms.TabPage(); - this.webBrowser1 = new System.Windows.Forms.WebBrowser(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.rtLog = new System.Windows.Forms.RichTextBox(); - this.tabControl1.SuspendLayout(); - this.parse.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - this.groupBox1.SuspendLayout(); - this.browser.SuspendLayout(); - this.SuspendLayout(); - // - // statusStrip1 - // - this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.statusStrip1.Location = new System.Drawing.Point(0, 545); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); - this.statusStrip1.Size = new System.Drawing.Size(1298, 22); - this.statusStrip1.TabIndex = 0; - this.statusStrip1.Text = "statusStrip1"; - // - // tabControl1 - // - this.tabControl1.Controls.Add(this.parse); - this.tabControl1.Controls.Add(this.browser); - this.tabControl1.Controls.Add(this.tabPage1); - this.tabControl1.Location = new System.Drawing.Point(0, 0); - this.tabControl1.Margin = new System.Windows.Forms.Padding(2); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1079, 515); - this.tabControl1.TabIndex = 1; - // - // parse - // - this.parse.Controls.Add(this.splitContainer1); - this.parse.Location = new System.Drawing.Point(4, 22); - this.parse.Margin = new System.Windows.Forms.Padding(2); - this.parse.Name = "parse"; - this.parse.Padding = new System.Windows.Forms.Padding(2); - this.parse.Size = new System.Drawing.Size(1071, 489); - this.parse.TabIndex = 0; - this.parse.Text = "Parse"; - this.parse.UseVisualStyleBackColor = true; - // - // splitContainer1 - // - this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(2, 2); - this.splitContainer1.Margin = new System.Windows.Forms.Padding(2); - this.splitContainer1.Name = "splitContainer1"; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.Controls.Add(this.btnFindSpec); - this.splitContainer1.Panel1.Controls.Add(this.btnHippaParse); - this.splitContainer1.Panel1.Controls.Add(this.button1); - this.splitContainer1.Panel1.Controls.Add(this.btnParse); - this.splitContainer1.Panel1.Controls.Add(this.lblInterchangeCount); - this.splitContainer1.Panel1.Controls.Add(this.label3); - this.splitContainer1.Panel1.Controls.Add(this.lblSelectedFile); - this.splitContainer1.Panel1.Controls.Add(this.label1); - this.splitContainer1.Panel1.Controls.Add(this.groupBox1); - this.splitContainer1.Panel1.Controls.Add(this.btnAddFiles); - this.splitContainer1.Panel1.Controls.Add(this.lbxFileList); - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.Controls.Add(this.rtLog); - this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); - this.splitContainer1.Size = new System.Drawing.Size(1067, 485); - this.splitContainer1.SplitterDistance = 302; - this.splitContainer1.SplitterWidth = 3; - this.splitContainer1.TabIndex = 0; - // - // btnFindSpec - // - this.btnFindSpec.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnFindSpec.Location = new System.Drawing.Point(19, 434); - this.btnFindSpec.Margin = new System.Windows.Forms.Padding(2); - this.btnFindSpec.Name = "btnFindSpec"; - this.btnFindSpec.Size = new System.Drawing.Size(161, 34); - this.btnFindSpec.TabIndex = 10; - this.btnFindSpec.Text = "Find Spec"; - this.btnFindSpec.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnFindSpec, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnFindSpec.UseVisualStyleBackColor = true; - this.btnFindSpec.Click += new System.EventHandler(this.btnFindSpec_Click); - // - // btnHippaParse - // - this.btnHippaParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnHippaParse.Location = new System.Drawing.Point(19, 383); - this.btnHippaParse.Margin = new System.Windows.Forms.Padding(2); - this.btnHippaParse.Name = "btnHippaParse"; - this.btnHippaParse.Size = new System.Drawing.Size(161, 34); - this.btnHippaParse.TabIndex = 9; - this.btnHippaParse.Text = "Parse Hippa"; - this.btnHippaParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnHippaParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnHippaParse.UseVisualStyleBackColor = true; - this.btnHippaParse.Click += new System.EventHandler(this.btnHippaParse_Click); - // - // button1 - // - this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button1.Location = new System.Drawing.Point(15, 345); - this.button1.Margin = new System.Windows.Forms.Padding(2); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(182, 34); - this.button1.TabIndex = 8; - this.button1.Text = "Any Xml to HTML"; - this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.button1.UseVisualStyleBackColor = true; - // - // btnParse - // - this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnParse.Location = new System.Drawing.Point(210, 295); - this.btnParse.Margin = new System.Windows.Forms.Padding(2); - this.btnParse.Name = "btnParse"; - this.btnParse.Size = new System.Drawing.Size(122, 25); - this.btnParse.TabIndex = 7; - this.btnParse.Text = "<< Parse"; - this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnParse.UseVisualStyleBackColor = true; - this.btnParse.Click += new System.EventHandler(this.btnParse_Click); - // - // lblInterchangeCount - // - this.lblInterchangeCount.AutoSize = true; - this.lblInterchangeCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblInterchangeCount.ForeColor = System.Drawing.Color.Red; - this.lblInterchangeCount.Location = new System.Drawing.Point(112, 85); - this.lblInterchangeCount.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.lblInterchangeCount.Name = "lblInterchangeCount"; - this.lblInterchangeCount.Size = new System.Drawing.Size(19, 20); - this.lblInterchangeCount.TabIndex = 6; - this.lblInterchangeCount.Text = "0"; - this.lblInterchangeCount.TextChanged += new System.EventHandler(this.lblInterchangeCount_TextChanged); - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label3.Location = new System.Drawing.Point(4, 85); - this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(115, 20); - this.label3.TabIndex = 5; - this.label3.Text = "Interchanges"; - // - // lblSelectedFile - // - this.lblSelectedFile.AutoSize = true; - this.lblSelectedFile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblSelectedFile.ForeColor = System.Drawing.Color.Red; - this.lblSelectedFile.Location = new System.Drawing.Point(82, 65); - this.lblSelectedFile.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.lblSelectedFile.Name = "lblSelectedFile"; - this.lblSelectedFile.Size = new System.Drawing.Size(0, 20); - this.lblSelectedFile.TabIndex = 4; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(4, 65); - this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(80, 20); - this.label1.TabIndex = 3; - this.label1.Text = "Selected"; - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.rbHtml); - this.groupBox1.Controls.Add(this.rbXml); - this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.groupBox1.Location = new System.Drawing.Point(15, 272); - this.groupBox1.Margin = new System.Windows.Forms.Padding(2); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(2); - this.groupBox1.Size = new System.Drawing.Size(182, 53); - this.groupBox1.TabIndex = 2; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Transform.."; - // - // rbHtml - // - this.rbHtml.AutoSize = true; - this.rbHtml.Checked = true; - this.rbHtml.Location = new System.Drawing.Point(68, 24); - this.rbHtml.Margin = new System.Windows.Forms.Padding(2); - this.rbHtml.Name = "rbHtml"; - this.rbHtml.Size = new System.Drawing.Size(74, 24); - this.rbHtml.TabIndex = 1; - this.rbHtml.TabStop = true; - this.rbHtml.Text = "HTML"; - this.rbHtml.UseVisualStyleBackColor = true; - this.rbHtml.CheckedChanged += new System.EventHandler(this.rbHtml_CheckedChanged); - // - // rbXml - // - this.rbXml.AutoSize = true; - this.rbXml.Location = new System.Drawing.Point(4, 24); - this.rbXml.Margin = new System.Windows.Forms.Padding(2); - this.rbXml.Name = "rbXml"; - this.rbXml.Size = new System.Drawing.Size(63, 24); - this.rbXml.TabIndex = 0; - this.rbXml.TabStop = true; - this.rbXml.Text = "XML"; - this.rbXml.UseVisualStyleBackColor = true; - this.rbXml.CheckedChanged += new System.EventHandler(this.rbXml_CheckedChanged); - // - // btnAddFiles - // - this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnAddFiles.Location = new System.Drawing.Point(4, 30); - this.btnAddFiles.Margin = new System.Windows.Forms.Padding(2); - this.btnAddFiles.Name = "btnAddFiles"; - this.btnAddFiles.Size = new System.Drawing.Size(122, 25); - this.btnAddFiles.TabIndex = 1; - this.btnAddFiles.Text = "Add files.."; - this.btnAddFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnAddFiles, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnAddFiles.UseVisualStyleBackColor = true; - this.btnAddFiles.Click += new System.EventHandler(this.btnAddFiles_Click); - // - // lbxFileList - // - this.lbxFileList.FormattingEnabled = true; - this.lbxFileList.Location = new System.Drawing.Point(8, 108); - this.lbxFileList.Margin = new System.Windows.Forms.Padding(2); - this.lbxFileList.Name = "lbxFileList"; - this.lbxFileList.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; - this.lbxFileList.Size = new System.Drawing.Size(356, 160); - this.lbxFileList.TabIndex = 0; - this.lbxFileList.SelectedIndexChanged += new System.EventHandler(this.lbxFileList_SelectedIndexChanged); - // - // rtxInterchangeFile - // - this.rtxInterchangeFile.Location = new System.Drawing.Point(0, 0); - this.rtxInterchangeFile.Margin = new System.Windows.Forms.Padding(2); - this.rtxInterchangeFile.Name = "rtxInterchangeFile"; - this.rtxInterchangeFile.Size = new System.Drawing.Size(682, 515); - this.rtxInterchangeFile.TabIndex = 0; - this.rtxInterchangeFile.Text = ""; - // - // browser - // - this.browser.Controls.Add(this.webBrowser1); - this.browser.Location = new System.Drawing.Point(4, 22); - this.browser.Margin = new System.Windows.Forms.Padding(2); - this.browser.Name = "browser"; - this.browser.Padding = new System.Windows.Forms.Padding(2); - this.browser.Size = new System.Drawing.Size(1071, 489); - this.browser.TabIndex = 1; - this.browser.Text = "Browser"; - this.browser.UseVisualStyleBackColor = true; - // - // webBrowser1 - // - this.webBrowser1.AllowWebBrowserDrop = false; - this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; - this.webBrowser1.Location = new System.Drawing.Point(2, 2); - this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); - this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); - this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(1067, 485); - this.webBrowser1.TabIndex = 0; - // - // tabPage1 - // - this.tabPage1.Location = new System.Drawing.Point(4, 22); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(1071, 489); - this.tabPage1.TabIndex = 2; - this.tabPage1.Text = "tabPage1"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // rtLog - // - this.rtLog.Dock = System.Windows.Forms.DockStyle.Fill; - this.rtLog.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.rtLog.Location = new System.Drawing.Point(0, 0); - this.rtLog.Name = "rtLog"; - this.rtLog.Size = new System.Drawing.Size(762, 485); - this.rtLog.TabIndex = 1; - this.rtLog.Text = "aaaa"; - // - // X12UtilsFRM - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1298, 567); - this.Controls.Add(this.tabControl1); - this.Controls.Add(this.statusStrip1); - this.Margin = new System.Windows.Forms.Padding(2); - this.Name = "X12UtilsFRM"; - this.Text = "Form1"; - this.Load += new System.EventHandler(this.Form1_Load); - this.tabControl1.ResumeLayout(false); - this.parse.ResumeLayout(false); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel1.PerformLayout(); - this.splitContainer1.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.browser.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.parse = new System.Windows.Forms.TabPage(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.chkBrowse = new System.Windows.Forms.CheckBox(); + this.btnMap = new System.Windows.Forms.Button(); + this.btnFindSpec = new System.Windows.Forms.Button(); + this.btnHippaParse = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.btnParse = new System.Windows.Forms.Button(); + this.lblInterchangeCount = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.lblSelectedFile = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rbHtml = new System.Windows.Forms.RadioButton(); + this.rbXml = new System.Windows.Forms.RadioButton(); + this.btnAddFiles = new System.Windows.Forms.Button(); + this.lbxFileList = new System.Windows.Forms.ListBox(); + this.rtLog = new System.Windows.Forms.RichTextBox(); + this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); + this.browser = new System.Windows.Forms.TabPage(); + this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.FormLocations = new System.Windows.Forms.TabPage(); + this.rtLocations = new System.Windows.Forms.RichTextBox(); + this.tbpMap = new System.Windows.Forms.TabPage(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.pnlFunctoids = new System.Windows.Forms.Panel(); + this.trvTarget = new System.Windows.Forms.TreeView(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.tabControl1.SuspendLayout(); + this.parse.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.browser.SuspendLayout(); + this.FormLocations.SuspendLayout(); + this.tbpMap.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.SuspendLayout(); + this.SuspendLayout(); + // + // statusStrip1 + // + this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.statusStrip1.Location = new System.Drawing.Point(0, 545); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); + this.statusStrip1.Size = new System.Drawing.Size(1298, 22); + this.statusStrip1.TabIndex = 0; + this.statusStrip1.Text = "statusStrip1"; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.parse); + this.tabControl1.Controls.Add(this.browser); + this.tabControl1.Controls.Add(this.FormLocations); + this.tabControl1.Controls.Add(this.tbpMap); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Margin = new System.Windows.Forms.Padding(2); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(1298, 545); + this.tabControl1.TabIndex = 1; + this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); + // + // parse + // + this.parse.Controls.Add(this.splitContainer1); + this.parse.Location = new System.Drawing.Point(4, 22); + this.parse.Margin = new System.Windows.Forms.Padding(2); + this.parse.Name = "parse"; + this.parse.Padding = new System.Windows.Forms.Padding(2); + this.parse.Size = new System.Drawing.Size(1290, 519); + this.parse.TabIndex = 0; + this.parse.Text = "Parse"; + this.parse.UseVisualStyleBackColor = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer1.Location = new System.Drawing.Point(2, 2); + this.splitContainer1.Margin = new System.Windows.Forms.Padding(2); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.chkBrowse); + this.splitContainer1.Panel1.Controls.Add(this.btnMap); + this.splitContainer1.Panel1.Controls.Add(this.btnFindSpec); + this.splitContainer1.Panel1.Controls.Add(this.btnHippaParse); + this.splitContainer1.Panel1.Controls.Add(this.button1); + this.splitContainer1.Panel1.Controls.Add(this.btnParse); + this.splitContainer1.Panel1.Controls.Add(this.lblInterchangeCount); + this.splitContainer1.Panel1.Controls.Add(this.label3); + this.splitContainer1.Panel1.Controls.Add(this.lblSelectedFile); + this.splitContainer1.Panel1.Controls.Add(this.label1); + this.splitContainer1.Panel1.Controls.Add(this.groupBox1); + this.splitContainer1.Panel1.Controls.Add(this.btnAddFiles); + this.splitContainer1.Panel1.Controls.Add(this.lbxFileList); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.rtLog); + this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); + this.splitContainer1.Size = new System.Drawing.Size(1286, 515); + this.splitContainer1.SplitterDistance = 363; + this.splitContainer1.SplitterWidth = 3; + this.splitContainer1.TabIndex = 0; + // + // chkBrowse + // + this.chkBrowse.AutoSize = true; + this.chkBrowse.Checked = global::X12UtilsFRM.Properties.Settings.Default.BrowseWhenSelected; + this.chkBrowse.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "BrowseWhenSelected", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.chkBrowse.Location = new System.Drawing.Point(15, 235); + this.chkBrowse.Name = "chkBrowse"; + this.chkBrowse.Size = new System.Drawing.Size(127, 17); + this.chkBrowse.TabIndex = 12; + this.chkBrowse.Text = "Brows when selected"; + this.chkBrowse.UseVisualStyleBackColor = true; + // + // btnMap + // + this.btnMap.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnMap.Location = new System.Drawing.Point(15, 443); + this.btnMap.Margin = new System.Windows.Forms.Padding(2); + this.btnMap.Name = "btnMap"; + this.btnMap.Size = new System.Drawing.Size(158, 34); + this.btnMap.TabIndex = 11; + this.btnMap.Text = "Map"; + this.toolTip1.SetToolTip(this.btnMap, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnMap.UseVisualStyleBackColor = true; + this.btnMap.Click += new System.EventHandler(this.btnMap_Click); + // + // btnFindSpec + // + this.btnFindSpec.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnFindSpec.Location = new System.Drawing.Point(15, 405); + this.btnFindSpec.Margin = new System.Windows.Forms.Padding(2); + this.btnFindSpec.Name = "btnFindSpec"; + this.btnFindSpec.Size = new System.Drawing.Size(158, 34); + this.btnFindSpec.TabIndex = 10; + this.btnFindSpec.Text = "Find Spec"; + this.toolTip1.SetToolTip(this.btnFindSpec, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnFindSpec.UseVisualStyleBackColor = true; + this.btnFindSpec.Click += new System.EventHandler(this.btnFindSpec_Click); + // + // btnHippaParse + // + this.btnHippaParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnHippaParse.Location = new System.Drawing.Point(15, 367); + this.btnHippaParse.Margin = new System.Windows.Forms.Padding(2); + this.btnHippaParse.Name = "btnHippaParse"; + this.btnHippaParse.Size = new System.Drawing.Size(158, 34); + this.btnHippaParse.TabIndex = 9; + this.btnHippaParse.Text = "Parse Hippa"; + this.toolTip1.SetToolTip(this.btnHippaParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnHippaParse.UseVisualStyleBackColor = true; + this.btnHippaParse.Click += new System.EventHandler(this.btnHippaParse_Click); + // + // button1 + // + this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button1.Location = new System.Drawing.Point(15, 329); + this.button1.Margin = new System.Windows.Forms.Padding(2); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(158, 34); + this.button1.TabIndex = 8; + this.button1.Text = "Any Xml to HTML"; + this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.button1.UseVisualStyleBackColor = true; + // + // btnParse + // + this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnParse.Location = new System.Drawing.Point(210, 295); + this.btnParse.Margin = new System.Windows.Forms.Padding(2); + this.btnParse.Name = "btnParse"; + this.btnParse.Size = new System.Drawing.Size(122, 25); + this.btnParse.TabIndex = 7; + this.btnParse.Text = "<< Parse"; + this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnParse.UseVisualStyleBackColor = true; + this.btnParse.Click += new System.EventHandler(this.btnParse_Click); + // + // lblInterchangeCount + // + this.lblInterchangeCount.AutoSize = true; + this.lblInterchangeCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblInterchangeCount.ForeColor = System.Drawing.Color.Red; + this.lblInterchangeCount.Location = new System.Drawing.Point(112, 85); + this.lblInterchangeCount.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.lblInterchangeCount.Name = "lblInterchangeCount"; + this.lblInterchangeCount.Size = new System.Drawing.Size(19, 20); + this.lblInterchangeCount.TabIndex = 6; + this.lblInterchangeCount.Text = "0"; + this.lblInterchangeCount.TextChanged += new System.EventHandler(this.lblInterchangeCount_TextChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(4, 85); + this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(115, 20); + this.label3.TabIndex = 5; + this.label3.Text = "Interchanges"; + // + // lblSelectedFile + // + this.lblSelectedFile.AutoSize = true; + this.lblSelectedFile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblSelectedFile.ForeColor = System.Drawing.Color.Red; + this.lblSelectedFile.Location = new System.Drawing.Point(82, 65); + this.lblSelectedFile.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.lblSelectedFile.Name = "lblSelectedFile"; + this.lblSelectedFile.Size = new System.Drawing.Size(0, 20); + this.lblSelectedFile.TabIndex = 4; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(4, 65); + this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(80, 20); + this.label1.TabIndex = 3; + this.label1.Text = "Selected"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rbHtml); + this.groupBox1.Controls.Add(this.rbXml); + this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.groupBox1.Location = new System.Drawing.Point(15, 272); + this.groupBox1.Margin = new System.Windows.Forms.Padding(2); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Padding = new System.Windows.Forms.Padding(2); + this.groupBox1.Size = new System.Drawing.Size(182, 53); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Transform.."; + // + // rbHtml + // + this.rbHtml.AutoSize = true; + this.rbHtml.Checked = true; + this.rbHtml.Location = new System.Drawing.Point(68, 24); + this.rbHtml.Margin = new System.Windows.Forms.Padding(2); + this.rbHtml.Name = "rbHtml"; + this.rbHtml.Size = new System.Drawing.Size(74, 24); + this.rbHtml.TabIndex = 1; + this.rbHtml.TabStop = true; + this.rbHtml.Text = "HTML"; + this.rbHtml.UseVisualStyleBackColor = true; + this.rbHtml.CheckedChanged += new System.EventHandler(this.rbHtml_CheckedChanged); + // + // rbXml + // + this.rbXml.AutoSize = true; + this.rbXml.Location = new System.Drawing.Point(4, 24); + this.rbXml.Margin = new System.Windows.Forms.Padding(2); + this.rbXml.Name = "rbXml"; + this.rbXml.Size = new System.Drawing.Size(63, 24); + this.rbXml.TabIndex = 0; + this.rbXml.TabStop = true; + this.rbXml.Text = "XML"; + this.rbXml.UseVisualStyleBackColor = true; + this.rbXml.CheckedChanged += new System.EventHandler(this.rbXml_CheckedChanged); + // + // btnAddFiles + // + this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnAddFiles.Location = new System.Drawing.Point(4, 30); + this.btnAddFiles.Margin = new System.Windows.Forms.Padding(2); + this.btnAddFiles.Name = "btnAddFiles"; + this.btnAddFiles.Size = new System.Drawing.Size(122, 25); + this.btnAddFiles.TabIndex = 1; + this.btnAddFiles.Text = "Add files.."; + this.btnAddFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnAddFiles, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnAddFiles.UseVisualStyleBackColor = true; + this.btnAddFiles.Click += new System.EventHandler(this.btnAddFiles_Click); + // + // lbxFileList + // + this.lbxFileList.FormattingEnabled = true; + this.lbxFileList.Location = new System.Drawing.Point(8, 108); + this.lbxFileList.Margin = new System.Windows.Forms.Padding(2); + this.lbxFileList.Name = "lbxFileList"; + this.lbxFileList.Size = new System.Drawing.Size(356, 121); + this.lbxFileList.TabIndex = 0; + this.lbxFileList.SelectedIndexChanged += new System.EventHandler(this.lbxFileList_SelectedIndexChanged); + // + // rtLog + // + this.rtLog.BackColor = System.Drawing.Color.Black; + this.rtLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtLog.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.rtLog.ForeColor = System.Drawing.Color.Lime; + this.rtLog.Location = new System.Drawing.Point(0, 0); + this.rtLog.Name = "rtLog"; + this.rtLog.Size = new System.Drawing.Size(920, 515); + this.rtLog.TabIndex = 1; + this.rtLog.Text = "aaaa"; + // + // rtxInterchangeFile + // + this.rtxInterchangeFile.Location = new System.Drawing.Point(0, 0); + this.rtxInterchangeFile.Margin = new System.Windows.Forms.Padding(2); + this.rtxInterchangeFile.Name = "rtxInterchangeFile"; + this.rtxInterchangeFile.Size = new System.Drawing.Size(682, 515); + this.rtxInterchangeFile.TabIndex = 0; + this.rtxInterchangeFile.Text = ""; + // + // browser + // + this.browser.Controls.Add(this.webBrowser1); + this.browser.Location = new System.Drawing.Point(4, 22); + this.browser.Margin = new System.Windows.Forms.Padding(2); + this.browser.Name = "browser"; + this.browser.Padding = new System.Windows.Forms.Padding(2); + this.browser.Size = new System.Drawing.Size(1290, 519); + this.browser.TabIndex = 1; + this.browser.Text = "Browser"; + this.browser.UseVisualStyleBackColor = true; + // + // webBrowser1 + // + this.webBrowser1.AllowWebBrowserDrop = false; + this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; + this.webBrowser1.Location = new System.Drawing.Point(2, 2); + this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); + this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); + this.webBrowser1.Name = "webBrowser1"; + this.webBrowser1.Size = new System.Drawing.Size(1286, 515); + this.webBrowser1.TabIndex = 0; + // + // FormLocations + // + this.FormLocations.Controls.Add(this.rtLocations); + this.FormLocations.Location = new System.Drawing.Point(4, 22); + this.FormLocations.Name = "FormLocations"; + this.FormLocations.Padding = new System.Windows.Forms.Padding(3); + this.FormLocations.Size = new System.Drawing.Size(1290, 519); + this.FormLocations.TabIndex = 2; + this.FormLocations.Text = "Form locations"; + this.FormLocations.UseVisualStyleBackColor = true; + // + // rtLocations + // + this.rtLocations.BackColor = System.Drawing.Color.Black; + this.rtLocations.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtLocations.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.rtLocations.ForeColor = System.Drawing.Color.Lime; + this.rtLocations.Location = new System.Drawing.Point(3, 3); + this.rtLocations.Name = "rtLocations"; + this.rtLocations.Size = new System.Drawing.Size(1284, 513); + this.rtLocations.TabIndex = 2; + this.rtLocations.Text = "aaaa"; + // + // tbpMap + // + this.tbpMap.Controls.Add(this.splitContainer2); + this.tbpMap.Location = new System.Drawing.Point(4, 22); + this.tbpMap.Name = "tbpMap"; + this.tbpMap.Size = new System.Drawing.Size(1290, 519); + this.tbpMap.TabIndex = 3; + this.tbpMap.Text = "Mapper"; + this.tbpMap.UseVisualStyleBackColor = true; + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.Location = new System.Drawing.Point(0, 0); + this.splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.pnlFunctoids); + this.splitContainer2.Size = new System.Drawing.Size(1290, 519); + this.splitContainer2.SplitterDistance = 430; + this.splitContainer2.TabIndex = 0; + // + // pnlFunctoids + // + this.pnlFunctoids.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlFunctoids.Location = new System.Drawing.Point(0, 0); + this.pnlFunctoids.Name = "pnlFunctoids"; + this.pnlFunctoids.Size = new System.Drawing.Size(430, 519); + this.pnlFunctoids.TabIndex = 0; + this.pnlFunctoids.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragDrop); + this.pnlFunctoids.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragEnter); + // + // trvTarget + // + this.trvTarget.Dock = System.Windows.Forms.DockStyle.Fill; + this.trvTarget.LineColor = System.Drawing.Color.Empty; + this.trvTarget.Location = new System.Drawing.Point(0, 0); + this.trvTarget.Name = "trvTarget"; + this.trvTarget.Size = new System.Drawing.Size(441, 519); + this.trvTarget.TabIndex = 1; + // + // X12UtilsFRM + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1298, 567); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.statusStrip1); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "X12UtilsFRM"; + this.Text = "Form1"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.X12UtilsFRM_FormClosing); + this.Load += new System.EventHandler(this.Form1_Load); + this.tabControl1.ResumeLayout(false); + this.parse.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.browser.ResumeLayout(false); + this.FormLocations.ResumeLayout(false); + this.tbpMap.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); + this.splitContainer2.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -388,11 +494,18 @@ private void InitializeComponent() { private System.Windows.Forms.Button btnParse; private System.Windows.Forms.WebBrowser webBrowser1; private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button btnFindSpec; - private System.Windows.Forms.Button btnHippaParse; - private System.Windows.Forms.TabPage tabPage1; - //private NLog.Windows.Forms.RichTextBoxTarget rtLog; - private System.Windows.Forms.RichTextBox rtLog; - } + private System.Windows.Forms.Button btnFindSpec; + private System.Windows.Forms.Button btnHippaParse; + private System.Windows.Forms.TabPage FormLocations; + //private NLog.Windows.Forms.RichTextBoxTarget rtLog; + private System.Windows.Forms.RichTextBox rtLog; + private System.Windows.Forms.RichTextBox rtLocations; + private System.Windows.Forms.Button btnMap; + private System.Windows.Forms.TabPage tbpMap; + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.TreeView trvTarget; + private System.Windows.Forms.CheckBox chkBrowse; + private System.Windows.Forms.Panel pnlFunctoids; + } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 2fbdc5b0..f5a4a8c1 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -1,287 +1,967 @@ -using System; +using NLog; +using NLog.Windows.Forms; +using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Data.SqlClient; +using System.Configuration; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.CompilerServices; using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; using System.Xml; -using NLog; -using NLog.Config; -using NLog.Targets; -using NLog.Windows.Forms; using X12.Hipaa.Claims; using X12.Hipaa.Claims.Services; using X12.Parsing; using X12.Shared.Models; using X12.Transformations; - -namespace X12UtilsFRM { - public enum enmTabPages { - parse, - browser - } - public partial class X12UtilsFRM : Form { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - List interchanges = null; - ToolTip tt = null; - - private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; - - static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") { - - Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); - Trace.Flush(); - } - - public string X12Tohtml(string x12) { - var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); - return htmlService.Transform(x12); - } - public string X12ToXml(string x12) { - using (MemoryStream memStream = new MemoryStream(1000)) { - interchanges.First().Serialize(memStream); - memStream.Seek(0, 0); - StreamReader sr = new StreamReader(memStream); - return sr.ReadToEnd(); - } - } - - public X12UtilsFRM() { - InitializeComponent(); - } - - protected override void OnLoad(EventArgs e) { - base.OnLoad(e); - - // Ensure RichTextBox target points to this form and control - //this also reroute the console to RTB - RichTextBoxTarget.ReInitializeAllTextboxes(this); - - // Test logging - Logger.Info("RichTextBox target initialized successfully, any existing Console logging will be routed to this RichTextBox "); - Logger.Debug("Debug message to RichTextBox"); - } - - protected override void OnShown(EventArgs e) { - base.OnShown(e); - RichTextBoxTarget.ReInitializeAllTextboxes(this); // In case form was not loaded when logging started */ - Logger.Info("RichTextBox logging attached (UI-safe)."); - } - - private void Form1_Load(object sender, EventArgs e) { - rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; - tt = new ToolTip(); - tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder} to the Listbox below.."); - if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) { - btnAddFiles_Click(null, null); - - } - lbxFileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); - btnParse.Enabled = false; - Logger.Trace("Trace message"); - Logger.Debug("Debug message"); - Logger.Info("Info message"); - Logger.Warn("Warning message"); - // Logger.Error("Error message"); - Logger.Fatal("Fatal message"); - } - - private void DisplayHtml(string html) { - - webBrowser1.Navigate("about:blank"); - webBrowser1.AllowWebBrowserDrop = false; - webBrowser1.AllowNavigation = false; - - try { - if (webBrowser1.Document != null) { - webBrowser1.Document.Write(string.Empty); - } - } catch (Exception e) { - - } - webBrowser1.DocumentText = html; - webBrowser1.AllowNavigation = true; - } - - private void displayPdf(string file) { - webBrowser1.AllowNavigation = true; - - if (this.webBrowser1.Document != null) { - this.webBrowser1.Navigate(file); - } - } - - private void rbXml_CheckedChanged(object sender, EventArgs e) { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - - private void rbHtml_CheckedChanged(object sender, EventArgs e) { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - - private void btnAddFiles_Click(object sender, EventArgs e) { - OpenFileDialog fd = new OpenFileDialog(); - fd.InitialDirectory = Properties.Settings.Default.X12Folder; - fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; - fd.FilterIndex = 0; - - lbxFileList.Items.Clear(); - lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); - lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); - string[] ss = new string[lbxFileList.Items.Count]; - lbxFileList.Items.CopyTo(ss, 0); - Properties.Settings.Default.fileList = String.Join(",", ss); - Properties.Settings.Default.Save(); - - - - - } - public string ContentFromFile(string filename/*fullPath*/) { - using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) { - return new StreamReader(filename).ReadToEnd(); - } - } - private Encoding GetEncoding(string fname) { - byte[] header = new byte[6]; - using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) { - fs.Read(header, 0, 6);// peak 6 characters to detemind encoding - fs.Close(); - } - return (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; - } - public string ReadFromStream(Stream strm) { - - // Log(strm.Position.ToString()); - - using (StreamReader sr = new StreamReader(strm)) - return sr.ReadToEnd(); - } - private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) { - string fileName = ((ListBox)sender).Text; - tt.SetToolTip(lbxFileList, fileName + " is Selected now.."); - - - lblSelectedFile.Text = Path.GetFileName(fileName); - Log($"fileName={fileName}"); - if (String.IsNullOrEmpty(fileName)) return;// can not parse empty file - - - bool throwException = Properties.Settings.Default.throwExceptions; - rtxInterchangeFile.Text = ContentFromFile(fileName); - - X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); - - parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); - - interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); - lblInterchangeCount.Text = interchanges.Count.ToString(); - - - - } - - private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args)// => throw new NotImplementedException(); - { - Log($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); - } - - private void lblInterchangeCount_TextChanged(object sender, EventArgs e) { - int fcount = int.Parse(((Label)sender).Text); - btnParse.Enabled = fcount == 1 ? true : false; - } - - private void btnParse_Click(object sender, EventArgs e) { - string x = ""; - switch (Properties.Settings.Default.TransformFormat) { - - case "HTML": - x = X12Tohtml(rtxInterchangeFile.Text); - break; - case "XML": - x = X12ToXml(rtxInterchangeFile.Text); - break; - } - DisplayHtml(x); - tabControl1.SelectedIndex = (int)enmTabPages.browser; - - } - - static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; - - - private void btnHippaParse_Click(object sender, EventArgs e) { - // C:\Temp is a standard folder for Windows. However, we'll - // want to verify that the \Pdfs folder exists and is empty - - // Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("X12.Hipaa.Tests.Unit.Claims.TestData.ProfessionalClaim1.txt"); - - //Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{lbxFileList.SelectedItem}"); - Stream stream = new FileStream($"{lbxFileList.SelectedItem}", FileMode.Open, FileAccess.Read); - - // new up a ClaimTransformationService object - var service = new ClaimFormTransformationService( - new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif"), - new InstitutionalClaimToUb04ClaimFormTransformation($"{TestImageDirectory}\\UB04_Red.gif"), - new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif")); - String outfile = $"{lbxFileList.SelectedItem}.pdf"; - try { - if (File.Exists(outfile)) - File.Delete(outfile); - } catch (Exception ex) { - MessageBox.Show($"Error deleting file {outfile}.\n{ex.Message}", "Error Deleting File", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - using (FileStream pdfoutput = new FileStream(outfile, FileMode.Create, FileAccess.Write)) { - ClaimDocument document = service.Transform837ToClaimDocument(stream); - var fonetDocument = new XmlDocument(); - string fonetXml = service.TransformClaimDocumentToFoXml(document); - fonetDocument.LoadXml(fonetXml); - Fonet.FonetDriver driver = Fonet.FonetDriver.Make(); - driver.CloseOnExit = true; - driver.Render(fonetDocument, pdfoutput); - pdfoutput.Close(); - } - string pdfout = $"file:///{outfile}"; - webBrowser1.Navigate(pdfout); - //displayPdf(pdfout); - } - - - private void btnFindSpec_Click(object sender, EventArgs e) { - var finder = new x12Test.specFinder(); - var spec = finder.FindTransactionSpec("SH", "005010X222A1", "856"); - Logger.Info($"Spec Found for 856: {spec?.Name}"); - - Logger.Trace("Trace message"); - Logger.Debug("Debug message"); - Logger.Info("Info message"); - Logger.Warn("Warning message"); - Logger.Error("Error message"); - Logger.Fatal("Fatal message"); - - if (spec != null) { - - MessageBox.Show($"Spec Found for 856: {spec.Name}"); - } else { - MessageBox.Show($"Spec Not Found for 856"); - } - } - } - } - +using static X12UtilsFRM.SkiaMapper; +using Label = System.Windows.Forms.Label; +using Rectangle = System.Drawing.Rectangle; + +namespace X12UtilsFRM +{ + public enum enmTabPages + { + parse, + browser, + formLocations, + map + } + public partial class X12UtilsFRM : Form + { + private List toolboxCategories = new List(); + private Panel pnlToolboxContainer = null; + + //-- DRAGGING STATE TRACKERS (CRITICAL for smooth UX) -- + private bool _isDraggingFunctoid = false; + private Point _dragStartMousePos; + private Point _dragStartControlPos; + //-- END DRAGGING STATE TRACKERS -- + + // This flat registry will hold every single node item for quick access during layout calculations and visibility checks + private List flatSchemaRegistry = new List(); + + // Define these class-level variables inside X12UtilsFRM.cs + private Panel pnlToolboxWrapper = null; + private FlowLayoutPanel pnlToolboxCategoriesContainer = null; + private Button btnToolboxToggle = null; + private bool _isToolboxExpanded = true; + private const int ToolboxWidth = 245; + + private void InitializeToolbox() + { + // 1. The main master wrapper panel pinned to the far right edge of the workspace canvas + pnlToolboxWrapper = new Panel + { + Width = ToolboxWidth + 20, + Location = new Point(pnlFunctoids.Width - (ToolboxWidth + 20), 0), + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right, + BackColor = Color.Transparent + }; + pnlFunctoids.Controls.Add(pnlToolboxWrapper); + pnlToolboxWrapper.BringToFront(); + + // 2. The thin, vertical toggle bar button + btnToolboxToggle = new Button + { + Text = "»", + Font = new Font("Segoe UI", 9, FontStyle.Bold), + Width = 20, + Dock = DockStyle.Left, + FlatStyle = FlatStyle.Flat, + BackColor = Color.FromArgb(220, 225, 235), + ForeColor = Color.FromArgb(50, 50, 80), + Cursor = Cursors.Hand + }; + btnToolboxToggle.FlatAppearance.BorderSize = 0; + btnToolboxToggle.Click += ToggleToolbox_Click; + pnlToolboxWrapper.Controls.Add(btnToolboxToggle); + + // 3. REVISED: Scrollable Flow Layout Container + pnlToolboxCategoriesContainer = new FlowLayoutPanel + { + Dock = DockStyle.Fill, + BackColor = Color.Transparent, + FlowDirection = FlowDirection.TopDown, // Force items to stack vertically + WrapContents = false, // Prevent side-by-side wrapping of categories + AutoScroll = true, // Automatically show vertical scrollbar when needed + Padding = new Padding(0, 20, 0, 0) // Top padding matching + }; + pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); + pnlToolboxCategoriesContainer.BringToFront(); + + // 4. Register your default operational utility items + var stringTools = new List { "Concatenate", "String Left", "String Right", "Trim", "Uppercase", "Lowercase" }; + var mathTools = new List { "Add", "Subtract", "Multiply", "Divide", "Modulus", "Absolute" }; + var dateTools = new List { "Current Date", "Date Format", "Add Days", "Date Diff" }; + + Action triggerLayoutUpdate = () => { RenderToolboxLayout(); }; + + toolboxCategories.Clear(); + toolboxCategories.Add(new ToolboxCategory("String Functoids", stringTools, triggerLayoutUpdate)); + toolboxCategories.Add(new ToolboxCategory("Mathematical Tools", mathTools, triggerLayoutUpdate)); + toolboxCategories.Add(new ToolboxCategory("Date / Time Utilities", dateTools, triggerLayoutUpdate)); + + RenderToolboxLayout(); + } + + private void RenderToolboxLayout() + { + if (pnlToolboxCategoriesContainer == null) return; + + pnlToolboxCategoriesContainer.SuspendLayout(); + pnlToolboxCategoriesContainer.Controls.Clear(); + + foreach (var category in toolboxCategories) + { + // 1. Give the category a solid fixed layout target width that leaves plenty of room + // for the parent container's scrollbar (ToolboxWidth is 245, so 215 works great) + category.Width = 215; + + // 2. Recalculate heights dynamically based on the newly assigned width bounds + category.UpdateHeight(); + + // 3. Apply standard column margins + category.Margin = new Padding(5, 0, 0, 8); + + pnlToolboxCategoriesContainer.Controls.Add(category); + } + + pnlToolboxCategoriesContainer.ResumeLayout(true); + } + private void ToggleToolbox_Click(object sender, EventArgs e) + { + _isToolboxExpanded = !_isToolboxExpanded; + + pnlFunctoids.SuspendLayout(); + + if (_isToolboxExpanded) + { + pnlToolboxWrapper.Width = ToolboxWidth + 20; + pnlToolboxWrapper.Location = new Point(pnlFunctoids.Width - pnlToolboxWrapper.Width, 0); + pnlToolboxCategoriesContainer.Visible = true; + btnToolboxToggle.Text = "»"; + + // Force the layout engine to recalculate child widths immediately upon expansion + RenderToolboxLayout(); + } + else + { + pnlToolboxCategoriesContainer.Visible = false; + pnlToolboxWrapper.Width = btnToolboxToggle.Width; + pnlToolboxWrapper.Location = new Point(pnlFunctoids.Width - pnlToolboxWrapper.Width, 0); + btnToolboxToggle.Text = "«"; + } + + pnlFunctoids.ResumeLayout(true); + _mapper.Invalidate(); + } + + + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + List interchanges = null; + ToolTip tt = null; + private string locationsFile = ""; + + private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; + static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; + static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") + { + + Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); + Trace.Flush(); + } + + private void MakeControlDraggable(Control masterControl) + { + // Route dragging events from the master wrapper panel container itself + AttachDragEvents(masterControl, masterControl); + + // Recursively bind child controls so clicking the text label or icon block drags the whole node! + foreach (Control child in masterControl.Controls) + { + AttachDragEvents(child, masterControl); + } + } + + private void AttachDragEvents(Control eventTriggerControl, Control actualMovingTarget) + { + eventTriggerControl.MouseDown += (sender, e) => + { + if (e.Button == MouseButtons.Left) + { + _isDraggingFunctoid = true; + _dragStartMousePos = Cursor.Position; + _dragStartControlPos = actualMovingTarget.Location; + actualMovingTarget.BringToFront(); + } + }; + + eventTriggerControl.MouseMove += (sender, e) => + { + if (_isDraggingFunctoid) + { + int deltaX = Cursor.Position.X - _dragStartMousePos.X; + int deltaY = Cursor.Position.Y - _dragStartMousePos.Y; + + actualMovingTarget.Location = new Point( + _dragStartControlPos.X + deltaX, + _dragStartControlPos.Y + deltaY + ); + + // Smoothly recalculate connection positions in real-time + _mapper.Invalidate(); + } + }; + + eventTriggerControl.MouseUp += (sender, e) => + { + if (e.Button == MouseButtons.Left) + { + _isDraggingFunctoid = false; + } + }; + } + + // Define this class-level variable at the top of X12UtilsFRM.cs + // private FlowLayoutPanel pnlSchemaScrollContainer = null; + private FlowLayoutPanel pnlSchemaScrollContainer = new FlowLayoutPanel + { + Name = "pnlSchemaScrollContainer", // CRITICAL: Allows SkiaMapper to instantly detect it + Width = 285, + Location = new Point(20, 20), + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left, + FlowDirection = FlowDirection.TopDown, + WrapContents = false, + AutoScroll = true, + BackColor = Color.Transparent + }; + private void InitializeEmbeddedSchemaLayout(string xmlFilePath) + { + pnlFunctoids.Controls.Clear(); + _mapper.Connections.Clear(); + flatSchemaRegistry.Clear(); + + pnlFunctoids.BackColor = Color.Transparent; + + // 1. Setup background Skia drawing canvas + _mapper.Dock = DockStyle.Fill; + pnlFunctoids.Controls.Add(_mapper); + _mapper.SendToBack(); + + // 2. NEW: Initialize the Scrollable Container for the Tree Column + pnlSchemaScrollContainer = new FlowLayoutPanel + { + Width = 285, // 260px node width + 25px for the vertical scrollbar buffer + Location = new Point(20, 20), + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left, + FlowDirection = FlowDirection.TopDown, // Stack nodes vertically + WrapContents = false, // Keep them in a single column + AutoScroll = true, // Enable the scrollbar! + BackColor = Color.Transparent // Let Skia lines show through behind it + }; + + + // Add this line immediately after setting up pnlSchemaScrollContainer in InitializeEmbeddedSchemaLayout: + pnlSchemaScrollContainer.Scroll += (s, e) => { _mapper.Invalidate(); }; + pnlFunctoids.Controls.Add(pnlSchemaScrollContainer); + pnlSchemaScrollContainer.BringToFront(); + + // 3. Load the XML schema data + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFilePath); + + BuildCustomSchemaTree(doc.DocumentElement, 0); + + // Render tree nodes inside our brand new scrollable lane + RenderCustomSchemaLayout(); + + // Initialize your right-hand toolbox panel + InitializeToolbox(); + + pnlFunctoids.AllowDrop = true; + _mapper.Invalidate(); + } + private void BuildCustomSchemaTree(XmlNode xmlNode, int indent, SchemaNodeItem parentItem = null) + { + if (xmlNode.NodeType != XmlNodeType.Element) return; + + var nodeItem = new SchemaNodeItem(xmlNode, indent, (clickedItem) => + { + // Redraw the entire layout configuration whenever a user collapses/expands a branch + RenderCustomSchemaLayout(); + _mapper.Invalidate(); + }); + + if (parentItem != null) + parentItem.ChildNodes.Add(nodeItem); + + flatSchemaRegistry.Add(nodeItem); + + foreach (XmlNode child in xmlNode.ChildNodes) + { + BuildCustomSchemaTree(child, indent + 1, nodeItem); + } + } + private void RenderCustomSchemaLayout() + { + if (pnlSchemaScrollContainer == null) return; + // Lock UI drawing updates temporarily to prevent visible scroll layout flickering + pnlSchemaScrollContainer.SuspendLayout(); + pnlSchemaScrollContainer.Controls.Clear(); + foreach (var item in flatSchemaRegistry) + { + if (IsNodeChainVisible(item)) + { + // Lock control item width slightly lower than the container size + // so the text doesn't slide under the scrollbar track + item.Width = pnlSchemaScrollContainer.Width - 25; + item.Margin = new Padding(0, 0, 0, 2); // Subtle horizontal row padding row gap + + pnlSchemaScrollContainer.Controls.Add(item); + } + } + pnlSchemaScrollContainer.ResumeLayout(true); + } + private bool IsNodeChainVisible(SchemaNodeItem item) + { + // Climb up the registry tree chain to see if any parent structural block is collapsed + var current = item; + while (current != null) + { + // Find who owns this child node in the flat registry list + var parent = flatSchemaRegistry.Find(p => p.ChildNodes.Contains(current)); + if (parent != null && !parent.IsExpanded) return false; + current = parent; + } + return true; + } + public string X12Tohtml(string x12) + { + var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); + return htmlService.Transform(x12); + } + public string X12ToXml(string x12) + { + using (MemoryStream memStream = new MemoryStream(1000)) + { + interchanges.First().Serialize(memStream); + memStream.Seek(0, 0); + StreamReader sr = new StreamReader(memStream); + return sr.ReadToEnd(); + } + } + + private SkiaMapper _mapper; + private void UpdateMap() + { // This is where you'd update the _mapper.Connections based on the current state of your UI controls + _mapper.Invalidate(); + } + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + // Ensure RichTextBox target points to this form and control + //this also reroute the console to RTB + RichTextBoxTarget.ReInitializeAllTextboxes(this); + + // Test logging + Logger.Info("RichTextBox target initialized successfully, any existing Console logging will be routed to this RichTextBox "); + Logger.Debug("Debug message to RichTextBox"); + } + protected override void OnShown(EventArgs e) + { + base.OnShown(e); + RichTextBoxTarget.ReInitializeAllTextboxes(this); // In case form was not loaded when logging started */ + Logger.Info("RichTextBox logging attached (UI-safe)."); + } + #region form + public X12UtilsFRM() + { + InitializeComponent(); + _mapper = new SkiaMapper(); + _mapper.Dock = DockStyle.Fill; + + // FIX: Add it to the specific Panel you created in the designer, + // NOT the SplitContainer.Panel2 directly. + if (this.pnlFunctoids != null) + { + this.pnlFunctoids.Controls.Add(_mapper); + _mapper.SendToBack(); + } + + this.pnlFunctoids.AllowDrop = true; + + } + + + private void Form1_Load(object sender, EventArgs e) + { + rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; + tt = new ToolTip(); + tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder} to the Listbox below.."); + if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) + { + btnAddFiles_Click(null, null); + + } + lbxFileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); + btnParse.Enabled = false; + Logger.Trace("Trace message"); + Logger.Debug("Debug message"); + Logger.Info("Info message"); + Logger.Warn("Warning message"); + // Logger.Error("Error message"); + Logger.Fatal("Fatal message"); + } + private void X12UtilsFRM_FormClosing(object sender, FormClosingEventArgs e) + { + Properties.Settings.Default.Save(); + } + #endregion form + private void DisplayHtml(string html) + { + + webBrowser1.Navigate("about:blank"); + webBrowser1.AllowWebBrowserDrop = false; + webBrowser1.AllowNavigation = false; + + try + { + if (webBrowser1.Document != null) + { + webBrowser1.Document.Write(string.Empty); + } + } + catch (Exception e) + { + + } + webBrowser1.DocumentText = html; + webBrowser1.AllowNavigation = true; + } + private void displayPdf(string file) + { + webBrowser1.AllowNavigation = true; + + if (this.webBrowser1.Document != null) + { + this.webBrowser1.Navigate(file); + } + } + private void rbXml_CheckedChanged(object sender, EventArgs e) + { + RadioButton r = (RadioButton)sender; + Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; + Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); + Properties.Settings.Default.Save(); + } + private void rbHtml_CheckedChanged(object sender, EventArgs e) + { + RadioButton r = (RadioButton)sender; + Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; + Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); + Properties.Settings.Default.Save(); + } + public string ContentFromFile(string filename/*fullPath*/) + { + using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) + { + return new StreamReader(filename).ReadToEnd(); + } + } + private Encoding GetEncoding(string fname) + { + byte[] header = new byte[6]; + using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) + { + fs.Read(header, 0, 6);// peak 6 characters to detemind encoding + fs.Close(); + } + return (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; + } + public string ReadFromStream(Stream strm) + { + + // Log(strm.Position.ToString()); + + using (StreamReader sr = new StreamReader(strm)) + return sr.ReadToEnd(); + } + private void lblInterchangeCount_TextChanged(object sender, EventArgs e) + { + int fcount = int.Parse(((Label)sender).Text); + btnParse.Enabled = fcount == 1 ? true : false; + } + private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) + { + string fileName = ((ListBox)sender).Text; + if (String.IsNullOrEmpty(fileName)) return; + tt.SetToolTip(lbxFileList, fileName + " is Selected now.."); + + if (chkBrowse.Checked) + { + switch (Path.GetExtension(fileName)) + { + case ".txt": + DisplayHtml(X12ToXml(ContentFromFile(fileName))); + break; + case ".xml": + DisplayHtml(ContentFromFile(fileName)); + tabControl1.SelectedIndex = (int)enmTabPages.browser; + break; + default: + break; + } + return; + } + + + + + + //lblSelectedFile.Text = Path.GetFileName(fileName); + //Log($"fileName={fileName}"); + + + + //bool throwException = Properties.Settings.Default.throwExceptions; + //rtxInterchangeFile.Text = ContentFromFile(fileName); + + //X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); + + //parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); + + //interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); + //lblInterchangeCount.Text = interchanges.Count.ToString(); + + + + } + private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args)// => throw new NotImplementedException(); + { + Log($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); + } + private void btnAddFiles_Click(object sender, EventArgs e) + { + OpenFileDialog fd = new OpenFileDialog(); + fd.InitialDirectory = Properties.Settings.Default.X12Folder; + fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; + fd.FilterIndex = 0; + + lbxFileList.Items.Clear(); + lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); + lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); + string[] ss = new string[lbxFileList.Items.Count]; + lbxFileList.Items.CopyTo(ss, 0); + Properties.Settings.Default.fileList = String.Join(",", ss); + Properties.Settings.Default.Save(); + + + + + } + #region buttons + private void btnParse_Click(object sender, EventArgs e) + { + string x = ""; + switch (Properties.Settings.Default.TransformFormat) + { + + case "HTML": + x = X12Tohtml(rtxInterchangeFile.Text); + break; + case "XML": + x = X12ToXml(rtxInterchangeFile.Text); + break; + } + DisplayHtml(x); + tabControl1.SelectedIndex = (int)enmTabPages.browser; + + } + private void btnFindSpec_Click(object sender, EventArgs e) + { + var finder = new x12Test.specFinder(); + var spec = finder.FindTransactionSpec("SH", "005010X222A1", "856"); + Logger.Info($"Spec Found for 856: {spec?.Name}"); + + Logger.Trace("Trace message"); + Logger.Debug("Debug message"); + Logger.Info("Info message"); + Logger.Warn("Warning message"); + Logger.Error("Error message"); + Logger.Fatal("Fatal message"); + + if (spec != null) + { + + MessageBox.Show($"Spec Found for 856: {spec.Name}"); + } + else + { + MessageBox.Show($"Spec Not Found for 856"); + } + } + private void btnHippaParse_Click(object sender, EventArgs e) + { + if (lbxFileList.SelectedItem == null) + { + MessageBox.Show("Please choose a file .."); + return; + } + Stream stream = new FileStream($"{lbxFileList.SelectedItem}", FileMode.Open, FileAccess.Read); + + + + // new up a ClaimTransformationService object + + InstitutionalClaimToUb04ClaimFormTransformation ict = new InstitutionalClaimToUb04ClaimFormTransformation($"{TestImageDirectory}\\UB04_Red.gif"); + + ict.DebugFile += Ict_DebugFile; + + ict.DebugFile += (s, file) => + { + try + { + Logger.Info($"Debug file generated: {file}"); + + this.locationsFile = file; + + this.Invoke((MethodInvoker)delegate + { + MessageBox.Show($"Found: {file}"); + }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(ex.Message); + } + }; + + var service = new ClaimFormTransformationService( + new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif"), + ict, + new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif")); + + + + String outfile = $"{lbxFileList.SelectedItem}.pdf"; + try + { + if (File.Exists(outfile)) + File.Delete(outfile); + } + catch (Exception ex) + { + MessageBox.Show($"Error deleting file {outfile}.\n{ex.Message}", "Error Deleting File", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + using (FileStream pdfoutput = new FileStream(outfile, FileMode.Create, FileAccess.Write)) + { + ClaimDocument document = service.Transform837ToClaimDocument(stream); + var fonetDocument = new XmlDocument(); + string fonetXml = service.TransformClaimDocumentToFoXml(document); + fonetDocument.LoadXml(fonetXml); + Fonet.FonetDriver driver = Fonet.FonetDriver.Make(); + driver.CloseOnExit = true; + driver.Render(fonetDocument, pdfoutput); + pdfoutput.Close(); + } + string pdfout = $"file:///{outfile}"; + webBrowser1.Navigate(pdfout); + tabControl1.SelectedTab = tabControl1.TabPages["browser"]; + + + } + + private void AddXmlNodes(XmlNode xmlNode, TreeNode treeNode) + { + // 1. Add Attributes first (BizTalk style shows these with a different icon/prefix) + if (xmlNode.Attributes != null) + { + foreach (XmlAttribute attr in xmlNode.Attributes) + { + TreeNode attrNode = new TreeNode("@" + attr.Name); + attrNode.Tag = attr; // Store the actual attribute object + attrNode.ForeColor = Color.DarkBlue; // Visual distinction + treeNode.Nodes.Add(attrNode); + } + } + + // 2. Add Child Elements + foreach (XmlNode childXmlNode in xmlNode.ChildNodes) + { + if (childXmlNode.NodeType == XmlNodeType.Element) + { + TreeNode childTreeNode = new TreeNode(childXmlNode.Name); + + // This is the key line you asked about: + childTreeNode.Tag = childXmlNode; + + treeNode.Nodes.Add(childTreeNode); + + // Recurse + AddXmlNodes(childXmlNode, childTreeNode); + } + } + } + + private TreeNode FindTreeNodeByTag(TreeNodeCollection nodes, object xmlNodeTarget) + { + foreach (TreeNode node in nodes) + { + if (node.Tag == xmlNodeTarget) + { + return node; + } + + // Deep search recursively through child branches + if (node.Nodes.Count > 0) + { + TreeNode found = FindTreeNodeByTag(node.Nodes, xmlNodeTarget); + if (found != null) return found; + } + } + return null; + } + private void LoadSchemaAsDiagramStart(string xmlFilePath) + { + if (!File.Exists(xmlFilePath)) + { + Logger.Warn($"Schema file not found: {xmlFilePath}"); + return; + } + + XmlDocument doc = new XmlDocument(); + doc.Load(xmlFilePath); + + // Clear out any previous dynamic mappings + pnlFunctoids.Controls.Clear(); + _mapper.Connections.Clear(); + + // Crucial: Re-add your SkiaMapper canvas so it remains the background! + pnlFunctoids.Controls.Add(_mapper); + _mapper.SendToBack(); + + // Start placing structural components at a fixed margin + int initialX = 20; // Left margin inside the panel + int initialY = 20; // Top margin inside the panel + int verticalSpacing = 45; // Space between each functoid block + + int currentY = initialY; + + // Loop through the main document segments (e.g., ISA, GS, ST, or Loops) + foreach (XmlNode childXmlNode in doc.DocumentElement.ChildNodes) + { + if (childXmlNode.NodeType == XmlNodeType.Element) + { + // 1. Automatically generate the Functoid Control UI + Point location = new Point(initialX, currentY); + Control functoidControl = CreateFunctoid(childXmlNode.Name, location); + + // 2. Add it to the panel + pnlFunctoids.Controls.Add(functoidControl); + functoidControl.BringToFront(); + + // 3. Find the matching TreeNode in trvSource to build the initial connection + // TreeNode matchingNode = FindTreeNodeByTag(trvSource.Nodes, childXmlNode); + + //if (matchingNode != null) + //{ + // // Auto-link the visual curve from the tree to the newly spawned functoid + // _mapper.Connections.Add(new MappingConnection + // { + // Source = matchingNode, + // Target = functoidControl + // }); + //} + + // Increment Y position for the next element block + currentY += verticalSpacing; + } + } + + // Force SkiaSharp to render all the newly created curves instantly + _mapper.Invalidate(); + Logger.Info("Input schema successfully mapped to diagram initialization state."); + } + private void btnMap_Click(object sender, EventArgs e) + { + string fileName = lbxFileList.Text; + if (Path.GetExtension(fileName) != ".xml") + { + MessageBox.Show("File extension must be an XML"); + return; + } + + // Shift focus straight to your Map workspace tab + _mapper.Invalidate(); + tabControl1.SelectedIndex = (int)enmTabPages.map; + + // Initialize our single embedded layout canvas—No more trvSource duplicate setup! + InitializeEmbeddedSchemaLayout(fileName); + } + #endregion buttons + private void Ict_DebugFile(object sender, string e) + + { + this.Text = $"Debug file generated: {e}"; + + } + private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) + { + Logger.Info($"tab={tabControl1.SelectedIndex} name={tabControl1.TabPages[tabControl1.SelectedIndex].Name}"); + switch (tabControl1.SelectedIndex) + { + case (int)enmTabPages.parse: + break; + case (int)enmTabPages.browser: + break; + case (int)enmTabPages.formLocations: + rtLocations.Text = File.Exists(locationsFile) ? File.ReadAllText(locationsFile) : $"Locations file not found: {locationsFile}"; + break; + case (int)enmTabPages.map: + + break; + } + } + #region treecontrols + private void trvSource_AfterSelect(object sender, TreeViewEventArgs e) + { + if (e.Node.Tag is XmlElement element) + { + Logger.Info($"Selected Element: {element.Name}, Path: {element.ParentNode?.Name}/{element.Name}"); + } + else if (e.Node.Tag is XmlAttribute attribute) + { + Logger.Info($"Selected Attribute: {attribute.Name}, Value: {attribute.Value}"); + } + } + + private void trvSource_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(typeof(TreeNode))) + { + // Sets the cursor to show a "Link" or "Copy" icon + e.Effect = DragDropEffects.Link; + } + else + { + // Keeps the cursor as "Not Allowed" + e.Effect = DragDropEffects.None; + } + } + + private void trvSource_ItemDrag(object sender, ItemDragEventArgs e) + { + // Cast dynamically so it works flawlessly for whichever TreeView fired it + if (sender is TreeView activeTree) + { + activeTree.SelectedNode = (TreeNode)e.Item; + Logger.Info($"Embedded tree item drag initiated: {activeTree.SelectedNode.Text}"); + activeTree.DoDragDrop(e.Item, DragDropEffects.Copy | DragDropEffects.Link); + } + } + + + #endregion treeControls + #region pnlFunctoids + private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) + { + // If this method name doesn't match the one in your Designer, the cursor won't change. + if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent("System.Windows.Forms.TreeNode")) + { + e.Effect = DragDropEffects.Link; + } + } + private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) + { + TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); + if (sourceNode == null) return; + + Point clientPoint = pnlFunctoids.PointToClient(new Point(e.X, e.Y)); + Control targetControl = pnlFunctoids.GetChildAtPoint(clientPoint); + + // 1. Guard against dropping directly onto structural UI boundaries + if (targetControl is SchemaNodeItem || + targetControl == pnlSchemaScrollContainer || + targetControl == pnlToolboxWrapper || + targetControl == pnlToolboxCategoriesContainer || + targetControl == btnToolboxToggle || + (pnlSchemaScrollContainer != null && pnlSchemaScrollContainer.Bounds.Contains(clientPoint)) || + (pnlToolboxWrapper != null && pnlToolboxWrapper.Bounds.Contains(clientPoint))) + { + return; + } + + // CASE A: Toolbox operational template drop (Spawns a new independent BizTalk capsule) + if (sourceNode.Tag as string == "FUNCTOID_TEMPLATE") + { + Control customFunctoidBlock = CreateFunctoid(sourceNode.Text, clientPoint); + pnlFunctoids.Controls.Add(customFunctoidBlock); + customFunctoidBlock.BringToFront(); + _mapper.Invalidate(); + return; + } + + // CASE B: Source Document Node Drag-Link + if (sourceNode.Tag is System.Xml.XmlNode realXmlNode) + { + // If dropped onto an empty canvas space or the Skia canvas background, spawn a target target block automatically + if (targetControl == null || targetControl is SkiaMapper) + { + targetControl = CreateFunctoid(sourceNode.Text, clientPoint); + pnlFunctoids.Controls.Add(targetControl); + targetControl.BringToFront(); + } + + // REVISED FOR PERSISTENCE: Anchor directly to the immutable underlying XmlNode! + // This ensures lines do not break when pnlSchemaScrollContainer updates its children. + _mapper.Connections.Add(new MappingConnection + { + Source = realXmlNode, + Target = targetControl + }); + + _mapper.Invalidate(); + } + } + #endregion pnlFunctoids + private Control CreateFunctoid(string text, Point location) + { + // Instantiation call utilizing our new BizTalk theme profile + BizTalkFunctoidNode functoidNode = new BizTalkFunctoidNode(text, location); + + // Bind dragging capabilities across all nested control elements + MakeControlDraggable(functoidNode); + + // Context Menu for right-click deletion + ContextMenuStrip functoidMenu = new ContextMenuStrip(); + var deleteItem = new ToolStripMenuItem("Delete Functoid"); + + deleteItem.Click += (sender, e) => + { + // Drop any connection link tracks tied to this node block + _mapper.Connections.RemoveAll(conn => conn.Target == functoidNode || conn.Source == functoidNode); + + pnlFunctoids.Controls.Remove(functoidNode); + functoidNode.Dispose(); + _mapper.Invalidate(); + }; + + functoidMenu.Items.Add(deleteItem); + + // Assign the deletion menu to the node layout wrapper and its children + functoidNode.ContextMenuStrip = functoidMenu; + functoidNode.LblIcon.ContextMenuStrip = functoidMenu; + functoidNode.LblText.ContextMenuStrip = functoidMenu; + + functoidNode.BringToFront(); + return functoidNode; + } + + } +} diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 90ce8d51..a0bdb7d3 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -27,6 +27,8 @@ false false true + + AnyCPU @@ -57,9 +59,46 @@ ..\packages\NLog.Windows.Forms.6.0.2\lib\net35\NLog.Windows.Forms.dll + + ..\packages\OpenTK.3.1.0\lib\net20\OpenTK.dll + + + ..\packages\OpenTK.GLControl.3.1.0\lib\net20\OpenTK.GLControl.dll + + + ..\packages\SkiaSharp.3.119.2\lib\net462\SkiaSharp.dll + + + ..\packages\SkiaSharp.Views.Desktop.Common.3.119.2\lib\net462\SkiaSharp.Views.Desktop.Common.dll + + + ..\packages\SkiaSharp.Views.WindowsForms.3.119.2\lib\net462\SkiaSharp.Views.WindowsForms.dll + + + C:\Users\tony\.nuget\packages\syncfusion.diagram.base\33.2.6\lib\net8.0-windows7.0\Design\WinForms\Syncfusion.Diagram.Base.Client.dll + + + C:\Users\tony\.nuget\packages\syncfusion.diagram.base\33.2.6\lib\net8.0-windows7.0\Design\WinForms\Syncfusion.Diagram.Base.Protocol.dll + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\packages\System.Configuration.ConfigurationManager.10.0.8\lib\net462\System.Configuration.ConfigurationManager.dll + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + @@ -71,7 +110,19 @@
+ + Component + + + Component + + + Component + + + Component + Form @@ -90,6 +141,9 @@ Resources.resx True + + SkiaMapper.cs + X12UtilsFRM.cs Designer @@ -97,6 +151,7 @@ PreserveNewest + SettingsSingleFileGenerator @@ -163,4 +218,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 22c85480..935065a9 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -123,7 +123,4 @@ 133, 17 - - 133, 17 - \ No newline at end of file diff --git a/X12UtilsFRM/packages.config b/X12UtilsFRM/packages.config index 541d0808..61c386e5 100644 --- a/X12UtilsFRM/packages.config +++ b/X12UtilsFRM/packages.config @@ -3,4 +3,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/X12.Hipaa/Claims/Services/CompilerAttributes.cs b/src/X12.Hipaa/Claims/Services/CompilerAttributes.cs new file mode 100644 index 00000000..2ca08f6e --- /dev/null +++ b/src/X12.Hipaa/Claims/Services/CompilerAttributes.cs @@ -0,0 +1,13 @@ +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] + public sealed class CallerArgumentExpressionAttribute : Attribute + { + public CallerArgumentExpressionAttribute(string parameterName) + { + ParameterName = parameterName; + } + + public string ParameterName { get; } + } +} \ No newline at end of file diff --git a/src/X12.Hipaa/Claims/Services/InstitutionalClaimToUB04ClaimFormTransformation.cs b/src/X12.Hipaa/Claims/Services/InstitutionalClaimToUB04ClaimFormTransformation.cs index 563e2878..ab03f197 100644 --- a/src/X12.Hipaa/Claims/Services/InstitutionalClaimToUB04ClaimFormTransformation.cs +++ b/src/X12.Hipaa/Claims/Services/InstitutionalClaimToUB04ClaimFormTransformation.cs @@ -4,24 +4,24 @@ using System.Collections.Generic; using System.Linq; using System.Text; - using X12.Hipaa.Claims.Forms; using X12.Hipaa.Claims.Forms.Institutional; using X12.Hipaa.Common; using X12.Hipaa.Enums; - + using System.Runtime.CompilerServices; + using System.IO; + using Microsoft.Extensions.Logging; + using NLog; public class InstitutionalClaimToUb04ClaimFormTransformation : IClaimToClaimFormTransfomation { + public event EventHandler DebugFile; private readonly string formImagePath; - - /// - /// Initializes a new instance of the class - /// - /// Form image path to be transformed + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); public InstitutionalClaimToUb04ClaimFormTransformation(string formImagePath) { this.formImagePath = formImagePath; this.PerPageTotalChargesView = false; + } public bool PerPageTotalChargesView { get; set; } @@ -382,15 +382,15 @@ public virtual UB04Claim TransformClaimToUB04(Claim claim) foreach (var line in claim.ServiceLines) { ub.ServiceLines.Add(new UB04ServiceLine - { - Field42_RevenueCode = line.RevenueCode, - Field43_Description = line.RevenueCodeDescription, - Field44_ProcedureCodes = SetProcedureCodeWithModifiers(line.Procedure), - Field45_ServiceDate = line.ServiceDateFrom > DateTime.MinValue ? $"{line.ServiceDateFrom:MMddyy}" : string.Empty, - Field46_ServiceUnits = line.Quantity.ToString(), - Field47_TotalCharges = line.ChargeAmount, - Field48_NonCoveredCharges = line.NonCoveredChargeAmount - }); + { + Field42_RevenueCode = line.RevenueCode, + Field43_Description = line.RevenueCodeDescription, + Field44_ProcedureCodes = SetProcedureCodeWithModifiers(line.Procedure), + Field45_ServiceDate = line.ServiceDateFrom > DateTime.MinValue ? $"{line.ServiceDateFrom:MMddyy}" : string.Empty, + Field46_ServiceUnits = line.Quantity.ToString(), + Field47_TotalCharges = line.ChargeAmount, + Field48_NonCoveredCharges = line.NonCoveredChargeAmount + }); } ub.Field47_Line23_TotalCharges = claim.TotalClaimChargeAmount; @@ -429,7 +429,7 @@ public virtual UB04Claim TransformClaimToUB04(Claim claim) var subscriber = claim.OtherSubscriberInformations[1]; SetOtherPayers(subscriber, ub); } - + var controlNumbers = claim.Identifications.Where(id => new[] { "F8", "D9", "9A", "9C", "LX" }.Contains(id.Qualifier)).ToList(); if (controlNumbers.Count > 0) { @@ -697,7 +697,7 @@ public virtual UB04Claim TransformClaimToUB04(Claim claim) } } } - + if (claim.Notes != null) { List remarksList = null; @@ -771,7 +771,7 @@ private static void LimitFieldWidths(UB04Claim ub) line.Field43_Description = SetStringLength(line.Field43_Description, 29); } } - + private static void SetOtherProviders(Provider provider, UB04Provider ub04Provider) { ub04Provider.Npi = SetStringLength(provider.Npi, 11); @@ -803,7 +803,7 @@ private static string SetStringLength(string source, int limit) return source.Length > limit ? source.Substring(0, limit) : source; } - private static void SetBillingProviderAddressDetails(UB04Claim ub, Provider provider,SubmitterInfo submitterinfo) + private static void SetBillingProviderAddressDetails(UB04Claim ub, Provider provider, SubmitterInfo submitterinfo) { if (provider?.Address == null) { @@ -824,8 +824,8 @@ private static void SetBillingProviderAddressDetails(UB04Claim ub, Provider prov if (string.IsNullOrEmpty(ub.Field01_BillingProvider.Line4)) { - if (submitterinfo?.Providers != null && - submitterinfo.Providers.Contacts.Count > 0 && + if (submitterinfo?.Providers != null && + submitterinfo.Providers.Contacts.Count > 0 && submitterinfo.Providers.Contacts[0].Numbers.Count > 0) { ub.Field01_BillingProvider.Line4 = submitterinfo.Providers.Contacts[0].Numbers[0].Number; @@ -872,79 +872,79 @@ private static void SetOtherPayers(OtherSubscriberInformation subscriber, UB04Cl switch (subscriber.SubscriberInformation.PayerResponsibilitySequenceNumberCode) { case "P": - { - if (subscriber.OtherPayer != null) { - ub.PayerA_Primary.Field50_PayerName = SetStringLength(subscriber.OtherPayer.Formatted(), 26); - ub.PayerA_Primary.Field51_HealthPlanId = SetStringLength(subscriber.OtherPayer.Identification.Id, 17); - if (!string.IsNullOrEmpty(subscriber.OtherPayer.PriorAuthorizationNumber)) + if (subscriber.OtherPayer != null) { - ub.Field63A_TreatmentAuthorizationCode = SetStringLength(subscriber.OtherPayer.PriorAuthorizationNumber, 34); + ub.PayerA_Primary.Field50_PayerName = SetStringLength(subscriber.OtherPayer.Formatted(), 26); + ub.PayerA_Primary.Field51_HealthPlanId = SetStringLength(subscriber.OtherPayer.Identification.Id, 17); + if (!string.IsNullOrEmpty(subscriber.OtherPayer.PriorAuthorizationNumber)) + { + ub.Field63A_TreatmentAuthorizationCode = SetStringLength(subscriber.OtherPayer.PriorAuthorizationNumber, 34); + } } - } - ub.PayerA_Primary.Field52_ReleaseOfInfoCertIndicator = subscriber.ReleaseOfInformationCode; - ub.PayerA_Primary.Field53_AssignmentOfBenefitsCertIndicator = subscriber.BenefitsAssignmentCertificationIndicator; - ub.PayerA_Primary.Field54_PriorPayments = subscriber.PayorPaidAmount; - ub.PayerA_Primary.Field55_EstimatedAmountDue = subscriber.RemainingPatientLiability; - - ub.PayerA_Primary.Field58_InsuredsName = SetStringLength(subscriber.Name.Formatted(), 29); - ub.PayerA_Primary.Field59_PatientRelationship = subscriber.SubscriberInformation.IndividualRelationshipCode; - ub.PayerA_Primary.Field60_InsuredsUniqueId = SetStringLength(subscriber.Name.Identification.Id, 23); - ub.PayerA_Primary.Field61_GroupName = SetStringLength(subscriber.SubscriberInformation.Name, 17); - ub.PayerA_Primary.Field62_InsuredsGroupNumber = SetStringLength(subscriber.SubscriberInformation.ReferenceIdentification, 21); - break; - } + ub.PayerA_Primary.Field52_ReleaseOfInfoCertIndicator = subscriber.ReleaseOfInformationCode; + ub.PayerA_Primary.Field53_AssignmentOfBenefitsCertIndicator = subscriber.BenefitsAssignmentCertificationIndicator; + ub.PayerA_Primary.Field54_PriorPayments = subscriber.PayorPaidAmount; + ub.PayerA_Primary.Field55_EstimatedAmountDue = subscriber.RemainingPatientLiability; + + ub.PayerA_Primary.Field58_InsuredsName = SetStringLength(subscriber.Name.Formatted(), 29); + ub.PayerA_Primary.Field59_PatientRelationship = subscriber.SubscriberInformation.IndividualRelationshipCode; + ub.PayerA_Primary.Field60_InsuredsUniqueId = SetStringLength(subscriber.Name.Identification.Id, 23); + ub.PayerA_Primary.Field61_GroupName = SetStringLength(subscriber.SubscriberInformation.Name, 17); + ub.PayerA_Primary.Field62_InsuredsGroupNumber = SetStringLength(subscriber.SubscriberInformation.ReferenceIdentification, 21); + break; + } case "S": - { - if (subscriber.OtherPayer != null) { - ub.PayerB_Secondary.Field50_PayerName = SetStringLength(subscriber.OtherPayer.Formatted(), 26); - ub.PayerB_Secondary.Field51_HealthPlanId = SetStringLength(subscriber.OtherPayer.Identification.Id, 17); - if (!string.IsNullOrEmpty(subscriber.OtherPayer.PriorAuthorizationNumber)) + if (subscriber.OtherPayer != null) { - ub.Field63B_TreatmentAuthorizationCode = SetStringLength(subscriber.OtherPayer.PriorAuthorizationNumber, 34); + ub.PayerB_Secondary.Field50_PayerName = SetStringLength(subscriber.OtherPayer.Formatted(), 26); + ub.PayerB_Secondary.Field51_HealthPlanId = SetStringLength(subscriber.OtherPayer.Identification.Id, 17); + if (!string.IsNullOrEmpty(subscriber.OtherPayer.PriorAuthorizationNumber)) + { + ub.Field63B_TreatmentAuthorizationCode = SetStringLength(subscriber.OtherPayer.PriorAuthorizationNumber, 34); + } } - } - ub.PayerB_Secondary.Field52_ReleaseOfInfoCertIndicator = subscriber.ReleaseOfInformationCode; - ub.PayerB_Secondary.Field53_AssignmentOfBenefitsCertIndicator = subscriber.BenefitsAssignmentCertificationIndicator; - ub.PayerB_Secondary.Field54_PriorPayments = subscriber.PayorPaidAmount; - ub.PayerB_Secondary.Field55_EstimatedAmountDue = subscriber.RemainingPatientLiability; - - ub.PayerB_Secondary.Field58_InsuredsName = SetStringLength(subscriber.Name.Formatted(), 29); - ub.PayerB_Secondary.Field59_PatientRelationship = subscriber.SubscriberInformation.IndividualRelationshipCode; - ub.PayerB_Secondary.Field60_InsuredsUniqueId = SetStringLength(subscriber.Name.Identification.Id, 23); - ub.PayerB_Secondary.Field61_GroupName = SetStringLength(subscriber.SubscriberInformation.Name, 17); - ub.PayerB_Secondary.Field62_InsuredsGroupNumber = SetStringLength(subscriber.SubscriberInformation.ReferenceIdentification, 21); - break; - } + ub.PayerB_Secondary.Field52_ReleaseOfInfoCertIndicator = subscriber.ReleaseOfInformationCode; + ub.PayerB_Secondary.Field53_AssignmentOfBenefitsCertIndicator = subscriber.BenefitsAssignmentCertificationIndicator; + ub.PayerB_Secondary.Field54_PriorPayments = subscriber.PayorPaidAmount; + ub.PayerB_Secondary.Field55_EstimatedAmountDue = subscriber.RemainingPatientLiability; + + ub.PayerB_Secondary.Field58_InsuredsName = SetStringLength(subscriber.Name.Formatted(), 29); + ub.PayerB_Secondary.Field59_PatientRelationship = subscriber.SubscriberInformation.IndividualRelationshipCode; + ub.PayerB_Secondary.Field60_InsuredsUniqueId = SetStringLength(subscriber.Name.Identification.Id, 23); + ub.PayerB_Secondary.Field61_GroupName = SetStringLength(subscriber.SubscriberInformation.Name, 17); + ub.PayerB_Secondary.Field62_InsuredsGroupNumber = SetStringLength(subscriber.SubscriberInformation.ReferenceIdentification, 21); + break; + } case "T": - { - if (subscriber.OtherPayer != null) { - ub.PayerC_Tertiary.Field50_PayerName = SetStringLength(subscriber.OtherPayer.Formatted(), 26); - ub.PayerC_Tertiary.Field51_HealthPlanId = SetStringLength(subscriber.OtherPayer.Identification.Id, 17); - if (!string.IsNullOrEmpty(subscriber.OtherPayer.PriorAuthorizationNumber)) + if (subscriber.OtherPayer != null) { - ub.Field63C_TreatmentAuthorizationCode = SetStringLength(subscriber.OtherPayer.PriorAuthorizationNumber, 34); + ub.PayerC_Tertiary.Field50_PayerName = SetStringLength(subscriber.OtherPayer.Formatted(), 26); + ub.PayerC_Tertiary.Field51_HealthPlanId = SetStringLength(subscriber.OtherPayer.Identification.Id, 17); + if (!string.IsNullOrEmpty(subscriber.OtherPayer.PriorAuthorizationNumber)) + { + ub.Field63C_TreatmentAuthorizationCode = SetStringLength(subscriber.OtherPayer.PriorAuthorizationNumber, 34); + } } - } - ub.PayerC_Tertiary.Field52_ReleaseOfInfoCertIndicator = subscriber.ReleaseOfInformationCode; - ub.PayerC_Tertiary.Field53_AssignmentOfBenefitsCertIndicator = subscriber.BenefitsAssignmentCertificationIndicator; - ub.PayerC_Tertiary.Field54_PriorPayments = subscriber.PayorPaidAmount; - ub.PayerC_Tertiary.Field55_EstimatedAmountDue = subscriber.RemainingPatientLiability; - - ub.PayerC_Tertiary.Field58_InsuredsName = SetStringLength(subscriber.Name.Formatted(), 29); - ub.PayerC_Tertiary.Field59_PatientRelationship = subscriber.SubscriberInformation.IndividualRelationshipCode; - ub.PayerC_Tertiary.Field60_InsuredsUniqueId = SetStringLength(subscriber.Name.Identification.Id, 23); - ub.PayerC_Tertiary.Field61_GroupName = SetStringLength(subscriber.SubscriberInformation.Name, 17); - ub.PayerC_Tertiary.Field62_InsuredsGroupNumber = SetStringLength(subscriber.SubscriberInformation.ReferenceIdentification, 21); - break; - } + ub.PayerC_Tertiary.Field52_ReleaseOfInfoCertIndicator = subscriber.ReleaseOfInformationCode; + ub.PayerC_Tertiary.Field53_AssignmentOfBenefitsCertIndicator = subscriber.BenefitsAssignmentCertificationIndicator; + ub.PayerC_Tertiary.Field54_PriorPayments = subscriber.PayorPaidAmount; + ub.PayerC_Tertiary.Field55_EstimatedAmountDue = subscriber.RemainingPatientLiability; + + ub.PayerC_Tertiary.Field58_InsuredsName = SetStringLength(subscriber.Name.Formatted(), 29); + ub.PayerC_Tertiary.Field59_PatientRelationship = subscriber.SubscriberInformation.IndividualRelationshipCode; + ub.PayerC_Tertiary.Field60_InsuredsUniqueId = SetStringLength(subscriber.Name.Identification.Id, 23); + ub.PayerC_Tertiary.Field61_GroupName = SetStringLength(subscriber.SubscriberInformation.Name, 17); + ub.PayerC_Tertiary.Field62_InsuredsGroupNumber = SetStringLength(subscriber.SubscriberInformation.ReferenceIdentification, 21); + break; + } } } @@ -1062,10 +1062,11 @@ private static string SetProcedureCodeWithModifiers(MedicalProcedure procedure) return procedureCode.ToString(); } - - private static FormBlock AddBlock(FormPage page, decimal x, decimal y, decimal width, string text, TextAlign textAlign = TextAlign.left) + + private static FormBlock AddBlock(FormPage page, decimal x, decimal y, decimal width, string text, TextAlign textAlign = TextAlign.left, [CallerArgumentExpression("text")] string expressionPath = "",string debugOutFileName="") { - decimal xScale = 0.08333m; + + decimal xScale = 0.08333m; decimal yScale = 0.16667m; var block = new FormBlock { @@ -1075,13 +1076,23 @@ private static FormBlock AddBlock(FormPage page, decimal x, decimal y, decimal w Width = xScale * width, Height = yScale * 1.1m, Text = text - }; + }; + + logger.Log(NLog.LogLevel.Info,$"Adding block at x:{x}, y:{y}, width:{width} with text:'{text}' for expression {expressionPath}"); + + + System.IO.File.AppendAllText(debugOutFileName, $"{x,-6},\t{y,-6},\tLeft:{block.Left}\tTop:{block.Top}\t{expressionPath}:{text}{Environment.NewLine}"); + page.Blocks.Add(block); return block; } - + public virtual List TransformUb04ToFormPages(UB04Claim ub04) { + string fn = Path.Combine(Path.GetTempPath(),"debug.txt"); + + + if( System.IO.File.Exists(fn)) System.IO.File.Delete(fn); List pages = new List(); int pageCount = 1 + ((ub04.ServiceLines.Count - 1) / 22); FormPage page = null; @@ -1098,163 +1109,155 @@ public virtual List TransformUb04ToFormPages(UB04Claim ub04) // header // Box 1 - AddBlock(page, 2, 1, 28, ub04.Field01_BillingProvider.Line1); - AddBlock(page, 2, 2, 28, ub04.Field01_BillingProvider.Line2); - AddBlock(page, 2, 3, 28, ub04.Field01_BillingProvider.Line3); - AddBlock(page, 2, 4, 28, ub04.Field01_BillingProvider.Line4); - + AddBlock(page, 2, 1, 28, ub04.Field01_BillingProvider.Line1,debugOutFileName:fn); + AddBlock(page, 2, 2, 28, ub04.Field01_BillingProvider.Line2,debugOutFileName:fn); + AddBlock(page, 2, 3, 28, ub04.Field01_BillingProvider.Line3,debugOutFileName:fn); + AddBlock(page, 2, 4, 28, ub04.Field01_BillingProvider.Line4,debugOutFileName:fn); + // Box 2 - AddBlock(page, 32, 1, 28, ub04.Field02_PayToProvider.Line1); - AddBlock(page, 32, 2, 28, ub04.Field02_PayToProvider.Line2); - AddBlock(page, 32, 3, 28, ub04.Field02_PayToProvider.Line3); - AddBlock(page, 32, 4, 28, ub04.Field02_PayToProvider.Line4); + AddBlock(page, 32, 1, 28, ub04.Field02_PayToProvider.Line1,debugOutFileName:fn); + AddBlock(page, 32, 2, 28, ub04.Field02_PayToProvider.Line2,debugOutFileName:fn); + AddBlock(page, 32, 3, 28, ub04.Field02_PayToProvider.Line3,debugOutFileName:fn); + AddBlock(page, 32, 4, 28, ub04.Field02_PayToProvider.Line4,debugOutFileName:fn); // Box 3 - AddBlock(page, 65, 1, 27, ub04.Field03a_PatientControlNumber); - AddBlock(page, 65, 2, 27, ub04.Field03b_MedicalRecordNumber); - + AddBlock(page, 65, 1, 27, ub04.Field03a_PatientControlNumber,debugOutFileName:fn); + AddBlock(page, 65, 2, 27, ub04.Field03b_MedicalRecordNumber,debugOutFileName:fn); + // Box 4 - AddBlock(page, 94, 2, 5, ub04.Field04_TypeOfBill); - + AddBlock(page, 94, 2, 5, ub04.Field04_TypeOfBill,debugOutFileName:fn); + // Box 5 - AddBlock(page, 62, 4, 10, ub04.Field05_FederalTaxId); + AddBlock(page, 62, 4, 10, ub04.Field05_FederalTaxId,debugOutFileName:fn); // Box 6 - Statement Covers Period - AddBlock(page, 74, 4, 9, ub04.Field06_StatementCoversPeriod.FromDate); - AddBlock(page, 82, 4, 9, ub04.Field06_StatementCoversPeriod.ThroughDate); - + AddBlock(page, 74, 4, 9, ub04.Field06_StatementCoversPeriod.FromDate,debugOutFileName:fn); + AddBlock(page, 82, 4, 9, ub04.Field06_StatementCoversPeriod.ThroughDate,debugOutFileName:fn); // Box 7 - Blank - AddBlock(page, 91, 3, 8, ub04.Field07.Line1); - AddBlock(page, 91, 4, 8, ub04.Field07.Line2); + AddBlock(page, 91, 3, 8, ub04.Field07.Line1,debugOutFileName:fn); + AddBlock(page, 91, 4, 8, ub04.Field07.Line2,debugOutFileName:fn); // Box 8 - AddBlock(page, 15, 5, 21, ub04.Field08_PatientName_a); - AddBlock(page, 3, 6, 33, ub04.Field08_PatientName_b); - + AddBlock(page, 15, 5, 21, ub04.Field08_PatientName_a,debugOutFileName:fn); + AddBlock(page, 3, 6, 33, ub04.Field08_PatientName_b,debugOutFileName:fn); // Box 9 - AddBlock(page, 51, 5, 48, ub04.Field09_PatientAddress.a_Street); - AddBlock(page, 39, 6, 37, ub04.Field09_PatientAddress.b_City); - AddBlock(page, 78, 6, 2, ub04.Field09_PatientAddress.c_State); - AddBlock(page, 83, 6, 10, ub04.Field09_PatientAddress.d_PostalCode); - AddBlock(page, 96, 6, 3, ub04.Field09_PatientAddress.e_CountryCode); + AddBlock(page, 51, 5, 48, ub04.Field09_PatientAddress.a_Street,debugOutFileName:fn); + AddBlock(page, 39, 6, 37, ub04.Field09_PatientAddress.b_City,debugOutFileName:fn); + AddBlock(page, 78, 6, 2, ub04.Field09_PatientAddress.c_State,debugOutFileName:fn); + AddBlock(page, 83, 6, 10, ub04.Field09_PatientAddress.d_PostalCode,debugOutFileName:fn); + AddBlock(page, 96, 6, 3, ub04.Field09_PatientAddress.e_CountryCode,debugOutFileName:fn); // Box 10 - AddBlock(page, 2, 8, 8, ub04.Field10_Birthdate); - + AddBlock(page, 2, 8, 8, ub04.Field10_Birthdate,debugOutFileName:fn); // Box 11 - AddBlock(page, 13, 8, 1, ub04.Field11_Sex); + AddBlock(page, 13, 8, 1, ub04.Field11_Sex,debugOutFileName:fn); // Box 12-15 - AddBlock(page, 16, 8, 6, ub04.Field12_AdmissionDate); - AddBlock(page, 23, 8, 2, ub04.Field13_AdmissionHour); - AddBlock(page, 27, 8, 2, ub04.Field14_AdmissionType); - AddBlock(page, 30, 8, 2, ub04.Field15_AdmissionSource); + AddBlock(page, 16, 8, 6, ub04.Field12_AdmissionDate,debugOutFileName:fn); + AddBlock(page, 23, 8, 2, ub04.Field13_AdmissionHour,debugOutFileName:fn); + AddBlock(page, 27, 8, 2, ub04.Field14_AdmissionType,debugOutFileName:fn); + AddBlock(page, 30, 8, 2, ub04.Field15_AdmissionSource,debugOutFileName:fn); // Box 16 - AddBlock(page, 34, 8, 2, ub04.Field16_DischargeHour); + AddBlock(page, 34, 8, 2, ub04.Field16_DischargeHour,debugOutFileName:fn); // Box 17 - AddBlock(page, 38, 8, 2, ub04.Field17_DischargeStatus); - - // Box 18 - 28 Condition Codes - AddBlock(page, 41, 8, 2, ub04.Field18_ConditionCode01); - AddBlock(page, 45, 8, 2, ub04.Field19_ConditionCode02); - AddBlock(page, 48, 8, 2, ub04.Field20_ConditionCode03); - AddBlock(page, 52, 8, 2, ub04.Field21_ConditionCode04); - AddBlock(page, 56, 8, 2, ub04.Field22_ConditionCode05); - AddBlock(page, 59, 8, 2, ub04.Field23_ConditionCode06); - AddBlock(page, 63, 8, 2, ub04.Field24_ConditionCode07); - AddBlock(page, 66, 8, 2, ub04.Field25_ConditionCode08); - AddBlock(page, 70, 8, 2, ub04.Field26_ConditionCode09); - AddBlock(page, 73.5m, 8, 2, ub04.Field27_ConditionCode10); - AddBlock(page, 77, 8, 2, ub04.Field28_ConditionCode11); + AddBlock(page, 38, 8, 2, ub04.Field17_DischargeStatus,debugOutFileName:fn); + // Box 18 - 28 Condition Codes + AddBlock(page, 41, 8, 2, ub04.Field18_ConditionCode01,debugOutFileName:fn); + AddBlock(page, 45, 8, 2, ub04.Field19_ConditionCode02,debugOutFileName:fn); + AddBlock(page, 48, 8, 2, ub04.Field20_ConditionCode03,debugOutFileName:fn); + AddBlock(page, 52, 8, 2, ub04.Field21_ConditionCode04,debugOutFileName:fn); + AddBlock(page, 56, 8, 2, ub04.Field22_ConditionCode05,debugOutFileName:fn); + AddBlock(page, 59, 8, 2, ub04.Field23_ConditionCode06,debugOutFileName:fn ); + AddBlock(page, 63, 8, 2, ub04.Field24_ConditionCode07,debugOutFileName:fn); + AddBlock(page, 66, 8, 2, ub04.Field25_ConditionCode08,debugOutFileName:fn); + AddBlock(page, 70, 8, 2, ub04.Field26_ConditionCode09,debugOutFileName:fn); + AddBlock(page, 73.5m, 8, 2, ub04.Field27_ConditionCode10,debugOutFileName:fn); + AddBlock(page, 77, 8, 2, ub04.Field28_ConditionCode11,debugOutFileName:fn); // Box 29 - AddBlock(page, 81, 8, 2, ub04.Field29_AccidentState); - + AddBlock(page, 81, 8, 2, ub04.Field29_AccidentState,debugOutFileName:fn); + // Box 30 - AddBlock(page, 85, 8, 14, ub04.Field30); + AddBlock(page, 85, 8, 14, ub04.Field30,debugOutFileName:fn); // Box 31 - AddBlock(page, 2, 10, 2, ub04.Field31a_Occurrence.Code); - AddBlock(page, 6, 10, 6, ub04.Field31a_Occurrence.Date); - AddBlock(page, 2, 11, 2, ub04.Field31b_Occurrence.Code); - AddBlock(page, 6, 11, 6, ub04.Field31b_Occurrence.Date); + AddBlock(page, 2, 10, 2, ub04.Field31a_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 6, 10, 6, ub04.Field31a_Occurrence.Date,debugOutFileName:fn); + AddBlock(page, 2, 11, 2, ub04.Field31b_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 6, 11, 6, ub04.Field31b_Occurrence.Date,debugOutFileName:fn); - // Box 32 - AddBlock(page, 14, 10, 2, ub04.Field32a_Occurrence.Code); - AddBlock(page, 18, 10, 6, ub04.Field32a_Occurrence.Date); - AddBlock(page, 14, 11, 2, ub04.Field32b_Occurrence.Code); - AddBlock(page, 18, 11, 6, ub04.Field32b_Occurrence.Date); + // Box 32 + AddBlock(page, 14, 10, 2, ub04.Field32a_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 18, 10, 6, ub04.Field32a_Occurrence.Date,debugOutFileName:fn); + AddBlock(page, 14, 11, 2, ub04.Field32b_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 18, 11, 6, ub04.Field32b_Occurrence.Date,debugOutFileName:fn); // Box 33 - AddBlock(page, 26, 10, 2, ub04.Field33a_Occurrence.Code); - AddBlock(page, 30, 10, 6, ub04.Field33a_Occurrence.Date); - AddBlock(page, 26, 11, 2, ub04.Field33b_Occurrence.Code); - AddBlock(page, 30, 11, 6, ub04.Field33b_Occurrence.Date); + AddBlock(page, 26, 10, 2, ub04.Field33a_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 30, 10, 6, ub04.Field33a_Occurrence.Date,debugOutFileName:fn); + AddBlock(page, 26, 11, 2, ub04.Field33b_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 30, 11, 6, ub04.Field33b_Occurrence.Date,debugOutFileName:fn); // Box 34 - AddBlock(page, 38, 10, 2, ub04.Field34a_Occurrence.Code); - AddBlock(page, 41, 10, 6, ub04.Field34a_Occurrence.Date); - AddBlock(page, 38, 11, 2, ub04.Field34b_Occurrence.Code); - AddBlock(page, 41, 11, 6, ub04.Field34b_Occurrence.Date); + AddBlock(page, 38, 10, 2, ub04.Field34a_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 41, 10, 6, ub04.Field34a_Occurrence.Date,debugOutFileName:fn); + AddBlock(page, 38, 11, 2, ub04.Field34b_Occurrence.Code,debugOutFileName:fn); + AddBlock(page, 41, 11, 6, ub04.Field34b_Occurrence.Date,debugOutFileName:fn); // Box 35 - AddBlock(page, 50, 10, 2, ub04.Field35a_OccurrenceSpan.Code); - AddBlock(page, 53, 10, 6, ub04.Field35a_OccurrenceSpan.FromDate); - AddBlock(page, 62, 10, 6, ub04.Field35a_OccurrenceSpan.ThroughDate); - AddBlock(page, 50, 11, 2, ub04.Field35b_OccurrenceSpan.Code); - AddBlock(page, 53, 11, 6, ub04.Field35b_OccurrenceSpan.FromDate); - AddBlock(page, 62, 11, 6, ub04.Field35b_OccurrenceSpan.ThroughDate); + AddBlock(page, 50, 10, 2, ub04.Field35a_OccurrenceSpan.Code,debugOutFileName:fn); + AddBlock(page, 53, 10, 6, ub04.Field35a_OccurrenceSpan.FromDate,debugOutFileName:fn); + AddBlock(page, 62, 10, 6, ub04.Field35a_OccurrenceSpan.ThroughDate,debugOutFileName:fn); + AddBlock(page, 50, 11, 2, ub04.Field35b_OccurrenceSpan.Code,debugOutFileName:fn); + AddBlock(page, 53, 11, 6, ub04.Field35b_OccurrenceSpan.FromDate,debugOutFileName:fn); + AddBlock(page, 62, 11, 6, ub04.Field35b_OccurrenceSpan.ThroughDate,debugOutFileName:fn); // Box 36 - AddBlock(page, 70, 10, 2, ub04.Field36a_OccurrenceSpan.Code); - AddBlock(page, 74, 10, 6, ub04.Field36a_OccurrenceSpan.FromDate); - AddBlock(page, 82, 10, 6, ub04.Field36a_OccurrenceSpan.ThroughDate); - AddBlock(page, 70, 11, 2, ub04.Field36b_OccurrenceSpan.Code); - AddBlock(page, 74, 11, 6, ub04.Field36b_OccurrenceSpan.FromDate); - AddBlock(page, 82, 11, 6, ub04.Field36b_OccurrenceSpan.ThroughDate); + AddBlock(page, 70, 10, 2, ub04.Field36a_OccurrenceSpan.Code,debugOutFileName:fn); + AddBlock(page, 74, 10, 6, ub04.Field36a_OccurrenceSpan.FromDate,debugOutFileName:fn); + AddBlock(page, 82, 10, 6, ub04.Field36a_OccurrenceSpan.ThroughDate,debugOutFileName:fn); + AddBlock(page, 70, 11, 2, ub04.Field36b_OccurrenceSpan.Code,debugOutFileName:fn); + AddBlock(page, 74, 11, 6, ub04.Field36b_OccurrenceSpan.FromDate,debugOutFileName:fn); + AddBlock(page, 82, 11, 6, ub04.Field36b_OccurrenceSpan.ThroughDate,debugOutFileName:fn); // Box 37 - Blank - AddBlock(page, 90, 10, 9, ub04.Field37.Line1); - AddBlock(page, 90, 11, 9, ub04.Field37.Line2); - + AddBlock(page, 90, 10, 9, ub04.Field37.Line1,debugOutFileName:fn); + AddBlock(page, 90, 11, 9, ub04.Field37.Line2,debugOutFileName:fn); // Box 38 - Responsible Party - AddBlock(page, 2, 12, 48, ub04.Field38_ResponsibleParty.Line1); - AddBlock(page, 2, 13, 48, ub04.Field38_ResponsibleParty.Line2); - AddBlock(page, 2, 14, 48, ub04.Field38_ResponsibleParty.Line3); - AddBlock(page, 2, 15, 48, ub04.Field38_ResponsibleParty.Line4); - AddBlock(page, 2, 16, 48, ub04.Field38_ResponsibleParty.Line5); - + AddBlock(page, 2, 12, 48, ub04.Field38_ResponsibleParty.Line1,debugOutFileName:fn); + AddBlock(page, 2, 13, 48, ub04.Field38_ResponsibleParty.Line2,debugOutFileName:fn); + AddBlock(page, 2, 14, 48, ub04.Field38_ResponsibleParty.Line3,debugOutFileName:fn); + AddBlock(page, 2, 15, 48, ub04.Field38_ResponsibleParty.Line4,debugOutFileName:fn); + AddBlock(page, 2, 16, 48, ub04.Field38_ResponsibleParty.Line5,debugOutFileName:fn); // Box 39 - Value Codes - AddBlock(page, 53, 13, 2, ub04.Field39a_Value.Code); - AddBlock(page, 57, 13, 12, $"{ub04.Field39a_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right); - AddBlock(page, 53, 14, 2, ub04.Field39b_Value.Code); - AddBlock(page, 57, 14, 12, $"{ub04.Field39b_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right); - AddBlock(page, 53, 15, 2, ub04.Field39c_Value.Code); - AddBlock(page, 57, 15, 12, $"{ub04.Field39c_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right); - AddBlock(page, 53, 16, 2, ub04.Field39d_Value.Code); - AddBlock(page, 57, 16, 12, $"{ub04.Field39d_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right); - + AddBlock(page, 53, 13, 2, ub04.Field39a_Value.Code,debugOutFileName:fn); + AddBlock(page, 57, 13, 12, $"{ub04.Field39a_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 53, 14, 2, ub04.Field39b_Value.Code,debugOutFileName:fn); + AddBlock(page, 57, 14, 12, $"{ub04.Field39b_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 53, 15, 2, ub04.Field39c_Value.Code,debugOutFileName:fn); + AddBlock(page, 57, 15, 12, $"{ub04.Field39c_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 53, 16, 2, ub04.Field39d_Value.Code,debugOutFileName:fn); + AddBlock(page, 57, 16, 12, $"{ub04.Field39d_Value.Amount:0.00}".Replace('.', ' '), TextAlign.right, debugOutFileName:fn); // Box 40 - AddBlock(page, 69, 13, 2, ub04.Field40a_Value.Code); - AddBlock(page, 72.5m, 13, 12, string.Format("{0:0.00}", ub04.Field40a_Value.Amount).Replace('.', ' '), TextAlign.right); - AddBlock(page, 69, 14, 2, ub04.Field40b_Value.Code); - AddBlock(page, 72.5m, 14, 12, string.Format("{0:0.00}", ub04.Field40b_Value.Amount).Replace('.', ' '), TextAlign.right); - AddBlock(page, 69, 15, 2, ub04.Field40c_Value.Code); - AddBlock(page, 72.5m, 15, 12, string.Format("{0:0.00}", ub04.Field40c_Value.Amount).Replace('.', ' '), TextAlign.right); - AddBlock(page, 69, 16, 2, ub04.Field40d_Value.Code); - AddBlock(page, 72.5m, 16, 12, string.Format("{0:0.00}", ub04.Field40d_Value.Amount).Replace('.', ' '), TextAlign.right); - + AddBlock(page, 69, 13, 2, ub04.Field40a_Value.Code,debugOutFileName:fn); + AddBlock(page, 72.5m, 13, 12, string.Format("{0:0.00}", ub04.Field40a_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 69, 14, 2, ub04.Field40b_Value.Code,debugOutFileName:fn); + AddBlock(page, 72.5m, 14, 12, string.Format("{0:0.00}", ub04.Field40b_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 69, 15, 2, ub04.Field40c_Value.Code,debugOutFileName:fn); + AddBlock(page, 72.5m, 15, 12, string.Format("{0:0.00}", ub04.Field40c_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 69, 16, 2, ub04.Field40d_Value.Code,debugOutFileName:fn); + AddBlock(page, 72.5m, 16, 12, string.Format("{0:0.00}", ub04.Field40d_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); // Box 41 - Value Codes - AddBlock(page, 84, 13, 2, ub04.Field41a_Value.Code); - AddBlock(page, 88, 13, 12, string.Format("{0:0.00}", ub04.Field41a_Value.Amount).Replace('.', ' '), TextAlign.right); - AddBlock(page, 84, 14, 2, ub04.Field41b_Value.Code); - AddBlock(page, 88, 14, 12, string.Format("{0:0.00}", ub04.Field41b_Value.Amount).Replace('.', ' '), TextAlign.right); - AddBlock(page, 84, 15, 2, ub04.Field41c_Value.Code); - AddBlock(page, 88, 15, 12, string.Format("{0:0.00}", ub04.Field41c_Value.Amount).Replace('.', ' '), TextAlign.right); - AddBlock(page, 84, 16, 2, ub04.Field41d_Value.Code); - AddBlock(page, 88, 16, 12, string.Format("{0:0.00}", ub04.Field41d_Value.Amount).Replace('.', ' '), TextAlign.right); + AddBlock(page, 84, 13, 2, ub04.Field41a_Value.Code,debugOutFileName:fn); + AddBlock(page, 88, 13, 12, string.Format("{0:0.00}", ub04.Field41a_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 84, 14, 2, ub04.Field41b_Value.Code,debugOutFileName:fn); + AddBlock(page, 88, 14, 12, string.Format("{0:0.00}", ub04.Field41b_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 84, 15, 2, ub04.Field41c_Value.Code,debugOutFileName:fn); + AddBlock(page, 88, 15, 12, string.Format("{0:0.00}", ub04.Field41c_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 84, 16, 2, ub04.Field41d_Value.Code,debugOutFileName:fn); + AddBlock(page, 88, 16, 12, string.Format("{0:0.00}", ub04.Field41d_Value.Amount).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); } // service lines @@ -1262,21 +1265,20 @@ public virtual List TransformUb04ToFormPages(UB04Claim ub04) var line = ub04.ServiceLines[i]; // Box 42 - 49 - Service Lines - AddBlock(page, 2, y, 4, line.Field42_RevenueCode); - AddBlock(page, 7, y, 29, line.Field43_Description); - AddBlock(page, 37, y, 17, line.Field44_ProcedureCodes); - AddBlock(page, 56, y, 6, line.Field45_ServiceDate); - AddBlock(page, 64, y, 9, line.Field46_ServiceUnits, TextAlign.right); - - AddBlock(page, 74, y, 11, string.Format("{0:0.00}", line.Field47_TotalCharges).Replace('.', ' '), TextAlign.right); - AddBlock(page, 86, y, 11, string.Format("{0:0.00}", line.Field48_NonCoveredCharges).Replace('.', ' '), TextAlign.right); - AddBlock(page, 97, y, 2, line.Field49); + AddBlock(page, 2, y, 4, line.Field42_RevenueCode,debugOutFileName:fn); + AddBlock(page, 7, y, 29, line.Field43_Description,debugOutFileName:fn); + AddBlock(page, 37, y, 17, line.Field44_ProcedureCodes,debugOutFileName:fn); + AddBlock(page, 56, y, 6, line.Field45_ServiceDate,debugOutFileName:fn); + AddBlock(page, 64, y, 9, line.Field46_ServiceUnits, TextAlign.right, debugOutFileName:fn); + AddBlock(page, 74, y, 11, string.Format("{0:0.00}", line.Field47_TotalCharges).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 86, y, 11, string.Format("{0:0.00}", line.Field48_NonCoveredCharges).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 97, y, 2, line.Field49,debugOutFileName:fn); // Footer - if (i % 22 == 21 || i == ub04.ServiceLines.Count - 1) + if (i % 22 == 21 || i == ub04.ServiceLines.Count - 1) { - AddBlock(page, 13, 40, 3, pageIndex.ToString(), TextAlign.right); - AddBlock(page, 20, 40, 3, pageCount.ToString(), TextAlign.right); + AddBlock(page, 13, 40, 3, pageIndex.ToString(), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 20, 40, 3, pageCount.ToString(), TextAlign.right, debugOutFileName:fn); if (this.PerPageTotalChargesView) { int lowIndex; @@ -1304,271 +1306,262 @@ public virtual List TransformUb04ToFormPages(UB04Claim ub04) } } - AddBlock(page, 74, 40, 11, string.Format("{0:0.00}", pageCharges).Replace('.', ' '), TextAlign.right); - AddBlock(page, 86, 40, 11, string.Format("{0:0.00}", nonCoveredCharges).Replace('.', ' '), TextAlign.right); + AddBlock(page, 74, 40, 11, string.Format("{0:0.00}", pageCharges).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 86, 40, 11, string.Format("{0:0.00}", nonCoveredCharges).Replace('.', ' '), TextAlign.right,debugOutFileName:fn ); } else { if (pageIndex == pageCount) { - AddBlock(page, 74, 40, 11, string.Format("{0:0.00}", ub04.Field47_Line23_TotalCharges).Replace('.', ' '), TextAlign.right); - AddBlock(page, 86, 40, 11, string.Format("{0:0.00}", ub04.Field48_Line23_NonCoveredCharges).Replace('.', ' '), TextAlign.right); + AddBlock(page, 74, 40, 11, string.Format("{0:0.00}", ub04.Field47_Line23_TotalCharges).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 86, 40, 11, string.Format("{0:0.00}", ub04.Field48_Line23_NonCoveredCharges).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); } } // Box 50 - AddBlock(page, 2, 42, 26, ub04.PayerA_Primary.Field50_PayerName); - AddBlock(page, 2, 43, 26, ub04.PayerB_Secondary.Field50_PayerName); - AddBlock(page, 2, 44, 26, ub04.PayerC_Tertiary.Field50_PayerName); + AddBlock(page, 2, 42, 26, ub04.PayerA_Primary.Field50_PayerName, debugOutFileName:fn); + AddBlock(page, 2, 43, 26, ub04.PayerB_Secondary.Field50_PayerName, debugOutFileName:fn); + AddBlock(page, 2, 44, 26, ub04.PayerC_Tertiary.Field50_PayerName, debugOutFileName:fn); // Box 51 - AddBlock(page, 29, 42, 17, ub04.PayerA_Primary.Field51_HealthPlanId); - AddBlock(page, 29, 43, 17, ub04.PayerB_Secondary.Field51_HealthPlanId); - AddBlock(page, 29, 44, 17, ub04.PayerC_Tertiary.Field51_HealthPlanId); - + AddBlock(page, 29, 42, 17, ub04.PayerA_Primary.Field51_HealthPlanId, debugOutFileName:fn); + AddBlock(page, 29, 43, 17, ub04.PayerB_Secondary.Field51_HealthPlanId, debugOutFileName:fn); + AddBlock(page, 29, 44, 17, ub04.PayerC_Tertiary.Field51_HealthPlanId, debugOutFileName:fn); + // Box 52 - Release of Info - AddBlock(page, 46.5m, 42, 2, ub04.PayerA_Primary.Field52_ReleaseOfInfoCertIndicator); - AddBlock(page, 46.5m, 43, 2, ub04.PayerB_Secondary.Field52_ReleaseOfInfoCertIndicator); - AddBlock(page, 46.5m, 44, 2, ub04.PayerC_Tertiary.Field52_ReleaseOfInfoCertIndicator); + AddBlock(page, 46.5m, 42, 2, ub04.PayerA_Primary.Field52_ReleaseOfInfoCertIndicator, debugOutFileName:fn); + AddBlock(page, 46.5m, 43, 2, ub04.PayerB_Secondary.Field52_ReleaseOfInfoCertIndicator, debugOutFileName:fn); + AddBlock(page, 46.5m, 44, 2, ub04.PayerC_Tertiary.Field52_ReleaseOfInfoCertIndicator, debugOutFileName:fn); // Box 53 - AddBlock(page, 50, 42, 2, ub04.PayerA_Primary.Field53_AssignmentOfBenefitsCertIndicator); - AddBlock(page, 50, 43, 2, ub04.PayerB_Secondary.Field53_AssignmentOfBenefitsCertIndicator); - AddBlock(page, 50, 44, 2, ub04.PayerC_Tertiary.Field53_AssignmentOfBenefitsCertIndicator); + AddBlock(page, 50, 42, 2, ub04.PayerA_Primary.Field53_AssignmentOfBenefitsCertIndicator, debugOutFileName:fn); + AddBlock(page, 50, 43, 2, ub04.PayerB_Secondary.Field53_AssignmentOfBenefitsCertIndicator, debugOutFileName:fn); + AddBlock(page, 50, 44, 2, ub04.PayerC_Tertiary.Field53_AssignmentOfBenefitsCertIndicator, debugOutFileName:fn); // Box 54 - AddBlock(page, 54.25m, 42, 11, string.Format("{0:0.00}", ub04.PayerA_Primary.Field54_PriorPayments).Replace('.', ' '), TextAlign.right); - AddBlock(page, 54.25m, 43, 11, string.Format("{0:0.00}", ub04.PayerB_Secondary.Field54_PriorPayments).Replace('.', ' '), TextAlign.right); - AddBlock(page, 54.25m, 44, 11, string.Format("{0:0.00}", ub04.PayerC_Tertiary.Field54_PriorPayments).Replace('.', ' '), TextAlign.right); + AddBlock(page, 54.25m, 42, 11, string.Format("{0:0.00}", ub04.PayerA_Primary.Field54_PriorPayments).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 54.25m, 43, 11, string.Format("{0:0.00}", ub04.PayerB_Secondary.Field54_PriorPayments).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 54.25m, 44, 11, string.Format("{0:0.00}", ub04.PayerC_Tertiary.Field54_PriorPayments).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); // Box 55 - AddBlock(page, 66.5m, 42, 12, string.Format("{0:0.00}", ub04.PayerA_Primary.Field55_EstimatedAmountDue).Replace('.', ' '), TextAlign.right); - AddBlock(page, 66.5m, 43, 12, string.Format("{0:0.00}", ub04.PayerB_Secondary.Field55_EstimatedAmountDue).Replace('.', ' '), TextAlign.right); - AddBlock(page, 66.5m, 44, 12, string.Format("{0:0.00}", ub04.PayerC_Tertiary.Field55_EstimatedAmountDue).Replace('.', ' '), TextAlign.right); + AddBlock(page, 66.5m, 42, 12, string.Format("{0:0.00}", ub04.PayerA_Primary.Field55_EstimatedAmountDue).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 66.5m, 43, 12, string.Format("{0:0.00}", ub04.PayerB_Secondary.Field55_EstimatedAmountDue).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); + AddBlock(page, 66.5m, 44, 12, string.Format("{0:0.00}", ub04.PayerC_Tertiary.Field55_EstimatedAmountDue).Replace('.', ' '), TextAlign.right, debugOutFileName:fn); // Box 56 - AddBlock(page, 85, 41, 10, ub04.Field56_NationalProviderIdentifier); + AddBlock(page, 85, 41, 10, ub04.Field56_NationalProviderIdentifier, debugOutFileName:fn); // Box 57 - AddBlock(page, 82, 42, 17, ub04.Field57_OtherProviderIdA); - AddBlock(page, 82, 43, 17, ub04.Field57_OtherProviderIdB); - AddBlock(page, 82, 44, 17, ub04.Field57_OtherProviderIdC); + AddBlock(page, 82, 42, 17, ub04.Field57_OtherProviderIdA, debugOutFileName:fn); + AddBlock(page, 82, 43, 17, ub04.Field57_OtherProviderIdB, debugOutFileName:fn); + AddBlock(page, 82, 44, 17, ub04.Field57_OtherProviderIdC, debugOutFileName:fn); // Box 58 - AddBlock(page, 2, 46, 29, ub04.PayerA_Primary.Field58_InsuredsName); - AddBlock(page, 2, 47, 29, ub04.PayerB_Secondary.Field58_InsuredsName); - AddBlock(page, 2, 48, 29, ub04.PayerC_Tertiary.Field58_InsuredsName); + AddBlock(page, 2, 46, 29, ub04.PayerA_Primary.Field58_InsuredsName, debugOutFileName:fn); + AddBlock(page, 2, 47, 29, ub04.PayerB_Secondary.Field58_InsuredsName, debugOutFileName:fn); + AddBlock(page, 2, 48, 29, ub04.PayerC_Tertiary.Field58_InsuredsName, debugOutFileName:fn); // Box 59 - AddBlock(page, 33, 46, 2, ub04.PayerA_Primary.Field59_PatientRelationship); - AddBlock(page, 33, 47, 2, ub04.PayerB_Secondary.Field59_PatientRelationship); - AddBlock(page, 33, 48, 2, ub04.PayerC_Tertiary.Field59_PatientRelationship); + AddBlock(page, 33, 46, 2, ub04.PayerA_Primary.Field59_PatientRelationship, debugOutFileName:fn); + AddBlock(page, 33, 47, 2, ub04.PayerB_Secondary.Field59_PatientRelationship, debugOutFileName:fn); + AddBlock(page, 33, 48, 2, ub04.PayerC_Tertiary.Field59_PatientRelationship, debugOutFileName:fn); // Box 60 - AddBlock(page, 36, 46, 23, ub04.PayerA_Primary.Field60_InsuredsUniqueId); - AddBlock(page, 36, 47, 23, ub04.PayerB_Secondary.Field60_InsuredsUniqueId); - AddBlock(page, 36, 48, 23, ub04.PayerC_Tertiary.Field60_InsuredsUniqueId); + AddBlock(page, 36, 46, 23, ub04.PayerA_Primary.Field60_InsuredsUniqueId, debugOutFileName:fn); + AddBlock(page, 36, 47, 23, ub04.PayerB_Secondary.Field60_InsuredsUniqueId, debugOutFileName:fn); + AddBlock(page, 36, 48, 23, ub04.PayerC_Tertiary.Field60_InsuredsUniqueId, debugOutFileName:fn); // Box 61 - AddBlock(page, 60, 46, 17, ub04.PayerA_Primary.Field61_GroupName); - AddBlock(page, 60, 47, 17, ub04.PayerB_Secondary.Field61_GroupName); - AddBlock(page, 60, 48, 17, ub04.PayerC_Tertiary.Field61_GroupName); + AddBlock(page, 60, 46, 17, ub04.PayerA_Primary.Field61_GroupName, debugOutFileName:fn); + AddBlock(page, 60, 47, 17, ub04.PayerB_Secondary.Field61_GroupName, debugOutFileName:fn); + AddBlock(page, 60, 48, 17, ub04.PayerC_Tertiary.Field61_GroupName, debugOutFileName:fn); // Box 62 - AddBlock(page, 78, 46, 21, ub04.PayerA_Primary.Field62_InsuredsGroupNumber); - AddBlock(page, 78, 47, 21, ub04.PayerB_Secondary.Field62_InsuredsGroupNumber); - AddBlock(page, 78, 48, 21, ub04.PayerC_Tertiary.Field62_InsuredsGroupNumber); + AddBlock(page, 78, 46, 21, ub04.PayerA_Primary.Field62_InsuredsGroupNumber, debugOutFileName:fn); + AddBlock(page, 78, 47, 21, ub04.PayerB_Secondary.Field62_InsuredsGroupNumber, debugOutFileName:fn); + AddBlock(page, 78, 48, 21, ub04.PayerC_Tertiary.Field62_InsuredsGroupNumber, debugOutFileName:fn); // Box 63 - AddBlock(page, 2, 50, 35, ub04.Field63A_TreatmentAuthorizationCode); - AddBlock(page, 2, 51, 35, ub04.Field63B_TreatmentAuthorizationCode); - AddBlock(page, 2, 52, 35, ub04.Field63C_TreatmentAuthorizationCode); + AddBlock(page, 2, 50, 35, ub04.Field63A_TreatmentAuthorizationCode, debugOutFileName:fn); + AddBlock(page, 2, 51, 35, ub04.Field63B_TreatmentAuthorizationCode, debugOutFileName:fn); + AddBlock(page, 2, 52, 35, ub04.Field63C_TreatmentAuthorizationCode, debugOutFileName:fn); // Box 64 - Document Control Number - AddBlock(page, 39, 50, 30, ub04.Field64A_DocumentControlNumber); - AddBlock(page, 39, 51, 30, ub04.Field64B_DocumentControlNumber); - AddBlock(page, 39, 52, 30, ub04.Field64C_DocumentControlNumber); + AddBlock(page, 39, 50, 30, ub04.Field64A_DocumentControlNumber, debugOutFileName:fn); + AddBlock(page, 39, 51, 30, ub04.Field64B_DocumentControlNumber, debugOutFileName:fn); + AddBlock(page, 39, 52, 30, ub04.Field64C_DocumentControlNumber, debugOutFileName:fn); // Box 65 - Employer Name - AddBlock(page, 70, 50, 29, ub04.Field65a_EmployerName); - AddBlock(page, 70, 51, 29, ub04.Field65b_EmployerName); - AddBlock(page, 70, 52, 29, ub04.Field65c_EmployerName); + AddBlock(page, 70, 50, 29, ub04.Field65a_EmployerName, debugOutFileName:fn); + AddBlock(page, 70, 51, 29, ub04.Field65b_EmployerName, debugOutFileName:fn); + AddBlock(page, 70, 52, 29, ub04.Field65c_EmployerName, debugOutFileName:fn); // Box 66 - ICD Version - AddBlock(page, 1, 54, 1, ub04.Field66_Version); + AddBlock(page, 1, 54, 1, ub04.Field66_Version, debugOutFileName:fn); // Box 67 - Primary Diagnosis - AddBlock(page, 3, 53, 6, ub04.Field67_PrincipleDiagnosis.Code); - AddBlock(page, 10.5m, 53, 1, ub04.Field67_PrincipleDiagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 3, 53, 6, ub04.Field67_PrincipleDiagnosis.Code, debugOutFileName:fn); + AddBlock(page, 10.5m, 53, 1, ub04.Field67_PrincipleDiagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67A - AddBlock(page, 13, 53, 6, ub04.Field67A_Diagnosis.Code); - AddBlock(page, 20, 53, 1, ub04.Field67A_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 13, 53, 6, ub04.Field67A_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 20, 53, 1, ub04.Field67A_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67B - AddBlock(page, 22, 53, 6, ub04.Field67B_Diagnosis.Code); - AddBlock(page, 29.75m, 53, 1, ub04.Field67B_Diagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 22, 53, 6, ub04.Field67B_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 29.75m, 53, 1, ub04.Field67B_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67C - AddBlock(page, 32, 53, 6, ub04.Field67C_Diagnosis.Code); - AddBlock(page, 39.25m, 53, 1, ub04.Field67C_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 32, 53, 6, ub04.Field67C_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 39.25m, 53, 1, ub04.Field67C_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67D - AddBlock(page, 42, 53, 6, ub04.Field67D_Diagnosis.Code); - AddBlock(page, 49m, 53, 1, ub04.Field67D_Diagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 42, 53, 6, ub04.Field67D_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 49m, 53, 1, ub04.Field67D_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67E - AddBlock(page, 51, 53, 6, ub04.Field67E_Diagnosis.Code); - AddBlock(page, 58.5m, 53, 1, ub04.Field67E_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 51, 53, 6, ub04.Field67E_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 58.5m, 53, 1, ub04.Field67E_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67F - AddBlock(page, 61, 53, 6, ub04.Field67F_Diagnosis.Code); - AddBlock(page, 68m, 53, 1, ub04.Field67F_Diagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 61, 53, 6, ub04.Field67F_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 68m, 53, 1, ub04.Field67F_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67G - AddBlock(page, 70, 53, 6, ub04.Field67G_Diagnosis.Code); - AddBlock(page, 77.75m, 53, 1, ub04.Field67G_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 70, 53, 6, ub04.Field67G_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 77.75m, 53, 1, ub04.Field67G_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67H - AddBlock(page, 80, 53, 6, ub04.Field67H_Diagnosis.Code); - AddBlock(page, 87.25m, 53, 1, ub04.Field67H_Diagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 80, 53, 6, ub04.Field67H_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 87.25m, 53, 1, ub04.Field67H_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67I - AddBlock(page, 3, 54, 6, ub04.Field67I_Diagnosis.Code); - AddBlock(page, 10.5m, 54, 1, ub04.Field67I_Diagnosis.PresentOnAdmissionIndicator); - - // Box 67J - AddBlock(page, 13, 54, 6, ub04.Field67J_Diagnosis.Code); - AddBlock(page, 20, 54, 1, ub04.Field67J_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 3, 54, 6, ub04.Field67I_Diagnosis.Code, debugOutFileName:fn ); + AddBlock(page, 10.5m, 54, 1, ub04.Field67I_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); + // Box 67J + AddBlock(page, 13, 54, 6, ub04.Field67J_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 20, 54, 1, ub04.Field67J_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67K - AddBlock(page, 22, 54, 6, ub04.Field67K_Diagnosis.Code); - AddBlock(page, 29.75m, 54, 1, ub04.Field67K_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 22, 54, 6, ub04.Field67K_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 29.75m, 54, 1, ub04.Field67K_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn ); // Box 67L - AddBlock(page, 32, 54, 6, ub04.Field67L_Diagnosis.Code); - AddBlock(page, 39.25m, 54, 1, ub04.Field67L_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 32, 54, 6, ub04.Field67L_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 39.25m, 54, 1, ub04.Field67L_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67M - AddBlock(page, 42, 54, 6, ub04.Field67M_Diagnosis.Code); - AddBlock(page, 49m, 54, 1, ub04.Field67M_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 42, 54, 6, ub04.Field67M_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 49m, 54, 1, ub04.Field67M_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67N - AddBlock(page, 51, 54, 6, ub04.Field67N_Diagnosis.Code); - AddBlock(page, 58.5m, 54, 1, ub04.Field67N_Diagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 51, 54, 6, ub04.Field67N_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 58.5m, 54, 1, ub04.Field67N_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67O - AddBlock(page, 61, 54, 6, ub04.Field67O_Diagnosis.Code); - AddBlock(page, 68m, 54, 1, ub04.Field67O_Diagnosis.PresentOnAdmissionIndicator); + AddBlock(page, 61, 54, 6, ub04.Field67O_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 68m, 54, 1, ub04.Field67O_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67P - AddBlock(page, 70, 54, 6, ub04.Field67P_Diagnosis.Code); - AddBlock(page, 77.75m, 54, 1, ub04.Field67P_Diagnosis.PresentOnAdmissionIndicator); - + AddBlock(page, 70, 54, 6, ub04.Field67P_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 77.75m, 54, 1, ub04.Field67P_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 67Q - AddBlock(page, 80, 54, 6, ub04.Field67Q_Diagnosis.Code); - AddBlock(page, 87.25m, 54, 1, ub04.Field67Q_Diagnosis.PresentOnAdmissionIndicator); - - // Box 68 - AddBlock(page, 90, 53, 9, ub04.Field68.Line1); - AddBlock(page, 90, 54, 9, ub04.Field68.Line2); + AddBlock(page, 80, 54, 6, ub04.Field67Q_Diagnosis.Code, debugOutFileName:fn); + AddBlock(page, 87.25m, 54, 1, ub04.Field67Q_Diagnosis.PresentOnAdmissionIndicator, debugOutFileName:fn); + // Box 68 + AddBlock(page, 90, 53, 9, ub04.Field68.Line1, debugOutFileName:fn); + AddBlock(page, 90, 54, 9, ub04.Field68.Line2, debugOutFileName:fn); // Box 69 - Admitting Diagnosis - AddBlock(page, 6, 55, 6, ub04.Field69_AdmittingDiagnosisCode.Code); + AddBlock(page, 6, 55, 6, ub04.Field69_AdmittingDiagnosisCode.Code, debugOutFileName:fn); // Box 70 - Patient Reason Diagnosis - AddBlock(page, 21, 55, 6, ub04.Field70a_PatientReasonDiagnosisCode.Code); - AddBlock(page, 29, 55, 6, ub04.Field70b_PatientReasonDiagnosisCode.Code); - AddBlock(page, 38, 55, 6, ub04.Field70c_PatientReasonDiagnosisCode.Code); + AddBlock(page, 21, 55, 6, ub04.Field70a_PatientReasonDiagnosisCode.Code, debugOutFileName:fn); + AddBlock(page, 29, 55, 6, ub04.Field70b_PatientReasonDiagnosisCode.Code, debugOutFileName:fn); + AddBlock(page, 38, 55, 6, ub04.Field70c_PatientReasonDiagnosisCode.Code, debugOutFileName:fn); // Box 71 - PPS Code - AddBlock(page, 51, 55, 5, ub04.Field71_PPSCode); + AddBlock(page, 51, 55, 5, ub04.Field71_PPSCode, debugOutFileName:fn); // Box 72 - External Cause of Injury - AddBlock(page, 59, 55, 6, ub04.Field72a_ExternalCauseOfInjury.Code); - AddBlock(page, 67m, 55, 1, ub04.Field72a_ExternalCauseOfInjury.PresentOnAdmissionIndicator); - AddBlock(page, 69, 55, 6, ub04.Field72b_ExternalCauseOfInjury.Code); - AddBlock(page, 76.75m, 55, 1, ub04.Field72b_ExternalCauseOfInjury.PresentOnAdmissionIndicator); - AddBlock(page, 79, 55, 6, ub04.Field72c_ExternalCauseOfInjury.Code); - AddBlock(page, 86.25m, 55, 1, ub04.Field72c_ExternalCauseOfInjury.PresentOnAdmissionIndicator); + AddBlock(page, 59, 55, 6, ub04.Field72a_ExternalCauseOfInjury.Code, debugOutFileName:fn); + AddBlock(page, 67m, 55, 1, ub04.Field72a_ExternalCauseOfInjury.PresentOnAdmissionIndicator, debugOutFileName:fn); + AddBlock(page, 69, 55, 6, ub04.Field72b_ExternalCauseOfInjury.Code, debugOutFileName:fn); + AddBlock(page, 76.75m, 55, 1, ub04.Field72b_ExternalCauseOfInjury.PresentOnAdmissionIndicator, debugOutFileName:fn); + AddBlock(page, 79, 55, 6, ub04.Field72c_ExternalCauseOfInjury.Code, debugOutFileName:fn); + AddBlock(page, 86.25m, 55, 1, ub04.Field72c_ExternalCauseOfInjury.PresentOnAdmissionIndicator, debugOutFileName:fn); // Box 73 - Blank - AddBlock(page, 89, 55, 10, ub04.Field73); + AddBlock(page, 89, 55, 10, ub04.Field73, debugOutFileName:fn); // Box 74 - AddBlock(page, 2, 57, 8, ub04.Field74_PrincipalProcedure.Code); - AddBlock(page, 12, 57, 6, ub04.Field74_PrincipalProcedure.Date); - AddBlock(page, 20, 57, 8, ub04.Field74a_OtherProcedure.Code); - AddBlock(page, 29, 57, 6, ub04.Field74a_OtherProcedure.Date); - AddBlock(page, 38, 57, 8, ub04.Field74b_OtherProcedure.Code); - AddBlock(page, 48, 57, 6, ub04.Field74b_OtherProcedure.Date); - AddBlock(page, 2, 59, 8, ub04.Field74c_OtherProcedure.Code); - AddBlock(page, 12, 59, 6, ub04.Field74c_OtherProcedure.Date); - AddBlock(page, 20, 59, 8, ub04.Field74d_OtherProcedure.Code); - AddBlock(page, 29, 59, 6, ub04.Field74d_OtherProcedure.Date); - AddBlock(page, 38, 59, 8, ub04.Field74e_OtherProcedure.Code); - AddBlock(page, 48, 59, 6, ub04.Field74e_OtherProcedure.Date); - + AddBlock(page, 2, 57, 8, ub04.Field74_PrincipalProcedure.Code, debugOutFileName:fn); + AddBlock(page, 12, 57, 6, ub04.Field74_PrincipalProcedure.Date, debugOutFileName:fn); + AddBlock(page, 20, 57, 8, ub04.Field74a_OtherProcedure.Code, debugOutFileName:fn); + AddBlock(page, 29, 57, 6, ub04.Field74a_OtherProcedure.Date, debugOutFileName:fn); + AddBlock(page, 38, 57, 8, ub04.Field74b_OtherProcedure.Code, debugOutFileName:fn); + AddBlock(page, 48, 57, 6, ub04.Field74b_OtherProcedure.Date, debugOutFileName:fn); + AddBlock(page, 2, 59, 8, ub04.Field74c_OtherProcedure.Code, debugOutFileName:fn); + AddBlock(page, 12, 59, 6, ub04.Field74c_OtherProcedure.Date, debugOutFileName:fn); + AddBlock(page, 20, 59, 8, ub04.Field74d_OtherProcedure.Code, debugOutFileName:fn); + AddBlock(page, 29, 59, 6, ub04.Field74d_OtherProcedure.Date, debugOutFileName:fn); + AddBlock(page, 38, 59, 8, ub04.Field74e_OtherProcedure.Code, debugOutFileName:fn); + AddBlock(page, 48, 59, 6, ub04.Field74e_OtherProcedure.Date, debugOutFileName:fn); // Box 75 - AddBlock(page, 56, 56, 4, ub04.Field75.Line1); - AddBlock(page, 56, 57, 4, ub04.Field75.Line2); - AddBlock(page, 56, 58, 4, ub04.Field75.Line3); - AddBlock(page, 56, 59, 4, ub04.Field75.Line4); + AddBlock(page, 56, 56, 4, ub04.Field75.Line1, debugOutFileName:fn); + AddBlock(page, 56, 57, 4, ub04.Field75.Line2, debugOutFileName:fn); + AddBlock(page, 56, 58, 4, ub04.Field75.Line3, debugOutFileName:fn); + AddBlock(page, 56, 59, 4, ub04.Field75.Line4, debugOutFileName:fn); // Box 76 - AddBlock(page, 72, 56, 10, ub04.Field76_AttendingPhysician.Npi); - AddBlock(page, 86, 56, 2, ub04.Field76_AttendingPhysician.IdentifierQualifier); - AddBlock(page, 89, 56, 10, ub04.Field76_AttendingPhysician.Identifier); - AddBlock(page, 64, 57, 18, ub04.Field76_AttendingPhysician.LastName); - AddBlock(page, 86, 57, 13, ub04.Field76_AttendingPhysician.FirstName); + AddBlock(page, 72, 56, 10, ub04.Field76_AttendingPhysician.Npi, debugOutFileName:fn); + AddBlock(page, 86, 56, 2, ub04.Field76_AttendingPhysician.IdentifierQualifier, debugOutFileName:fn); + AddBlock(page, 89, 56, 10, ub04.Field76_AttendingPhysician.Identifier, debugOutFileName:fn); + AddBlock(page, 64, 57, 18, ub04.Field76_AttendingPhysician.LastName, debugOutFileName:fn); + AddBlock(page, 86, 57, 13, ub04.Field76_AttendingPhysician.FirstName, debugOutFileName:fn); // Box 77 - AddBlock(page, 72, 58, 10, ub04.Field77_OperatingPhysician.Npi); - AddBlock(page, 86, 58, 2, ub04.Field77_OperatingPhysician.IdentifierQualifier); - AddBlock(page, 89, 58, 10, ub04.Field77_OperatingPhysician.Identifier); - AddBlock(page, 64, 59, 18, ub04.Field77_OperatingPhysician.LastName); - AddBlock(page, 86, 59, 13, ub04.Field77_OperatingPhysician.FirstName); + AddBlock(page, 72, 58, 10, ub04.Field77_OperatingPhysician.Npi, debugOutFileName:fn); + AddBlock(page, 86, 58, 2, ub04.Field77_OperatingPhysician.IdentifierQualifier, debugOutFileName:fn); + AddBlock(page, 89, 58, 10, ub04.Field77_OperatingPhysician.Identifier, debugOutFileName:fn); + AddBlock(page, 64, 59, 18, ub04.Field77_OperatingPhysician.LastName, debugOutFileName:fn); + AddBlock(page, 86, 59, 13, ub04.Field77_OperatingPhysician.FirstName, debugOutFileName:fn); // Box 78 - AddBlock(page, 72, 60, 10, ub04.Field78_OtherProvider.Npi); - AddBlock(page, 67, 60, 2, ub04.Field78_OtherProvider.ProviderQualifier); - AddBlock(page, 86, 60, 2, ub04.Field78_OtherProvider.IdentifierQualifier); - AddBlock(page, 89, 60, 10, ub04.Field78_OtherProvider.Identifier); - AddBlock(page, 64, 61, 18, ub04.Field78_OtherProvider.LastName); - AddBlock(page, 86, 61, 13, ub04.Field78_OtherProvider.FirstName); + AddBlock(page, 72, 60, 10, ub04.Field78_OtherProvider.Npi, debugOutFileName:fn); + AddBlock(page, 67, 60, 2, ub04.Field78_OtherProvider.ProviderQualifier, debugOutFileName:fn); + AddBlock(page, 86, 60, 2, ub04.Field78_OtherProvider.IdentifierQualifier, debugOutFileName:fn); + AddBlock(page, 89, 60, 10, ub04.Field78_OtherProvider.Identifier, debugOutFileName:fn); + AddBlock(page, 64, 61, 18, ub04.Field78_OtherProvider.LastName, debugOutFileName:fn); + AddBlock(page, 86, 61, 13, ub04.Field78_OtherProvider.FirstName, debugOutFileName:fn); // Box 79 - AddBlock(page, 72, 62, 10, ub04.Field79_OtherProvider.Npi); - AddBlock(page, 67, 62, 2, ub04.Field79_OtherProvider.ProviderQualifier); - AddBlock(page, 86, 62, 2, ub04.Field79_OtherProvider.IdentifierQualifier); - AddBlock(page, 89, 62, 10, ub04.Field79_OtherProvider.Identifier); - AddBlock(page, 64, 63, 18, ub04.Field79_OtherProvider.LastName); - AddBlock(page, 86, 63, 13, ub04.Field79_OtherProvider.FirstName); + AddBlock(page, 72, 62, 10, ub04.Field79_OtherProvider.Npi, debugOutFileName:fn); + AddBlock(page, 67, 62, 2, ub04.Field79_OtherProvider.ProviderQualifier, debugOutFileName:fn); + AddBlock(page, 86, 62, 2, ub04.Field79_OtherProvider.IdentifierQualifier, debugOutFileName:fn); + AddBlock(page, 89, 62, 10, ub04.Field79_OtherProvider.Identifier, debugOutFileName:fn); + AddBlock(page, 64, 63, 18, ub04.Field79_OtherProvider.LastName, debugOutFileName:fn); + AddBlock(page, 86, 63, 13, ub04.Field79_OtherProvider.FirstName, debugOutFileName:fn); // Box 80 - AddBlock(page, 2, 61, 27, ub04.Field80_Remarks.Line1); - AddBlock(page, 2, 62, 27, ub04.Field80_Remarks.Line2); - AddBlock(page, 2, 63, 27, ub04.Field80_Remarks.Line3); + AddBlock(page, 2, 61, 27, ub04.Field80_Remarks.Line1, debugOutFileName:fn); + AddBlock(page, 2, 62, 27, ub04.Field80_Remarks.Line2, debugOutFileName:fn); + AddBlock(page, 2, 63, 27, ub04.Field80_Remarks.Line3, debugOutFileName:fn); // Box 81 - AddBlock(page, 32, 60, 2, ub04.Field81a.Qualifier); - AddBlock(page, 35, 60, 10, ub04.Field81a.Code1); - AddBlock(page, 48, 60, 12, ub04.Field81a.Code2); - AddBlock(page, 32, 61, 2, ub04.Field81b.Qualifier); - AddBlock(page, 35, 61, 10, ub04.Field81b.Code1); - AddBlock(page, 48, 61, 12, ub04.Field81b.Code2); - AddBlock(page, 32, 62, 2, ub04.Field81c.Qualifier); - AddBlock(page, 35, 62, 10, ub04.Field81c.Code1); - AddBlock(page, 48, 62, 12, ub04.Field81c.Code2); - AddBlock(page, 32, 63, 2, ub04.Field81d.Qualifier); - AddBlock(page, 35, 63, 10, ub04.Field81d.Code1); - AddBlock(page, 48, 63, 12, ub04.Field81d.Code2); - + AddBlock(page, 32, 60, 2, ub04.Field81a.Qualifier, debugOutFileName:fn); + AddBlock(page, 35, 60, 10, ub04.Field81a.Code1, debugOutFileName:fn); + AddBlock(page, 48, 60, 12, ub04.Field81a.Code2, debugOutFileName:fn); + AddBlock(page, 32, 61, 2, ub04.Field81b.Qualifier, debugOutFileName:fn); + AddBlock(page, 35, 61, 10, ub04.Field81b.Code1, debugOutFileName:fn); + AddBlock(page, 48, 61, 12, ub04.Field81b.Code2, debugOutFileName:fn); + AddBlock(page, 32, 62, 2, ub04.Field81c.Qualifier, debugOutFileName:fn); + AddBlock(page, 35, 62, 10, ub04.Field81c.Code1, debugOutFileName:fn); + AddBlock(page, 48, 62, 12, ub04.Field81c.Code2, debugOutFileName:fn); + AddBlock(page, 32, 63, 2, ub04.Field81d.Qualifier, debugOutFileName:fn); + AddBlock(page, 35, 63, 10, ub04.Field81d.Code1, debugOutFileName:fn); + AddBlock(page, 48, 63, 12, ub04.Field81d.Code2, debugOutFileName:fn); // reorder by locations; page.Blocks = page.Blocks.OrderBy(bl => bl.Top).ToList(); } } + + DebugFile(this, fn); return pages; } diff --git a/src/X12.Hipaa/X12.Hipaa.csproj b/src/X12.Hipaa/X12.Hipaa.csproj index 059ae3b7..41d00550 100644 --- a/src/X12.Hipaa/X12.Hipaa.csproj +++ b/src/X12.Hipaa/X12.Hipaa.csproj @@ -38,8 +38,40 @@ false + + ..\..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.8\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.8\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.8\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\packages\NLog.6.1.3\lib\net46\NLog.dll + + + ..\..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll + + + + ..\..\packages\System.Diagnostics.DiagnosticSource.10.0.8\lib\net462\System.Diagnostics.DiagnosticSource.dll + + + ..\..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll + + + + ..\..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll + @@ -87,6 +119,7 @@ + @@ -166,6 +199,7 @@ Always + diff --git a/src/X12.Hipaa/packages.config b/src/X12.Hipaa/packages.config new file mode 100644 index 00000000..f0f9c545 --- /dev/null +++ b/src/X12.Hipaa/packages.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/X12.Shared/Models/HierarchicalLoop.cs b/src/X12.Shared/Models/HierarchicalLoop.cs index b5910781..7ae1b244 100644 --- a/src/X12.Shared/Models/HierarchicalLoop.cs +++ b/src/X12.Shared/Models/HierarchicalLoop.cs @@ -1,101 +1,87 @@ -namespace X12.Shared.Models -{ - using System.Collections.Generic; - using System.Linq; - using System.Xml.Serialization; - - using X12.Specifications; - - public class HierarchicalLoop : HierarchicalLoopContainer - { - /// - /// Initializes a new instance of the class with the provided parameters - /// - /// Parent container - /// Delimiter set indicating how to segregate segments and elements - /// Segment string for the loop - internal HierarchicalLoop(Container parent, X12DelimiterSet delimiters, string segment) - : base(parent, delimiters, segment) - { - } - - public HierarchicalLoopSpecification Specification { get; internal set; } - - internal override IList AllowedChildLoops => - this.Specification != null ? this.Specification.LoopSpecifications : new List(); - - internal override IList AllowedChildSegments => - this.Specification != null ? this.Specification.SegmentSpecifications : new List(); - - [XmlAttribute("Id")] - public string Id => this.GetElement(1); - - [XmlAttribute("ParentId")] - public string ParentId => this.GetElement(2); - - public string LevelCode => this.GetElement(3); - - public string HierarchicalChildCode - { - get { return this.GetElement(4); } - internal set { this.SetElement(4, value); } - } - - public override bool AllowsHierarchicalLoop(string levelCode) - { - return true; - } - - public override HierarchicalLoop AddHLoop(string id, string levelCode, bool? willHoldChildHLoops) - { - var hloop = base.AddHLoop(string.Format("HL{0}{1}{0}{2}{0}{3}{0}", this.DelimiterSet.ElementSeparator, id, this.Id, levelCode)); - if (willHoldChildHLoops.HasValue) - { - hloop.HierarchicalChildCode = willHoldChildHLoops.Value ? "1" : "0"; - } - - return hloop; - } - - internal override IEnumerable TrailerSegmentIds - { - get - { - var list = new List(); - - foreach (var spec in this.Specification.SegmentSpecifications.Where(ss => ss.Trailer)) - { - list.Add(spec.SegmentId); - } - - return list; - } - } - - internal override void WriteXml(System.Xml.XmlWriter writer) - { - if (!string.IsNullOrEmpty(this.SegmentId)) - { - writer.WriteStartElement("HierarchicalLoop"); - - if (this.Specification != null) - { - writer.WriteAttributeString("LoopId", this.Specification.LoopId); - writer.WriteAttributeString("LoopName", this.Specification.Name); - } - - writer.WriteAttributeString("Id", this.Id); - writer.WriteAttributeString("ParentId", this.ParentId); - - base.WriteXml(writer); - - writer.WriteEndElement(); - } - } - - public override string ToString() - { - return $"Loop(Id={this.Id},ParentId={this.ParentId},Level={this.LevelCode},ChildLoops={this.Loops.Count()}, ChildSegments={this.Segments.Count})"; - } - } -} +namespace X12.Shared.Models { + using System.Collections.Generic; + using System.Linq; + using System.Xml.Serialization; + + using X12.Specifications; + + public class HierarchicalLoop : HierarchicalLoopContainer { + /// + /// Initializes a new instance of the class with the provided parameters + /// + /// Parent container + /// Delimiter set indicating how to segregate segments and elements + /// Segment string for the loop + internal HierarchicalLoop(Container parent, X12DelimiterSet delimiters, string segment) + : base(parent, delimiters, segment) { + } + + public HierarchicalLoopSpecification Specification { get; internal set; } + + internal override IList AllowedChildLoops => + this.Specification != null ? this.Specification.LoopSpecifications : new List(); + + internal override IList AllowedChildSegments => + this.Specification != null ? this.Specification.SegmentSpecifications : new List(); + + [XmlAttribute("Id")] + public string Id => this.GetElement(1); + + [XmlAttribute("ParentId")] + public string ParentId => this.GetElement(2); + + public string LevelCode => this.GetElement(3); + + public string HierarchicalChildCode { + get { return this.GetElement(4); } + internal set { this.SetElement(4, value); } + } + + public override bool AllowsHierarchicalLoop(string levelCode) { + return true; + } + + public override HierarchicalLoop AddHLoop(string id, string levelCode, bool? willHoldChildHLoops) { + var hloop = base.AddHLoop(string.Format("HL{0}{1}{0}{2}{0}{3}{0}", this.DelimiterSet.ElementSeparator, id, this.Id, levelCode)); + if (willHoldChildHLoops.HasValue) { + hloop.HierarchicalChildCode = willHoldChildHLoops.Value ? "1" : "0"; + } + + return hloop; + } + + internal override IEnumerable TrailerSegmentIds { + get { + var list = new List(); + + foreach (var spec in this.Specification.SegmentSpecifications.Where(ss => ss.Trailer)) { + list.Add(spec.SegmentId); + } + + return list; + } + } + + internal override void WriteXml(System.Xml.XmlWriter writer) { + if (!string.IsNullOrEmpty(this.SegmentId)) { + writer.WriteStartElement("HierarchicalLoop"); + + if (this.Specification != null) { + writer.WriteAttributeString("LoopId", this.Specification.LoopId); + writer.WriteAttributeString("LoopName", this.Specification.Name); + } + + writer.WriteAttributeString("Id", this.Id); + writer.WriteAttributeString("ParentId", this.ParentId); + + base.WriteXml(writer); + + writer.WriteEndElement(); + } + } + + public override string ToString() { + return $"Loop(Id={this.Id},ParentId={this.ParentId},Level={this.LevelCode},ChildLoops={this.Loops.Count()}, ChildSegments={this.Segments.Count})"; + } + } + } diff --git a/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.dtd b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.dtd new file mode 100644 index 00000000..2fdf64f8 --- /dev/null +++ b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.dtd @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xml b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xml new file mode 100644 index 00000000..4bec47ec --- /dev/null +++ b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xml @@ -0,0 +1,477 @@ + + + + + SUBMITTER NAME + + + + + + + RECEIVER NAME + + + + + + BILLING PROVIDER HIERARCHICAL LEVEL + + + + BILLING PROVIDER NAME + + + + + + + + + + PAY-TO PROVIDER'S NAME + + + + + + + + PAY-TO PLAN NAME + + + + + + + + + + + SUBSCRIBER HIERARCHICAL LOOP + + + SUBSCRIBER NAME + + + + + + + + + + PAYER NAME + + + + + + + + + CLAIM INFORMATION + + + + + + + + + + + + + + + + ATTENDING PHYSICIAN NAME + + + + + + + + OPERATING PHYSICIAN NAME + + + + + + + OTHER OPERATING PHYSICIAN NAME + + + + + + + RENDERING PROVIDER NAME + + + + + + + SERVICE FACILITY LOCATION NAME + + + + + + + + + REFERRING PROVIDER NAME + + + + + + + OTHER SUBSCRIBER INFORMATION + + + + + + + + + + OTHER SUBSCRIBER NAME + + + + + + + + + OTHER PAYER NAME + + + + + + + + + + + + OTHER PAYER ATTENDING PROVIDER + + + + + + + OTHER PAYER OPERATING PHYSICIAN + + + + + + + OTHER PAYER OTHER OPERATING PHYSICIAN + + + + + + + OTHER PAYER SERVICE FACILITY LOCATION + + + + + + + OTHER PAYER RENDERING PROVIDER NAME + + + + + + + OTHER PAYER REFERRING PROVIDER + + + + + + + OTHER PAYER BILLING PROVIDER + + + + + + + + SERVICE LINE + + + + + + + + + + DRUG IDENTIFICATION + + + + + + OPERATION PHYSICIAN NAME + + + + + + + OTHER OPERATING PHYSICIAN NAME + + + + + + + RENDERING PROVIDER NAME + + + + + + + REFERRING PROVIDER NAME + + + + + + + Service Line Adjudication Information + + + + + + + + + + PATIENT HIERARCHICAL LOOP + + + PATIENT NAME + + + + + + + + + + CLAIM INFORMATION + + + + + + + + + + + + + + + + ATTENDING PHYSICIAN NAME + + + + + + + + OPERATING PHYSICIAN NAME + + + + + + + OTHER OPERATING PHYSICIAN NAME + + + + + + + RENDERING PROVIDER NAME + + + + + + + SERVICE FACILITY LOCATION NAME + + + + + + + + + REFERRING PROVIDER NAME + + + + + + + OTHER SUBSCRIBER INFORMATION + + + + + + + + + + OTHER SUBSCRIBER NAME + + + + + + + + + OTHER PAYER NAME + + + + + + + + + + + + OTHER PAYER ATTENDING PROVIDER + + + + + + + OTHER PAYER OPERATING PHYSICIAN + + + + + + + OTHER PAYER OTHER OPERATING PHYSICIAN + + + + + + + OTHER PAYER SERVICE FACILITY LOCATION + + + + + + + OTHER PAYER RENDERING PROVIDER NAME + + + + + + + OTHER PAYER REFERRING PROVIDER + + + + + + + OTHER PAYER BILLING PROVIDER + + + + + + + + SERVICE LINE + + + + + + + + + + DRUG IDENTIFICATION + + + + + + OPERATION PHYSICIAN NAME + + + + + + + OTHER OPERATING PHYSICIAN NAME + + + + + + + RENDERING PROVIDER NAME + + + + + + + REFERRING PROVIDER NAME + + + + + + + Service Line Adjudication Information + + + + + + + + + \ No newline at end of file diff --git a/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd new file mode 100644 index 00000000..cb64b3de --- /dev/null +++ b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + For Property & Casualty Claim For Property & Casualty Claim + + + + + DMG not in spec, but in example within spec Professional Segments DMG not in spec, but in example within spec Professional Segments + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd.xml b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd.xml new file mode 100644 index 00000000..24a93e6b --- /dev/null +++ b/src/X12.Specifications/Resource/MyCustom/Ansi-837I-5010Specification.xsd.xml @@ -0,0 +1,37 @@ + + string + + + string + + claustra + + string + mollitque + + + string + + + + + + PATIENT HIERARCHICAL LOOP + + string + + + string + + ac + + string + claustra + + + string + + + + + \ No newline at end of file diff --git a/src/X12.Specifications/X12.Specifications.csproj b/src/X12.Specifications/X12.Specifications.csproj index 2e72e852..bf059d82 100644 --- a/src/X12.Specifications/X12.Specifications.csproj +++ b/src/X12.Specifications/X12.Specifications.csproj @@ -824,9 +824,6 @@ Designer - - - @@ -1061,5 +1058,8 @@ Always
+ + + \ No newline at end of file From a03e04abb0110c11ed3b2fe9e2bce9c404ce77ee Mon Sep 17 00:00:00 2001 From: apeiris Date: Sun, 17 May 2026 11:10:18 -0400 Subject: [PATCH 08/22] wip --- X12UtilsFRM/BiztalkFunctoidNode.cs | 49 ++- X12UtilsFRM/FunctoidScriptEditorForm.cs | 76 ++++ X12UtilsFRM/FunctoidXsltCompiler.cs | 69 ++++ X12UtilsFRM/SkiaMapper.cs | 164 ++++++-- X12UtilsFRM/ToolboxCategory.cs | 77 ++-- X12UtilsFRM/X12UtilsFRM.Designer.cs | 64 ++-- X12UtilsFRM/X12UtilsFRM.cs | 475 +++++++++++++++++++----- X12UtilsFRM/X12UtilsFRM.csproj | 4 + 8 files changed, 799 insertions(+), 179 deletions(-) create mode 100644 X12UtilsFRM/FunctoidScriptEditorForm.cs create mode 100644 X12UtilsFRM/FunctoidXsltCompiler.cs diff --git a/X12UtilsFRM/BiztalkFunctoidNode.cs b/X12UtilsFRM/BiztalkFunctoidNode.cs index ecf70550..dfb4965e 100644 --- a/X12UtilsFRM/BiztalkFunctoidNode.cs +++ b/X12UtilsFRM/BiztalkFunctoidNode.cs @@ -6,12 +6,17 @@ namespace X12UtilsFRM { public class BizTalkFunctoidNode : Panel { + public string CustomScript { get; set; } public string FunctoidName { get; private set; } public string FunctoidCategory { get; private set; } public Label LblIcon { get; private set; } public Label LblText { get; private set; } + // Core tracking variables for drawing cascading links between functoids + private Point mouseStartLoc = Point.Empty; + private bool trackingForLineConnection = false; + public BizTalkFunctoidNode(string text, Point location) { this.FunctoidName = text; @@ -80,11 +85,18 @@ public BizTalkFunctoidNode(string text, Point location) Cursor = Cursors.SizeAll }; this.Controls.Add(LblText); + + // Seed initial execution script snippet properties + this.CustomScript = FunctoidXsltCompiler.GetXsltSnippet(text, "SOURCE_XPATH_PLACEHOLDER", text.Replace(" ", "_")); + + // 3. Register Drag Line Intercept Listeners contextually across all component layout areas + AttachLineDragHooks(this); + AttachLineDragHooks(LblIcon); + AttachLineDragHooks(LblText); } private string DetermineCategory(string functoidName) { - // Auto-detect the classification group dynamically based on string naming patterns string name = functoidName.ToLower(); if (name.Contains("string") || name.Contains("concat") || name.Contains("trim") || name.Contains("case")) return "String"; @@ -95,5 +107,40 @@ private string DetermineCategory(string functoidName) return "Custom"; } + + /// + /// Binds connection dragging hooks recursively so users can Shift+Drag from anywhere on the control. + /// + private void AttachLineDragHooks(Control control) + { + control.MouseDown += (s, e) => + { + if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Shift) + { + trackingForLineConnection = true; + mouseStartLoc = e.Location; + } + }; + + control.MouseMove += (s, e) => + { + if (trackingForLineConnection) + { + int dx = Math.Abs(e.X - mouseStartLoc.X); + int dy = Math.Abs(e.Y - mouseStartLoc.Y); + + // Once the mouse slips past system drag sensitivity variables, trip the mapper drop engine + if (dx >= SystemInformation.DragSize.Width || dy >= SystemInformation.DragSize.Height) + { + trackingForLineConnection = false; + + // Pass THIS entire instance as the underlying link source node reference payload + this.DoDragDrop(this, DragDropEffects.Link); + } + } + }; + + control.MouseUp += (s, e) => { trackingForLineConnection = false; }; + } } } \ No newline at end of file diff --git a/X12UtilsFRM/FunctoidScriptEditorForm.cs b/X12UtilsFRM/FunctoidScriptEditorForm.cs new file mode 100644 index 00000000..d89fe868 --- /dev/null +++ b/X12UtilsFRM/FunctoidScriptEditorForm.cs @@ -0,0 +1,76 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace X12UtilsFRM +{ + public class FunctoidScriptEditorForm : Form + { + private TextBox txtScript; + private Button btnSave; + private Button btnCancel; + public string CompiledScriptText { get; private set; } + + public FunctoidScriptEditorForm(string functoidName, string currentScript) + { + this.Text = $"Configure Functoid Script Properties - [{functoidName}]"; + this.Size = new Size(500, 380); + this.StartPosition = FormStartPosition.CenterParent; + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Font = new Font("Segoe UI", 9f); + + // 1. Info Header Label Banner + Label lblInfo = new Label + { + Text = "Modify the raw XSLT expression value snippet injected during map output compilation loops:", + Location = new Point(12, 12), + Size = new Size(460, 32), + ForeColor = Color.FromArgb(60, 60, 80) + }; + this.Controls.Add(lblInfo); + + // 2. Multi-line Script Editor TextBox + txtScript = new TextBox + { + Multiline = true, + ScrollBars = ScrollBars.Both, + Font = new Font("Consolas", 9.75f, FontStyle.Regular), // Code Editor Monospace Font + Text = currentScript, + Location = new Point(15, 48), + Size = new Size(455, 230), + WordWrap = false + }; + this.Controls.Add(txtScript); + + // 3. Save Operational Trigger Action Button + btnSave = new Button + { + Text = "Save Changes", + DialogResult = DialogResult.OK, + Location = new Point(265, 295), + Size = new Size(100, 30), + BackColor = Color.FromArgb(0, 122, 204), + ForeColor = Color.White, + FlatStyle = FlatStyle.Flat + }; + btnSave.FlatAppearance.BorderSize = 0; + btnSave.Click += (s, e) => { this.CompiledScriptText = txtScript.Text; this.Close(); }; + this.Controls.Add(btnSave); + + // 4. Cancel Operative Control Button + btnCancel = new Button + { + Text = "Cancel", + DialogResult = DialogResult.Cancel, + Location = new Point(370, 295), + Size = new Size(100, 30), + FlatStyle = FlatStyle.Flat + }; + this.AcceptButton = btnSave; + this.CancelButton = btnCancel; + this.Controls.Add(btnCancel); + } + } +} \ No newline at end of file diff --git a/X12UtilsFRM/FunctoidXsltCompiler.cs b/X12UtilsFRM/FunctoidXsltCompiler.cs new file mode 100644 index 00000000..01652b91 --- /dev/null +++ b/X12UtilsFRM/FunctoidXsltCompiler.cs @@ -0,0 +1,69 @@ +using System; + +namespace X12UtilsFRM +{ + public static class FunctoidXsltCompiler + { + /// + /// Generates an XSLT element snippet matching the processing rules of standard BizTalk functoids. + /// + /// The type of the operational functoid capsule. + /// The computed absolute XPath matching the linked source document node. + /// The fallback sanitized output XML node name tag structure. + public static string GetXsltSnippet(string functoidName, string sourceXPath, string targetNodeName) + { + switch (functoidName) + { + // ========================================== + // STRING FUNCTOIDS + // ========================================== + case "Uppercase": + return $"<{targetNodeName}>"; + + case "Lowercase": + return $"<{targetNodeName}>"; + + case "Trim": + return $"<{targetNodeName}>"; + + case "String Left": + // XSLT 1.0 substring extraction rule (Starts at index position 1, captures 4 chars as an initial sample frame) + return $"<{targetNodeName}>"; + + case "String Right": + // Grabs the trailing tail subset elements natively + return $"<{targetNodeName}>"; + + // ========================================== + // MATHEMATICAL TOOLS + // ========================================== + case "Add": + return $"<{targetNodeName}>"; + + case "Subtract": + return $"<{targetNodeName}>"; + + case "Absolute": + return $"<{targetNodeName}>"; + + // ========================================== + // DATE / TIME UTILITIES + // ========================================== + case "Current Date": + // Safe basic expression string rule + return $"<{targetNodeName}>"; + + // ========================================== + // INTERNAL SYSTEM FALLBACKS + // ========================================== + case "DirectLink": + // Used when a line stretches directly from a tree item straight into another tree item (no capsule) + return $"<{targetNodeName}>"; + + default: + // General pass-through backup option + return $"<{targetNodeName}>"; + } + } + } +} \ No newline at end of file diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index 2d3f8dbd..7bfa04b2 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -58,29 +58,7 @@ protected override void WndProc(ref Message m) } // NEW HELPER METHOD: Seamlessly finds the correct UI component to map paths to - private Control ResolveSourceControl(object source) - { - if (source is Control ctrl) return ctrl; - - // If it's tracking an XmlNode data instance, look into our side scroll container lane - if (source is System.Xml.XmlNode xmlNode && this.Parent != null) - { - foreach (Control c in this.Parent.Controls) - { - if (c is FlowLayoutPanel pnlScroll && (pnlScroll.Name == "pnlSchemaScrollContainer" || pnlScroll.Width == 285)) - { - foreach (Control subCtrl in pnlScroll.Controls) - { - if (subCtrl is SchemaNodeItem sni && sni.XmlSourceNode == xmlNode) - { - return sni; - } - } - } - } - } - return null; - } + private void CheckForLineRightClick(Point clickPt) { @@ -146,36 +124,160 @@ protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) canvas.Clear(SKColors.Transparent); using (var paint = new SKPaint()) + using (var textPaint = new SKPaint()) { + // 1. Line Curve Paint Properties paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 2; paint.Color = SKColors.DodgerBlue; paint.IsAntialias = true; + // 2. Text Label Paint Properties + textPaint.Color = Color.FromArgb(70, 80, 110).ToSKColor(); // Slate-gray + textPaint.TextSize = 10.5f; // Tighter font size for clean side-by-side display + textPaint.IsAntialias = true; + textPaint.Typeface = SKTypeface.FromFamilyName("Segoe UI", SKFontStyle.Bold); + textPaint.TextAlign = SKTextAlign.Center; + foreach (var conn in Connections) { - // CRITICAL FIX: Resolve visual control reference dynamically var visualSource = ResolveSourceControl(conn.Source); + var visualTarget = conn.Target as Control; // Fallback resolve for standard controls + var start = GetControlPoint(visualSource, isSource: true); - var end = GetControlPoint(conn.Target as Control, isSource: false); + var end = GetControlPoint(visualTarget, isSource: false); if (start != SKPoint.Empty && end != SKPoint.Empty) { - DrawBezierLine(canvas, paint, start, end); + // --- RESOLVE SOURCE LABEL STRING --- + string sourceLabelText = ""; + if (conn.Source is System.Xml.XmlNode srcXmlNode) + { + sourceLabelText = srcXmlNode.Name; + } + else if (visualSource is SchemaNodeItem srcSni) + { + sourceLabelText = srcSni.XmlSourceNode.Name; + } + else if (visualSource is BizTalkFunctoidNode srcFunctoid) + { + sourceLabelText = srcFunctoid.FunctoidName; + } + + // --- RESOLVE TARGET LABEL STRING --- + string targetLabelText = "dddddd"; + if (conn.Target is SchemaNodeItem tgtSni) + { + targetLabelText = tgtSni.XmlSourceNode.Name; + } + else if (visualTarget is BizTalkFunctoidNode tgtFunctoid) + { + targetLabelText = tgtFunctoid.FunctoidName; + } + + // Draw the line with both structural labels attached! + DrawBezierLine(canvas, paint, textPaint, start, end, sourceLabelText, targetLabelText); } } } } - private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPoint start, SKPoint end) + private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, SKPoint start, SKPoint end, string sourceLabel, string targetLabel) { + float controlOffset = Math.Abs(start.X - end.X) / 2; + + SKPoint p0 = start; + SKPoint p1 = new SKPoint(start.X + controlOffset, start.Y); + SKPoint p2 = new SKPoint(end.X - controlOffset, end.Y); + SKPoint p3 = end; + + // A. Draw the main Bezier curve link line using (var path = new SKPath()) { path.MoveTo(start); - float controlOffset = Math.Abs(start.X - end.X) / 2; - path.CubicTo(start.X + controlOffset, start.Y, end.X - controlOffset, end.Y, end.X, end.Y); + path.CubicTo(p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y); canvas.DrawPath(path, paint); } + + // B. Render Source Label Badge near the first third mark (t = 0.30) + if (!string.IsNullOrEmpty(sourceLabel)) + { + SKPoint pointOnCurve = GetCubicBezierPoint(0.30f, p0, p1, p2, p3); + DrawLabelBadge(canvas, textPaint, pointOnCurve, sourceLabel); + } + + // C. Render Target Label Badge near the last third mark (t = 0.70) + if (!string.IsNullOrEmpty(targetLabel)) + { + SKPoint pointOnCurve = GetCubicBezierPoint(0.70f, p0, p1, p2, p3); + DrawLabelBadge(canvas, textPaint, pointOnCurve, targetLabel); + } + } + + // HELPER: Calculates exact XY positions along a Cubic Bezier curve at a given 't' percentage split + private SKPoint GetCubicBezierPoint(float t, SKPoint p0, SKPoint p1, SKPoint p2, SKPoint p3) + { + float u = 1 - t; + float tt = t * t; + float uu = u * u; + float uuu = uu * u; + float ttt = tt * t; + + float x = uuu * p0.X + 3 * uu * t * p1.X + 3 * u * tt * p2.X + ttt * p3.X; + float y = uuu * p0.Y + 3 * uu * t * p1.Y + 3 * u * tt * p2.Y + ttt * p3.Y; + + return new SKPoint(x, y); + } + + // HELPER: Renders a clean white protective text capsule card over the line layout canvas + private void DrawLabelBadge(SKCanvas canvas, SKPaint textPaint, SKPoint position, string text) + { + float textWidth = textPaint.MeasureText(text); + + // Draw background masking box so intersecting lines do not cut through the text characters + using (var bgPaint = new SKPaint { Color = SKColors.White, Style = SKPaintStyle.Fill }) + { + var bgRect = new SKRect(position.X - (textWidth / 2) - 5, position.Y - 13, position.X + (textWidth / 2) + 5, position.Y + 3); + canvas.DrawRoundRect(bgRect, 4, 4, bgPaint); + } + + // Print the clean centered text label + canvas.DrawText(text, position.X, position.Y - 1, textPaint); + } + private Control ResolveSourceControl(object source) + { + if (source is Control ctrl) return ctrl; + + if (source is System.Xml.XmlNode xmlNode && this.Parent != null) + { + // 1. Scan Left Column (Source Schema Tree Pane Container) + foreach (Control c in this.Parent.Controls) + { + if (c is FlowLayoutPanel pnlScroll && pnlScroll.Name == "pnlSchemaScrollContainer") + { + foreach (Control subCtrl in pnlScroll.Controls) + { + if (subCtrl is SchemaNodeItem sni && sni.XmlSourceNode == xmlNode) + { + return sni; + } + } + } + + // 2. Scan Right Column (Target Schema Tree Pane Container) + if (c is FlowLayoutPanel pnlTargetScroll && pnlTargetScroll.Name == "pnlTargetSchemaScrollContainer") + { + foreach (Control subCtrl in pnlTargetScroll.Controls) + { + if (subCtrl is SchemaNodeItem sni && sni.XmlSourceNode == xmlNode) + { + return sni; + } + } + } + } + } + return null; } private SKPoint GetControlPoint(Control ctrl, bool isSource) @@ -184,8 +286,11 @@ private SKPoint GetControlPoint(Control ctrl, bool isSource) try { + // If it's a source, line should emerge from the RIGHT edge. + // If it's a target, line should snap into the LEFT edge. int targetX = isSource ? ctrl.Width : 0; Point localAnchorPt = new Point(targetX, ctrl.Height / 2); + Point screenPt = ctrl.PointToScreen(localAnchorPt); Point localPt = this.PointToClient(screenPt); @@ -196,6 +301,7 @@ private SKPoint GetControlPoint(Control ctrl, bool isSource) return SKPoint.Empty; } } + } public class MappingConnection diff --git a/X12UtilsFRM/ToolboxCategory.cs b/X12UtilsFRM/ToolboxCategory.cs index 0516574c..44747363 100644 --- a/X12UtilsFRM/ToolboxCategory.cs +++ b/X12UtilsFRM/ToolboxCategory.cs @@ -21,7 +21,7 @@ public ToolboxCategory(string name, List functoids, Action onStateChange this.FunctoidTemplates = functoids; this._onStateChanged = onStateChanged; - this.Width = 220; // Slightly narrower to safely clear parent scrollbars + this.Width = 205; // Lock the base category width tightly this.BackColor = Color.Transparent; // 1. Category Header Label @@ -43,15 +43,13 @@ public ToolboxCategory(string name, List functoids, Action onStateChange // 2. Content Flow Panel for Functoids pnlContent = new FlowLayoutPanel { - // FIX A: Remove DockStyle.Fill! Use Top anchoring and manual positioning instead. Location = new Point(0, lblHeader.Height), - Width = this.Width, + Width = this.Width, // Enforce strict fixed width tracking BackColor = Color.FromArgb(250, 250, 252), - Padding = new Padding(6), + Padding = new Padding(6, 4, 6, 4), FlowDirection = FlowDirection.LeftToRight, WrapContents = true, - AutoSize = true, // FIX B: Let it resize itself naturally to fit its rows! - AutoSizeMode = AutoSizeMode.GrowAndShrink, + AutoSize = false, // CRITICAL FIX: Turn off AutoSize so it stops expanding horizontally! Visible = false }; @@ -62,14 +60,34 @@ public ToolboxCategory(string name, List functoids, Action onStateChange } this.Controls.Add(pnlContent); - - // Explicitly force layout tree depth stacking ordering this.Controls.SetChildIndex(lblHeader, 0); this.Controls.SetChildIndex(pnlContent, 1); UpdateHeight(); } + public void UpdateHeight() + { + if (!IsExpanded) + { + this.Height = lblHeader.Height; + } + else + { + // Force inner flow layout boundaries to match the parent category container perfectly + pnlContent.Width = this.Width; + + // Force the layout engine to calculate wrapping rows based on the rigid fixed width bounds + pnlContent.PerformLayout(); + + // Ask the layout engine how much vertical space it needs for the wrapped grid rows + Size neededSize = pnlContent.GetPreferredSize(new Size(pnlContent.Width, 0)); + + // Apply the computed height constraints directly to both container layers + pnlContent.Height = neededSize.Height; + this.Height = lblHeader.Height + pnlContent.Height + 4; + } + } private Label CreateTemplateItem(string text) { Label lbl = new Label @@ -79,29 +97,27 @@ private Label CreateTemplateItem(string text) BackColor = Color.LightSteelBlue, BorderStyle = BorderStyle.FixedSingle, TextAlign = ContentAlignment.MiddleCenter, - Size = new Size(92, 28), // Safe button size matrix - Margin = new Padding(4), + // FIX B: Shrink item size from 92px down to 90px wide. + // (2 buttons * 90px) + margins + padding fits beautifully in a 210px container! + Size = new Size(90, 28), + Margin = new Padding(3), Cursor = Cursors.Hand }; - // Smart Drag-Size Threshold Logic + // Keep your smart drag-size tracking logic intact... Point mouseDownLocation = Point.Empty; bool isPotentialDrag = false; - lbl.MouseDown += (s, e) => { - if (e.Button == MouseButtons.Left) - { - isPotentialDrag = true; - mouseDownLocation = e.Location; - } + lbl.MouseDown += (s, e) => + { + if (e.Button == MouseButtons.Left) { isPotentialDrag = true; mouseDownLocation = e.Location; } }; - - lbl.MouseMove += (s, e) => { + lbl.MouseMove += (s, e) => + { if (isPotentialDrag) { int deltaX = Math.Abs(e.X - mouseDownLocation.X); int deltaY = Math.Abs(e.Y - mouseDownLocation.Y); - if (deltaX >= SystemInformation.DragSize.Width || deltaY >= SystemInformation.DragSize.Height) { isPotentialDrag = false; @@ -110,7 +126,6 @@ private Label CreateTemplateItem(string text) } } }; - lbl.MouseUp += (s, e) => { if (e.Button == MouseButtons.Left) isPotentialDrag = false; }; return lbl; @@ -125,21 +140,7 @@ private void Header_Click(object sender, EventArgs e) UpdateHeight(); _onStateChanged?.Invoke(); } - - public void UpdateHeight() - { - if (!IsExpanded) - { - this.Height = lblHeader.Height; - } - else - { - // Force the layout engine to resolve auto-size parameters instantly - pnlContent.PerformLayout(); - - // FIX C: Calculate height strictly based on the real size of the auto-sized content panel - this.Height = lblHeader.Height + pnlContent.Height + 4; - } - } } -} \ No newline at end of file +} + + \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 1be23bdd..f0c8d1c4 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -47,7 +47,7 @@ private void InitializeComponent() this.rbHtml = new System.Windows.Forms.RadioButton(); this.rbXml = new System.Windows.Forms.RadioButton(); this.btnAddFiles = new System.Windows.Forms.Button(); - this.lbxFileList = new System.Windows.Forms.ListBox(); + this.lbxInfileList = new System.Windows.Forms.ListBox(); this.rtLog = new System.Windows.Forms.RichTextBox(); this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); this.browser = new System.Windows.Forms.TabPage(); @@ -59,6 +59,7 @@ private void InitializeComponent() this.pnlFunctoids = new System.Windows.Forms.Panel(); this.trvTarget = new System.Windows.Forms.TreeView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.lbxTargetSchema = new System.Windows.Forms.ListBox(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -77,7 +78,7 @@ private void InitializeComponent() // statusStrip1 // this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.statusStrip1.Location = new System.Drawing.Point(0, 545); + this.statusStrip1.Location = new System.Drawing.Point(0, 768); this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); this.statusStrip1.Size = new System.Drawing.Size(1298, 22); @@ -95,7 +96,7 @@ private void InitializeComponent() this.tabControl1.Margin = new System.Windows.Forms.Padding(2); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1298, 545); + this.tabControl1.Size = new System.Drawing.Size(1298, 768); this.tabControl1.TabIndex = 1; this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); // @@ -106,7 +107,7 @@ private void InitializeComponent() this.parse.Margin = new System.Windows.Forms.Padding(2); this.parse.Name = "parse"; this.parse.Padding = new System.Windows.Forms.Padding(2); - this.parse.Size = new System.Drawing.Size(1290, 519); + this.parse.Size = new System.Drawing.Size(1290, 742); this.parse.TabIndex = 0; this.parse.Text = "Parse"; this.parse.UseVisualStyleBackColor = true; @@ -121,6 +122,7 @@ private void InitializeComponent() // // splitContainer1.Panel1 // + this.splitContainer1.Panel1.Controls.Add(this.lbxTargetSchema); this.splitContainer1.Panel1.Controls.Add(this.chkBrowse); this.splitContainer1.Panel1.Controls.Add(this.btnMap); this.splitContainer1.Panel1.Controls.Add(this.btnFindSpec); @@ -133,13 +135,13 @@ private void InitializeComponent() this.splitContainer1.Panel1.Controls.Add(this.label1); this.splitContainer1.Panel1.Controls.Add(this.groupBox1); this.splitContainer1.Panel1.Controls.Add(this.btnAddFiles); - this.splitContainer1.Panel1.Controls.Add(this.lbxFileList); + this.splitContainer1.Panel1.Controls.Add(this.lbxInfileList); // // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.rtLog); this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); - this.splitContainer1.Size = new System.Drawing.Size(1286, 515); + this.splitContainer1.Size = new System.Drawing.Size(1286, 738); this.splitContainer1.SplitterDistance = 363; this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; @@ -149,7 +151,7 @@ private void InitializeComponent() this.chkBrowse.AutoSize = true; this.chkBrowse.Checked = global::X12UtilsFRM.Properties.Settings.Default.BrowseWhenSelected; this.chkBrowse.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "BrowseWhenSelected", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.chkBrowse.Location = new System.Drawing.Point(15, 235); + this.chkBrowse.Location = new System.Drawing.Point(5, 213); this.chkBrowse.Name = "chkBrowse"; this.chkBrowse.Size = new System.Drawing.Size(127, 17); this.chkBrowse.TabIndex = 12; @@ -159,7 +161,7 @@ private void InitializeComponent() // btnMap // this.btnMap.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnMap.Location = new System.Drawing.Point(15, 443); + this.btnMap.Location = new System.Drawing.Point(8, 666); this.btnMap.Margin = new System.Windows.Forms.Padding(2); this.btnMap.Name = "btnMap"; this.btnMap.Size = new System.Drawing.Size(158, 34); @@ -172,7 +174,7 @@ private void InitializeComponent() // btnFindSpec // this.btnFindSpec.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnFindSpec.Location = new System.Drawing.Point(15, 405); + this.btnFindSpec.Location = new System.Drawing.Point(8, 628); this.btnFindSpec.Margin = new System.Windows.Forms.Padding(2); this.btnFindSpec.Name = "btnFindSpec"; this.btnFindSpec.Size = new System.Drawing.Size(158, 34); @@ -185,7 +187,7 @@ private void InitializeComponent() // btnHippaParse // this.btnHippaParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnHippaParse.Location = new System.Drawing.Point(15, 367); + this.btnHippaParse.Location = new System.Drawing.Point(8, 590); this.btnHippaParse.Margin = new System.Windows.Forms.Padding(2); this.btnHippaParse.Name = "btnHippaParse"; this.btnHippaParse.Size = new System.Drawing.Size(158, 34); @@ -198,7 +200,7 @@ private void InitializeComponent() // button1 // this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button1.Location = new System.Drawing.Point(15, 329); + this.button1.Location = new System.Drawing.Point(8, 552); this.button1.Margin = new System.Windows.Forms.Padding(2); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(158, 34); @@ -210,7 +212,7 @@ private void InitializeComponent() // btnParse // this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnParse.Location = new System.Drawing.Point(210, 295); + this.btnParse.Location = new System.Drawing.Point(203, 518); this.btnParse.Margin = new System.Windows.Forms.Padding(2); this.btnParse.Name = "btnParse"; this.btnParse.Size = new System.Drawing.Size(122, 25); @@ -226,7 +228,7 @@ private void InitializeComponent() this.lblInterchangeCount.AutoSize = true; this.lblInterchangeCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lblInterchangeCount.ForeColor = System.Drawing.Color.Red; - this.lblInterchangeCount.Location = new System.Drawing.Point(112, 85); + this.lblInterchangeCount.Location = new System.Drawing.Point(207, 65); this.lblInterchangeCount.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.lblInterchangeCount.Name = "lblInterchangeCount"; this.lblInterchangeCount.Size = new System.Drawing.Size(19, 20); @@ -238,7 +240,7 @@ private void InitializeComponent() // this.label3.AutoSize = true; this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label3.Location = new System.Drawing.Point(4, 85); + this.label3.Location = new System.Drawing.Point(88, 65); this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(115, 20); @@ -272,7 +274,7 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.rbHtml); this.groupBox1.Controls.Add(this.rbXml); this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.groupBox1.Location = new System.Drawing.Point(15, 272); + this.groupBox1.Location = new System.Drawing.Point(8, 495); this.groupBox1.Margin = new System.Windows.Forms.Padding(2); this.groupBox1.Name = "groupBox1"; this.groupBox1.Padding = new System.Windows.Forms.Padding(2); @@ -322,15 +324,15 @@ private void InitializeComponent() this.btnAddFiles.UseVisualStyleBackColor = true; this.btnAddFiles.Click += new System.EventHandler(this.btnAddFiles_Click); // - // lbxFileList + // lbxInfileList // - this.lbxFileList.FormattingEnabled = true; - this.lbxFileList.Location = new System.Drawing.Point(8, 108); - this.lbxFileList.Margin = new System.Windows.Forms.Padding(2); - this.lbxFileList.Name = "lbxFileList"; - this.lbxFileList.Size = new System.Drawing.Size(356, 121); - this.lbxFileList.TabIndex = 0; - this.lbxFileList.SelectedIndexChanged += new System.EventHandler(this.lbxFileList_SelectedIndexChanged); + this.lbxInfileList.FormattingEnabled = true; + this.lbxInfileList.Location = new System.Drawing.Point(5, 87); + this.lbxInfileList.Margin = new System.Windows.Forms.Padding(2); + this.lbxInfileList.Name = "lbxInfileList"; + this.lbxInfileList.Size = new System.Drawing.Size(356, 121); + this.lbxInfileList.TabIndex = 0; + this.lbxInfileList.SelectedIndexChanged += new System.EventHandler(this.lbxInputFileList); // // rtLog // @@ -340,7 +342,7 @@ private void InitializeComponent() this.rtLog.ForeColor = System.Drawing.Color.Lime; this.rtLog.Location = new System.Drawing.Point(0, 0); this.rtLog.Name = "rtLog"; - this.rtLog.Size = new System.Drawing.Size(920, 515); + this.rtLog.Size = new System.Drawing.Size(920, 738); this.rtLog.TabIndex = 1; this.rtLog.Text = "aaaa"; // @@ -441,11 +443,20 @@ private void InitializeComponent() this.trvTarget.Size = new System.Drawing.Size(441, 519); this.trvTarget.TabIndex = 1; // + // lbxTargetSchema + // + this.lbxTargetSchema.FormattingEnabled = true; + this.lbxTargetSchema.Location = new System.Drawing.Point(3, 283); + this.lbxTargetSchema.Margin = new System.Windows.Forms.Padding(2); + this.lbxTargetSchema.Name = "lbxTargetSchema"; + this.lbxTargetSchema.Size = new System.Drawing.Size(356, 147); + this.lbxTargetSchema.TabIndex = 13; + // // X12UtilsFRM // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1298, 567); + this.ClientSize = new System.Drawing.Size(1298, 790); this.Controls.Add(this.tabControl1); this.Controls.Add(this.statusStrip1); this.Margin = new System.Windows.Forms.Padding(2); @@ -480,7 +491,7 @@ private void InitializeComponent() private System.Windows.Forms.TabPage parse; private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.TabPage browser; - private System.Windows.Forms.ListBox lbxFileList; + private System.Windows.Forms.ListBox lbxInfileList; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.RadioButton rbHtml; private System.Windows.Forms.RadioButton rbXml; @@ -506,6 +517,7 @@ private void InitializeComponent() private System.Windows.Forms.TreeView trvTarget; private System.Windows.Forms.CheckBox chkBrowse; private System.Windows.Forms.Panel pnlFunctoids; + private System.Windows.Forms.ListBox lbxTargetSchema; } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index f5a4a8c1..ba677352 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -33,23 +33,22 @@ public partial class X12UtilsFRM : Form { private List toolboxCategories = new List(); private Panel pnlToolboxContainer = null; - //-- DRAGGING STATE TRACKERS (CRITICAL for smooth UX) -- private bool _isDraggingFunctoid = false; private Point _dragStartMousePos; private Point _dragStartControlPos; //-- END DRAGGING STATE TRACKERS -- - // This flat registry will hold every single node item for quick access during layout calculations and visibility checks - private List flatSchemaRegistry = new List(); - // Define these class-level variables inside X12UtilsFRM.cs private Panel pnlToolboxWrapper = null; - private FlowLayoutPanel pnlToolboxCategoriesContainer = null; + private FlowLayoutPanel pnlToolboxCategoriesContainer = null; + private List flatSchemaRegistry = new List(); + // Add this field at the top of X12UtilsFRM.cs with your other panel declarations + private FlowLayoutPanel pnlTargetSchemaScrollContainer; + private List flatTargetSchemaRegistry = new List(); private Button btnToolboxToggle = null; private bool _isToolboxExpanded = true; private const int ToolboxWidth = 245; - private void InitializeToolbox() { // 1. The main master wrapper panel pinned to the far right edge of the workspace canvas @@ -70,7 +69,7 @@ private void InitializeToolbox() Font = new Font("Segoe UI", 9, FontStyle.Bold), Width = 20, Dock = DockStyle.Left, - FlatStyle = FlatStyle.Flat, + FlatStyle = FlatStyle.Popup, BackColor = Color.FromArgb(220, 225, 235), ForeColor = Color.FromArgb(50, 50, 80), Cursor = Cursors.Hand @@ -87,7 +86,7 @@ private void InitializeToolbox() FlowDirection = FlowDirection.TopDown, // Force items to stack vertically WrapContents = false, // Prevent side-by-side wrapping of categories AutoScroll = true, // Automatically show vertical scrollbar when needed - Padding = new Padding(0, 20, 0, 0) // Top padding matching + Padding = new Padding(20, 20, 20, 20) // Top padding matching }; pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); pnlToolboxCategoriesContainer.BringToFront(); @@ -106,7 +105,6 @@ private void InitializeToolbox() RenderToolboxLayout(); } - private void RenderToolboxLayout() { if (pnlToolboxCategoriesContainer == null) return; @@ -116,15 +114,14 @@ private void RenderToolboxLayout() foreach (var category in toolboxCategories) { - // 1. Give the category a solid fixed layout target width that leaves plenty of room - // for the parent container's scrollbar (ToolboxWidth is 245, so 215 works great) - category.Width = 215; + // Allocate a predictable fixed layout width that fits safely inside the container view + // regardless of whether the vertical scrollbar is currently visible or hidden. + category.Width = 205; - // 2. Recalculate heights dynamically based on the newly assigned width bounds + // Apply width parameters downwards into the category inner containers category.UpdateHeight(); - // 3. Apply standard column margins - category.Margin = new Padding(5, 0, 0, 8); + category.Margin = new Padding(6, 0, 0, 6); pnlToolboxCategoriesContainer.Controls.Add(category); } @@ -158,13 +155,10 @@ private void ToggleToolbox_Click(object sender, EventArgs e) pnlFunctoids.ResumeLayout(true); _mapper.Invalidate(); } - - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); List interchanges = null; ToolTip tt = null; private string locationsFile = ""; - private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") @@ -173,7 +167,6 @@ static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); Trace.Flush(); } - private void MakeControlDraggable(Control masterControl) { // Route dragging events from the master wrapper panel container itself @@ -185,13 +178,16 @@ private void MakeControlDraggable(Control masterControl) AttachDragEvents(child, masterControl); } } - private void AttachDragEvents(Control eventTriggerControl, Control actualMovingTarget) { eventTriggerControl.MouseDown += (sender, e) => { if (e.Button == MouseButtons.Left) { + // FIX PART 1: If Shift is held, skip this moving logic completely + // so BizTalkFunctoidNode's connection hook can fire! + if (Control.ModifierKeys == Keys.Shift) return; + _isDraggingFunctoid = true; _dragStartMousePos = Cursor.Position; _dragStartControlPos = actualMovingTarget.Location; @@ -201,6 +197,13 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT eventTriggerControl.MouseMove += (sender, e) => { + // FIX PART 2: Safety guard block + if (Control.ModifierKeys == Keys.Shift) + { + _isDraggingFunctoid = false; + return; + } + if (_isDraggingFunctoid) { int deltaX = Cursor.Position.X - _dragStartMousePos.X; @@ -224,9 +227,6 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT } }; } - - // Define this class-level variable at the top of X12UtilsFRM.cs - // private FlowLayoutPanel pnlSchemaScrollContainer = null; private FlowLayoutPanel pnlSchemaScrollContainer = new FlowLayoutPanel { Name = "pnlSchemaScrollContainer", // CRITICAL: Allows SkiaMapper to instantly detect it @@ -238,11 +238,12 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT AutoScroll = true, BackColor = Color.Transparent }; - private void InitializeEmbeddedSchemaLayout(string xmlFilePath) + private void InitializeEmbeddedSchemaLayout(string sourceXmlPath, string targetXmlPath) { pnlFunctoids.Controls.Clear(); _mapper.Connections.Clear(); flatSchemaRegistry.Clear(); + flatTargetSchemaRegistry.Clear(); // Reset the destination registry pnlFunctoids.BackColor = Color.Transparent; @@ -251,58 +252,159 @@ private void InitializeEmbeddedSchemaLayout(string xmlFilePath) pnlFunctoids.Controls.Add(_mapper); _mapper.SendToBack(); - // 2. NEW: Initialize the Scrollable Container for the Tree Column + // 2. Left Column: Full-Height Source Document Tree Container pnlSchemaScrollContainer = new FlowLayoutPanel { - Width = 285, // 260px node width + 25px for the vertical scrollbar buffer - Location = new Point(20, 20), + Name = "pnlSchemaScrollContainer", + Width = 285, + Location = new Point(0, 0), + Height = pnlFunctoids.Height, Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left, - FlowDirection = FlowDirection.TopDown, // Stack nodes vertically - WrapContents = false, // Keep them in a single column - AutoScroll = true, // Enable the scrollbar! - BackColor = Color.Transparent // Let Skia lines show through behind it + FlowDirection = FlowDirection.TopDown, + WrapContents = false, + AutoScroll = true, + BackColor = Color.Transparent }; - - - // Add this line immediately after setting up pnlSchemaScrollContainer in InitializeEmbeddedSchemaLayout: pnlSchemaScrollContainer.Scroll += (s, e) => { _mapper.Invalidate(); }; pnlFunctoids.Controls.Add(pnlSchemaScrollContainer); pnlSchemaScrollContainer.BringToFront(); - // 3. Load the XML schema data - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFilePath); - - BuildCustomSchemaTree(doc.DocumentElement, 0); - - // Render tree nodes inside our brand new scrollable lane - RenderCustomSchemaLayout(); - - // Initialize your right-hand toolbox panel + // 3. NEW: Right Column: Full-Height Target Document Tree Container + // Positions it perfectly adjacent to the right edge toolbox panel boundary + int targetLeftCoordinate = pnlFunctoids.Width - 285 - (pnlToolboxWrapper?.Width ?? 220); + pnlTargetSchemaScrollContainer = new FlowLayoutPanel + { + Name = "pnlTargetSchemaScrollContainer", + Width = 285, + Location = new Point(targetLeftCoordinate, 0), + Height = pnlFunctoids.Height, + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right, // Anchors right! + FlowDirection = FlowDirection.TopDown, + WrapContents = false, + AutoScroll = true, + BackColor = Color.Transparent, + AllowDrop = true + }; + // FIX 2: Wire up the DragEnter and DragOver events to accept incoming mapping links + pnlTargetSchemaScrollContainer.DragEnter += TargetSchemaPanel_DragEnterOrOver; + pnlTargetSchemaScrollContainer.DragOver += TargetSchemaPanel_DragEnterOrOver; + pnlTargetSchemaScrollContainer.DragDrop += pnlFunctoids_DragDrop; + // Keep your scrolling refresh trigger intact + pnlTargetSchemaScrollContainer.Scroll += (s, e) => { _mapper.Invalidate(); }; + pnlFunctoids.Controls.Add(pnlTargetSchemaScrollContainer); + pnlTargetSchemaScrollContainer.BringToFront(); + + // 4. Load Source XML Data + XmlDocument sourceDoc = new XmlDocument(); + sourceDoc.Load(sourceXmlPath); + BuildCustomSchemaTree(sourceDoc.DocumentElement, 0, isTargetSchema: false); + RenderCustomSchemaLayout(isTargetSchema: false); + + // 5. Load Target XML Data + XmlDocument targetDoc = new XmlDocument(); + targetDoc.Load(targetXmlPath); + BuildCustomSchemaTree(targetDoc.DocumentElement, 0, isTargetSchema: true); + RenderCustomSchemaLayout(isTargetSchema: true); + + // Initialize right-hand toolbox panel accordion panels InitializeToolbox(); pnlFunctoids.AllowDrop = true; _mapper.Invalidate(); } - private void BuildCustomSchemaTree(XmlNode xmlNode, int indent, SchemaNodeItem parentItem = null) + private void RenderCustomSchemaLayout(bool isTargetSchema) + { + FlowLayoutPanel container = isTargetSchema ? pnlTargetSchemaScrollContainer : pnlSchemaScrollContainer; + List registry = isTargetSchema ? flatTargetSchemaRegistry : flatSchemaRegistry; + + if (container == null) return; + + container.SuspendLayout(); + container.Controls.Clear(); + + bool isFirstItem = true; + + foreach (var item in registry) + { + // Calculate visible collapse expansion loops hierarchy states + if (IsNodeChainVisible(item)) + { + item.Width = container.Width - 25; + + if (isFirstItem) + { + item.Margin = new Padding(0, 10, 0, 2); + isFirstItem = false; + } + else + { + item.Margin = new Padding(0, 0, 0, 2); + } + + container.Controls.Add(item); + } + } + + container.ResumeLayout(true); + } + private void BuildCustomSchemaTree(XmlNode node, int depth, bool isTargetSchema) { - if (xmlNode.NodeType != XmlNodeType.Element) return; + if (node == null) return; - var nodeItem = new SchemaNodeItem(xmlNode, indent, (clickedItem) => + SchemaNodeItem item = new SchemaNodeItem(node, depth, (clickedItem) => { - // Redraw the entire layout configuration whenever a user collapses/expands a branch - RenderCustomSchemaLayout(); + RenderCustomSchemaLayout(isTargetSchema); _mapper.Invalidate(); }); - if (parentItem != null) - parentItem.ChildNodes.Add(nodeItem); + if (isTargetSchema) + { + flatTargetSchemaRegistry.Add(item); + + // FIX: Deep-wire the drag-and-drop validation rules down to the subcomponent layer! + EnableTargetNodeDragDropInteractions(item); + } + else + { + flatSchemaRegistry.Add(item); + } + + if (node.Attributes != null) + { + foreach (XmlAttribute attr in node.Attributes) + { + BuildCustomSchemaTree(attr, depth + 1, isTargetSchema); + } + } - flatSchemaRegistry.Add(nodeItem); + foreach (XmlNode child in node.ChildNodes) + { + if (child.NodeType == XmlNodeType.Element) + { + BuildCustomSchemaTree(child, depth + 1, isTargetSchema); + } + } + } + private void EnableTargetNodeDragDropInteractions(Control rootTargetControl) + { + rootTargetControl.AllowDrop = true; + rootTargetControl.DragEnter += TargetSchemaPanel_DragEnterOrOver; + rootTargetControl.DragOver += TargetSchemaPanel_DragEnterOrOver; + rootTargetControl.DragDrop += pnlFunctoids_DragDrop; - foreach (XmlNode child in xmlNode.ChildNodes) + // Loop through nested controls (like the text label and icon inside SchemaNodeItem) + foreach (Control childControl in rootTargetControl.Controls) { - BuildCustomSchemaTree(child, indent + 1, nodeItem); + childControl.AllowDrop = true; + childControl.DragEnter += TargetSchemaPanel_DragEnterOrOver; + childControl.DragOver += TargetSchemaPanel_DragEnterOrOver; + childControl.DragDrop += pnlFunctoids_DragDrop; + + // Go deeper if your row item has nested layouts + if (childControl.HasChildren) + { + EnableTargetNodeDragDropInteractions(childControl); + } } } private void RenderCustomSchemaLayout() @@ -353,7 +455,6 @@ public string X12ToXml(string x12) return sr.ReadToEnd(); } } - private SkiaMapper _mapper; private void UpdateMap() { // This is where you'd update the _mapper.Connections based on the current state of your UI controls @@ -407,7 +508,10 @@ private void Form1_Load(object sender, EventArgs e) btnAddFiles_Click(null, null); } - lbxFileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); + lbxInfileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); + lbxTargetSchema.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); + + btnParse.Enabled = false; Logger.Trace("Trace message"); Logger.Debug("Debug message"); @@ -495,11 +599,11 @@ private void lblInterchangeCount_TextChanged(object sender, EventArgs e) int fcount = int.Parse(((Label)sender).Text); btnParse.Enabled = fcount == 1 ? true : false; } - private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) + private void lbxInputFileList(object sender, EventArgs e) { string fileName = ((ListBox)sender).Text; if (String.IsNullOrEmpty(fileName)) return; - tt.SetToolTip(lbxFileList, fileName + " is Selected now.."); + tt.SetToolTip(lbxInfileList, fileName + " is Selected now.."); if (chkBrowse.Checked) { @@ -522,13 +626,13 @@ private void lbxFileList_SelectedIndexChanged(object sender, EventArgs e) - //lblSelectedFile.Text = Path.GetFileName(fileName); - //Log($"fileName={fileName}"); + //lblSelectedFile.Text = Path.GetFileName(inputFileName); + //Log($"inputFileName={inputFileName}"); //bool throwException = Properties.Settings.Default.throwExceptions; - //rtxInterchangeFile.Text = ContentFromFile(fileName); + //rtxInterchangeFile.Text = ContentFromFile(inputFileName); //X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); @@ -551,11 +655,11 @@ private void btnAddFiles_Click(object sender, EventArgs e) fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; fd.FilterIndex = 0; - lbxFileList.Items.Clear(); - lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); - lbxFileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); - string[] ss = new string[lbxFileList.Items.Count]; - lbxFileList.Items.CopyTo(ss, 0); + lbxInfileList.Items.Clear(); + lbxInfileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); + lbxInfileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); + string[] ss = new string[lbxInfileList.Items.Count]; + lbxInfileList.Items.CopyTo(ss, 0); Properties.Settings.Default.fileList = String.Join(",", ss); Properties.Settings.Default.Save(); @@ -606,12 +710,12 @@ private void btnFindSpec_Click(object sender, EventArgs e) } private void btnHippaParse_Click(object sender, EventArgs e) { - if (lbxFileList.SelectedItem == null) + if (lbxInfileList.SelectedItem == null) { MessageBox.Show("Please choose a file .."); return; } - Stream stream = new FileStream($"{lbxFileList.SelectedItem}", FileMode.Open, FileAccess.Read); + Stream stream = new FileStream($"{lbxInfileList.SelectedItem}", FileMode.Open, FileAccess.Read); @@ -647,7 +751,7 @@ private void btnHippaParse_Click(object sender, EventArgs e) - String outfile = $"{lbxFileList.SelectedItem}.pdf"; + String outfile = $"{lbxInfileList.SelectedItem}.pdf"; try { if (File.Exists(outfile)) @@ -790,8 +894,15 @@ private void LoadSchemaAsDiagramStart(string xmlFilePath) } private void btnMap_Click(object sender, EventArgs e) { - string fileName = lbxFileList.Text; - if (Path.GetExtension(fileName) != ".xml") + string inputFileName = lbxInfileList.Text; + string outputFileName = lbxTargetSchema.Text; + if(String.IsNullOrEmpty(inputFileName) || String.IsNullOrEmpty(outputFileName)) + { + MessageBox.Show("Please select both source and target XML files for mapping."); + return; + } + + if (Path.GetExtension(inputFileName) != ".xml") { MessageBox.Show("File extension must be an XML"); return; @@ -802,7 +913,7 @@ private void btnMap_Click(object sender, EventArgs e) tabControl1.SelectedIndex = (int)enmTabPages.map; // Initialize our single embedded layout canvas—No more trvSource duplicate setup! - InitializeEmbeddedSchemaLayout(fileName); + InitializeEmbeddedSchemaLayout(inputFileName, outputFileName); } #endregion buttons private void Ict_DebugFile(object sender, string e) @@ -869,14 +980,49 @@ private void trvSource_ItemDrag(object sender, ItemDragEventArgs e) #endregion treeControls #region pnlFunctoids - private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) + + private Control ResolveActualTargetNode(Control control, Point clientPt) { - // If this method name doesn't match the one in your Designer, the cursor won't change. - if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent("System.Windows.Forms.TreeNode")) + if (control == null) return null; + + // 1. If dropping onto the Skia background surface, check if a control is physically underneath + if (control is SkiaMapper) { - e.Effect = DragDropEffects.Link; + // Check functoids and right panel items first + foreach (Control c in pnlFunctoids.Controls) + { + if (c != _mapper && c.Bounds.Contains(clientPt)) + { + return ResolveActualTargetNode(c, clientPt); + } + } + } + + // 2. NEW: If the mouse is over a child label inside a SchemaNodeItem, find its parent row item + if (control.Parent is SchemaNodeItem targetSchemaItem) + { + // Ensure this row item actually lives inside the target panel registry + if (flatTargetSchemaRegistry.Contains(targetSchemaItem)) + { + return targetSchemaItem; + } + } + + // 3. If the mouse is over a child label inside a Functoid capsule, find its parent functoid + if (control.Parent is BizTalkFunctoidNode targetCapsule) + { + return targetCapsule; + } + + // 4. Return the control directly if it's already a valid base target type + if (control is BizTalkFunctoidNode || control is SchemaNodeItem) + { + return control; } + + return control; } + private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) { TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); @@ -929,32 +1075,73 @@ private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) _mapper.Invalidate(); } } + + private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) + { + // Check if the data being dragged is a TreeNode payload or a Functoid capsule + if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) + { + e.Effect = DragDropEffects.Copy | DragDropEffects.Link; + } + else + { + e.Effect = DragDropEffects.None; + } + } + + + #endregion pnlFunctoids + private void TargetSchemaPanel_DragEnterOrOver(object sender, DragEventArgs e) + { + // Check if the payload is a Left Tree Node or an active Canvas Functoid + if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) + { + // Force the OS to display the clean link/drop pointer instead of the disallowed circle! + e.Effect = DragDropEffects.Link; + } + else + { + e.Effect = DragDropEffects.None; + } + } private Control CreateFunctoid(string text, Point location) { - // Instantiation call utilizing our new BizTalk theme profile BizTalkFunctoidNode functoidNode = new BizTalkFunctoidNode(text, location); - - // Bind dragging capabilities across all nested control elements MakeControlDraggable(functoidNode); - // Context Menu for right-click deletion ContextMenuStrip functoidMenu = new ContextMenuStrip(); - var deleteItem = new ToolStripMenuItem("Delete Functoid"); + // NEW ITEM: Configure Script Editor + var editScriptItem = new ToolStripMenuItem("Configure Script Properties..."); + editScriptItem.Image = SystemIcons.Question.ToBitmap(); // Add a clean systematic glyph contextually if wanted + editScriptItem.Click += (sender, e) => + { + // Open our modal dialog window, seeding it with the node's current custom script string + using (var editorDlg = new FunctoidScriptEditorForm(functoidNode.FunctoidName, functoidNode.CustomScript)) + { + if (editorDlg.ShowDialog(this) == DialogResult.OK) + { + // Update the capsule's stored script state with the developer's raw modifications + functoidNode.CustomScript = editorDlg.CompiledScriptText; + } + } + }; + functoidMenu.Items.Add(editScriptItem); + functoidMenu.Items.Add(new ToolStripSeparator()); // Visual partition bar splitter line + + // Existing Delete Functoid Item + var deleteItem = new ToolStripMenuItem("Delete Functoid"); deleteItem.Click += (sender, e) => { - // Drop any connection link tracks tied to this node block _mapper.Connections.RemoveAll(conn => conn.Target == functoidNode || conn.Source == functoidNode); - pnlFunctoids.Controls.Remove(functoidNode); functoidNode.Dispose(); _mapper.Invalidate(); }; - functoidMenu.Items.Add(deleteItem); - // Assign the deletion menu to the node layout wrapper and its children + // Assign context configurations across all nested component areas functoidNode.ContextMenuStrip = functoidMenu; functoidNode.LblIcon.ContextMenuStrip = functoidMenu; functoidNode.LblText.ContextMenuStrip = functoidMenu; @@ -962,6 +1149,124 @@ private Control CreateFunctoid(string text, Point location) functoidNode.BringToFront(); return functoidNode; } + public string CompileMapToXslt() + { + StringBuilder xslt = new StringBuilder(); + + // 1. Generate the standard BizTalk-compliant XSLT stylesheet headers + xslt.AppendLine(""); + xslt.AppendLine(""); + xslt.AppendLine(" "); + xslt.AppendLine(" "); + xslt.AppendLine(); + + // 2. Main Entry Template Match (Targets the inbound root document segment) + xslt.AppendLine(" "); + xslt.AppendLine(" "); + + // 3. Process every active connection line on the Skia canvas + foreach (var conn in _mapper.Connections) + { + // Resolve the underlying immutable source data node structural footprint + if (conn.Source is XmlNode sourceXmlNode) + { + // Build the absolute absolute XPath locator string (e.g., Interchange/FunctionalGroup/Transaction/Element) + string sourceXPath = BuildAbsoluteXPath(sourceXmlNode); + + // CASE A: The line connects to an operational BizTalk Scripting Capsule + if (conn.Target is BizTalkFunctoidNode functoid) + { + string targetNodeName = functoid.FunctoidName.Replace(" ", "_"); + string snippet = ""; + + // If the developer has customized the script via the script dialog window, use it + if (!string.IsNullOrEmpty(functoid.CustomScript) && !functoid.CustomScript.Contains("SOURCE_XPATH_PLACEHOLDER")) + { + snippet = functoid.CustomScript; + } + else + { + // Fall back to compiling our standard default rule sets from our compiler factory + snippet = FunctoidXsltCompiler.GetXsltSnippet(functoid.FunctoidName, sourceXPath, targetNodeName); + } + + // Swap out the placeholder trace with the real computed absolute XPath string + snippet = snippet.Replace("SOURCE_XPATH_PLACEHOLDER", sourceXPath); + + xslt.AppendLine($" {snippet}"); + } + // CASE B: Direct continuous mapping connection line link case (No intermediate functoid) + else if (conn.Target is SchemaNodeItem targetSchemaItem) + { + string targetNodeName = targetSchemaItem.XmlSourceNode.Name; + string snippet = FunctoidXsltCompiler.GetXsltSnippet("DirectLink", sourceXPath, targetNodeName); + + xslt.AppendLine($" {snippet}"); + } + } + } + + xslt.AppendLine(" "); + xslt.AppendLine(""); + + return xslt.ToString(); + } + // Helper tool to find whatever control or node feeds into a target capsule's input port + private string TraceInputExpression(object targetControl) + { + foreach (var conn in _mapper.Connections) + { + if (conn.Target == targetControl) + { + if (conn.Source is XmlNode sourceXmlNode) + { + return BuildAbsoluteXPath(sourceXmlNode); + } + else if (conn.Source is BizTalkFunctoidNode parentFunctoid) + { + // RECURSION: Evaluate what is driving the parent functoid first! + string upstreamExpression = TraceInputExpression(parentFunctoid); + string currentTargetName = parentFunctoid.FunctoidName.Replace(" ", "_"); + + // Nest the parent script directly around the upstream value + string rawSnippet = FunctoidXsltCompiler.GetXsltSnippet(parentFunctoid.FunctoidName, "UPSTREAM_PLACEHOLDER", currentTargetName); + + // Strip outer XML tag structures for inline variable cascading evaluation injection + string pureExpression = ExtractInlineXsltExpression(rawSnippet); + return pureExpression.Replace("UPSTREAM_PLACEHOLDER", upstreamExpression); + } + } + } + return "''"; // Fallback empty string if input path breaks + } + + private string ExtractInlineXsltExpression(string xmlSnippet) + { + // Helper to pull 'translate(...)' or 'normalize-space(...)' out of raw tag sets like + int start = xmlSnippet.IndexOf("select=\""); + if (start == -1) return xmlSnippet; + start += 8; + int end = xmlSnippet.IndexOf("\"", start); + return xmlSnippet.Substring(start, end - start); + } + + // HELPER METHOD: Climbs the XML DOM tree recursively to output perfect structural absolute XPaths + private string BuildAbsoluteXPath(XmlNode node) + { + if (node == null || node.NodeType == XmlNodeType.Document) + return ""; + + // If it's an attribute node, prepend the '@' selector switch character + if (node.NodeType == XmlNodeType.Attribute) + return BuildAbsoluteXPath(((XmlAttribute)node).OwnerElement) + "/@" + node.Name; + + string parentPath = BuildAbsoluteXPath(node.ParentNode); + + if (string.IsNullOrEmpty(parentPath)) + return node.Name; + + return parentPath + "/" + node.Name; + } } } diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index a0bdb7d3..4e6771c9 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -113,6 +113,10 @@ Component + + Form + + Component From c52388fa86450e248d977896b930f649ea444b84 Mon Sep 17 00:00:00 2001 From: apeiris Date: Sun, 17 May 2026 14:42:23 -0400 Subject: [PATCH 09/22] wip --- X12UtilsFRM/SkiaMapper.cs | 74 ++++++++++----- X12UtilsFRM/X12UtilsFRM.cs | 187 +++++++++++++++++++++++++++++-------- 2 files changed, 195 insertions(+), 66 deletions(-) diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index 7bfa04b2..e6209af3 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -58,7 +58,7 @@ protected override void WndProc(ref Message m) } // NEW HELPER METHOD: Seamlessly finds the correct UI component to map paths to - + private void CheckForLineRightClick(Point clickPt) { @@ -66,10 +66,11 @@ private void CheckForLineRightClick(Point clickPt) foreach (var conn in Connections) { - // CRITICAL FIX: Resolve visual control reference dynamically var visualSource = ResolveSourceControl(conn.Source); + var visualTarget = ResolveSourceControl(conn.Target); // Fixed to use dynamic lookups! + var start = GetControlPoint(visualSource, isSource: true); - var end = GetControlPoint(conn.Target as Control, isSource: false); + var end = GetControlPoint(visualTarget, isSource: false); if (start != SKPoint.Empty && end != SKPoint.Empty) { @@ -118,6 +119,7 @@ private bool IsPointNearBezier(SKPoint clickPt, SKPoint start, SKPoint end, floa return false; } + protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { var canvas = e.Surface.Canvas; @@ -126,62 +128,84 @@ protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) using (var paint = new SKPaint()) using (var textPaint = new SKPaint()) { - // 1. Line Curve Paint Properties + // 1. Curve Rendering Parameters paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 2; paint.Color = SKColors.DodgerBlue; paint.IsAntialias = true; - // 2. Text Label Paint Properties - textPaint.Color = Color.FromArgb(70, 80, 110).ToSKColor(); // Slate-gray - textPaint.TextSize = 10.5f; // Tighter font size for clean side-by-side display + // 2. Line Text Label Parameters + textPaint.Color = Color.FromArgb(70, 80, 110).ToSKColor(); // Clean Slate-Gray color palette + textPaint.TextSize = 10.5f; textPaint.IsAntialias = true; textPaint.Typeface = SKTypeface.FromFamilyName("Segoe UI", SKFontStyle.Bold); textPaint.TextAlign = SKTextAlign.Center; foreach (var conn in Connections) { + // Trace dynamic visual container references on the layout panel var visualSource = ResolveSourceControl(conn.Source); - var visualTarget = conn.Target as Control; // Fallback resolve for standard controls + var visualTarget = ResolveSourceControl(conn.Target); var start = GetControlPoint(visualSource, isSource: true); var end = GetControlPoint(visualTarget, isSource: false); if (start != SKPoint.Empty && end != SKPoint.Empty) { - // --- RESOLVE SOURCE LABEL STRING --- + // --- DEFAULT NAME EXTRACTION PIPELINE --- string sourceLabelText = ""; - if (conn.Source is System.Xml.XmlNode srcXmlNode) - { + if (visualSource is SchemaNodeItem srcSni) + sourceLabelText = srcSni.XmlSourceNode.Name; + else if (visualSource is BizTalkFunctoidNode srcFunctoid) + sourceLabelText = srcFunctoid.FunctoidName; + else if (conn.Source is System.Xml.XmlNode srcXmlNode) sourceLabelText = srcXmlNode.Name; - } - else if (visualSource is SchemaNodeItem srcSni) + + string targetLabelText = ""; + if (visualTarget is SchemaNodeItem tgtSni) + targetLabelText = tgtSni.XmlSourceNode.Name; + else if (visualTarget is BizTalkFunctoidNode tgtFunctoid) + targetLabelText = tgtFunctoid.FunctoidName; + else if (conn.Target is System.Xml.XmlNode tgtXmlNode) + targetLabelText = tgtXmlNode.Name; + + // --- DETERMINISTIC SIDE CLASSIFIERS --- + bool isSourceSchema = (visualSource is SchemaNodeItem) || (conn.Source is System.Xml.XmlNode); + bool isTargetSchema = (visualTarget is SchemaNodeItem) || (conn.Target is System.Xml.XmlNode); + bool isSourceFunctoid = visualSource is BizTalkFunctoidNode; + bool isTargetFunctoid = visualTarget is BizTalkFunctoidNode; + + // --- LABEL RULE ROUTER --- + if (isSourceSchema && isTargetFunctoid) { - sourceLabelText = srcSni.XmlSourceNode.Name; + // Case A: Left Schema Node -> Functoid Capsule + // Keep the source node label, strip the target label so the functoid name isn't duplicated + targetLabelText = string.Empty; } - else if (visualSource is BizTalkFunctoidNode srcFunctoid) + else if (isSourceFunctoid && isTargetSchema) { - sourceLabelText = srcFunctoid.FunctoidName; + // Case B: Functoid Capsule -> Right Schema Node + // Strip the source label (functoid name) to keep the right side node clean + sourceLabelText = string.Empty; } - - // --- RESOLVE TARGET LABEL STRING --- - string targetLabelText = "dddddd"; - if (conn.Target is SchemaNodeItem tgtSni) + else if (isSourceSchema && isTargetSchema) { - targetLabelText = tgtSni.XmlSourceNode.Name; + // Case C: Direct Left Schema Node -> Right Schema Node link + // Clear the source label and display only one single label badge on the target side + sourceLabelText = string.Empty; } - else if (visualTarget is BizTalkFunctoidNode tgtFunctoid) + else if (!string.IsNullOrEmpty(sourceLabelText) && sourceLabelText == targetLabelText) { - targetLabelText = tgtFunctoid.FunctoidName; + // Fallback D: Universal text text match safety catcher + sourceLabelText = string.Empty; } - // Draw the line with both structural labels attached! + // Render out the connection line curve with text badges pinned safely onto it DrawBezierLine(canvas, paint, textPaint, start, end, sourceLabelText, targetLabelText); } } } } - private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, SKPoint start, SKPoint end, string sourceLabel, string targetLabel) { float controlOffset = Math.Abs(start.X - end.X) / 2; diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index ba677352..7006cbf2 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -1023,74 +1023,179 @@ private Control ResolveActualTargetNode(Control control, Point clientPt) return control; } - private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) + + private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) { - TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); - if (sourceNode == null) return; + // Check if the data being dragged is a TreeNode payload or a Functoid capsule + if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) + { + e.Effect = DragDropEffects.Copy | DragDropEffects.Link; + } + else + { + e.Effect = DragDropEffects.None; + } + } + private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) + { + // 1. Calculate drop coordinates relative to the central panel space Point clientPoint = pnlFunctoids.PointToClient(new Point(e.X, e.Y)); - Control targetControl = pnlFunctoids.GetChildAtPoint(clientPoint); - // 1. Guard against dropping directly onto structural UI boundaries - if (targetControl is SchemaNodeItem || - targetControl == pnlSchemaScrollContainer || + // Resolve the exact parent container control under the mouse pointer + Control rawTarget = pnlFunctoids.GetChildAtPoint(clientPoint); + Control targetControl = ResolveActualTargetNode(rawTarget, clientPoint); + + // 2. Clear out any background container boundary obstructions + if (targetControl == pnlSchemaScrollContainer || + targetControl == pnlTargetSchemaScrollContainer || targetControl == pnlToolboxWrapper || targetControl == pnlToolboxCategoriesContainer || targetControl == btnToolboxToggle || (pnlSchemaScrollContainer != null && pnlSchemaScrollContainer.Bounds.Contains(clientPoint)) || + (pnlTargetSchemaScrollContainer != null && pnlTargetSchemaScrollContainer.Bounds.Contains(clientPoint)) || (pnlToolboxWrapper != null && pnlToolboxWrapper.Bounds.Contains(clientPoint))) { return; } - // CASE A: Toolbox operational template drop (Spawns a new independent BizTalk capsule) - if (sourceNode.Tag as string == "FUNCTOID_TEMPLATE") + object connectionSource = null; + + // --- PACKAGING UNIFIED SOURCE PAYLOADS --- + if (e.Data.GetDataPresent(typeof(TreeNode))) { - Control customFunctoidBlock = CreateFunctoid(sourceNode.Text, clientPoint); - pnlFunctoids.Controls.Add(customFunctoidBlock); - customFunctoidBlock.BringToFront(); - _mapper.Invalidate(); - return; + TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); + if (sourceNode != null) + { + // Case A: Dropping a brand-new functoid from the toolbox panel list + if (sourceNode.Tag as string == "FUNCTOID_TEMPLATE") + { + Control customFunctoidBlock = CreateFunctoid(sourceNode.Text, clientPoint); + pnlFunctoids.Controls.Add(customFunctoidBlock); + customFunctoidBlock.BringToFront(); + _mapper.Invalidate(); + return; + } + + // Case B: Left or Right Tree Panel Data Element + if (sourceNode.Tag is System.Xml.XmlNode realXmlNode) + { + connectionSource = realXmlNode; + } + } + } + else if (e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) + { + // Case C: Center Panel Functoid capsule being dragged + connectionSource = e.Data.GetData(typeof(BizTalkFunctoidNode)) as BizTalkFunctoidNode; } - // CASE B: Source Document Node Drag-Link - if (sourceNode.Tag is System.Xml.XmlNode realXmlNode) + // --- PIPELINE VALIDATION & CONNECTION STORAGE --- + if (connectionSource != null) { - // If dropped onto an empty canvas space or the Skia canvas background, spawn a target target block automatically - if (targetControl == null || targetControl is SkiaMapper) + // Intercept and check if the dragged node belongs to the right panel (Target Schema Registry) + bool isRightPanelNode = false; + if (e.Data.GetDataPresent(typeof(TreeNode))) { - targetControl = CreateFunctoid(sourceNode.Text, clientPoint); - pnlFunctoids.Controls.Add(targetControl); - targetControl.BringToFront(); + TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); + if (sourceNode != null && sourceNode.Tag is XmlNode realXmlNode) + { + isRightPanelNode = flatTargetSchemaRegistry.Any(sni => sni.XmlSourceNode == realXmlNode); + } } - // REVISED FOR PERSISTENCE: Anchor directly to the immutable underlying XmlNode! - // This ensures lines do not break when pnlSchemaScrollContainer updates its children. - _mapper.Connections.Add(new MappingConnection + if (isRightPanelNode) { - Source = realXmlNode, - Target = targetControl - }); + // FIX: If dragged from the right panel onto a functoid, invert the roles. + // The functoid becomes the data SOURCE (right side connection point), + // and the right panel node becomes the data TARGET. + if (targetControl is BizTalkFunctoidNode functoid) + { + bool connectionExists = _mapper.Connections.Exists(c => c.Source == functoid && c.Target == connectionSource); + if (!connectionExists) + { + _mapper.Connections.Add(new MappingConnection + { + Source = functoid, + Target = connectionSource + }); + } + _mapper.Invalidate(); + } + else if (targetControl == null || targetControl is SkiaMapper) + { + // Fallback: If a right-panel node is dropped into empty space, spawn an inline functoid + // that feeds its output forward cleanly into the right panel node target. + TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); + Control autoFunctoid = CreateFunctoid(sourceNode.Text, clientPoint); + pnlFunctoids.Controls.Add(autoFunctoid); + autoFunctoid.BringToFront(); + + _mapper.Connections.Add(new MappingConnection + { + Source = autoFunctoid, + Target = connectionSource + }); + _mapper.Invalidate(); + } + return; + } - _mapper.Invalidate(); - } - } + // Standard Flow: Left panel nodes or center functoids dragging to targets + if (targetControl != null && targetControl != connectionSource) + { + bool isValidTarget = false; - private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) - { - // Check if the data being dragged is a TreeNode payload or a Functoid capsule - if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) - { - e.Effect = DragDropEffects.Copy | DragDropEffects.Link; - } - else - { - e.Effect = DragDropEffects.None; + // Target option A: Landing on a center functional capsule + if (targetControl is BizTalkFunctoidNode) + { + isValidTarget = true; + } + // Target option B: Landing directly on a right-side destination schema node! + else if (targetControl is SchemaNodeItem targetSni && flatTargetSchemaRegistry.Contains(targetSni)) + { + isValidTarget = true; + } + + if (isValidTarget) + { + // Verify if an identical duplicate connection already exists on the canvas + bool connectionExists = _mapper.Connections.Exists(c => c.Source == connectionSource && c.Target == targetControl); + + if (!connectionExists) + { + _mapper.Connections.Add(new MappingConnection + { + Source = connectionSource, + Target = targetControl + }); + } + + _mapper.Invalidate(); // Repaint the Skia drawing layer immediately + } + else + { + // Fallback: If it's a left node dropped into completely empty canvas air, spawn an inline capsule + if (e.Data.GetDataPresent(typeof(TreeNode)) && (targetControl == null || targetControl is SkiaMapper)) + { + TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); + Control autoFunctoid = CreateFunctoid(sourceNode.Text, clientPoint); + pnlFunctoids.Controls.Add(autoFunctoid); + autoFunctoid.BringToFront(); + + _mapper.Connections.Add(new MappingConnection + { + Source = connectionSource, + Target = autoFunctoid + }); + _mapper.Invalidate(); + } + } + } } } - #endregion pnlFunctoids private void TargetSchemaPanel_DragEnterOrOver(object sender, DragEventArgs e) { From 058daf8e3a0e4d4a70c5a4ee794d45b34668bcb6 Mon Sep 17 00:00:00 2001 From: apeiris Date: Sun, 17 May 2026 14:50:06 -0400 Subject: [PATCH 10/22] wip --- X12UtilsFRM/SkiaMapper.cs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index e6209af3..03cfee46 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -176,27 +176,34 @@ protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) bool isTargetFunctoid = visualTarget is BizTalkFunctoidNode; // --- LABEL RULE ROUTER --- - if (isSourceSchema && isTargetFunctoid) + if (isSourceFunctoid && isTargetFunctoid) { - // Case A: Left Schema Node -> Functoid Capsule - // Keep the source node label, strip the target label so the functoid name isn't duplicated + // Case A: Functoid -> Functoid cascade chain + // Completely hide both labels to keep the workspace clean + sourceLabelText = string.Empty; + targetLabelText = string.Empty; + } + else if (isSourceSchema && isTargetFunctoid) + { + // Case B: Left Schema Node -> Functoid Capsule + // Keep the source node name, hide the target capsule label targetLabelText = string.Empty; } else if (isSourceFunctoid && isTargetSchema) { - // Case B: Functoid Capsule -> Right Schema Node - // Strip the source label (functoid name) to keep the right side node clean + // Case C: Functoid Capsule -> Right Schema Node + // Hide the source capsule label, show the destination schema node name sourceLabelText = string.Empty; } else if (isSourceSchema && isTargetSchema) { - // Case C: Direct Left Schema Node -> Right Schema Node link - // Clear the source label and display only one single label badge on the target side + // Case D: Direct Left Schema Node -> Right Schema Node link + // Clear the source label and display a single badge on the target side sourceLabelText = string.Empty; } else if (!string.IsNullOrEmpty(sourceLabelText) && sourceLabelText == targetLabelText) { - // Fallback D: Universal text text match safety catcher + // Fallback E: Universal exact text match safety catcher sourceLabelText = string.Empty; } From d49aaf63c9fa57bd32684f58b991c00b883c7d1e Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 18 May 2026 08:52:27 -0400 Subject: [PATCH 11/22] wip --- X12UtilsFRM/SchemaNodeItem.cs | 13 +- X12UtilsFRM/SkiaMapper.cs | 416 +++++++--- X12UtilsFRM/X12UtilsFRM.Designer.cs | 55 +- X12UtilsFRM/X12UtilsFRM.cs | 1114 ++++++--------------------- X12UtilsFRM/X12UtilsFRM.csproj | 2 +- X12UtilsFRM/X12UtilsFRM.resx | 3 + 6 files changed, 567 insertions(+), 1036 deletions(-) diff --git a/X12UtilsFRM/SchemaNodeItem.cs b/X12UtilsFRM/SchemaNodeItem.cs index b4b43c6f..7d64b55f 100644 --- a/X12UtilsFRM/SchemaNodeItem.cs +++ b/X12UtilsFRM/SchemaNodeItem.cs @@ -6,12 +6,13 @@ namespace X12UtilsFRM { - public class SchemaNodeItem : Panel + public class SchemaNodeItem : UserControl { public XmlNode XmlSourceNode { get; private set; } public List ChildNodes { get; set; } = new List(); - public bool IsExpanded { get; private set; } = true; + public bool IsExpanded { get; set; } public int IndentLevel { get; set; } = 0; + public int Depth { get; private set; } private Label lblToggle; private Label lblText; @@ -19,10 +20,10 @@ public class SchemaNodeItem : Panel private Point _mouseDownLocation; private bool _isPotentialDrag = false; - public SchemaNodeItem(XmlNode xmlNode, int indent, Action onStateChanged) + public SchemaNodeItem(XmlNode xmlNode, int depth, Action onStateChanged) { this.XmlSourceNode = xmlNode; - this.IndentLevel = indent; + this.Depth = depth; this._onStateChanged = onStateChanged; this.Height = 28; @@ -37,7 +38,7 @@ public SchemaNodeItem(XmlNode xmlNode, int indent, Action onStat Text = "▼", Font = new Font("Segoe UI", 8, FontStyle.Bold), Size = new Size(16, 16), - Location = new Point(5 + (indent * 15), 6), + Location = new Point(5 + (Depth * 15), 6), Cursor = Cursors.Hand, TextAlign = ContentAlignment.MiddleCenter }; @@ -51,7 +52,7 @@ public SchemaNodeItem(XmlNode xmlNode, int indent, Action onStat Text = xmlNode.Name, Font = new Font("Segoe UI", 9, FontStyle.Regular), AutoSize = true, - Location = new Point((lblToggle != null ? 22 : 10) + (indent * 15), 5), + Location = new Point((lblToggle != null ? 22 : 10) + (Depth * 15), 5), Cursor = Cursors.Hand }; diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index 03cfee46..91b6fa70 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -1,15 +1,45 @@ -using SkiaSharp; +using NLog; +using SkiaSharp; using SkiaSharp.Views.Desktop; using System; using System.Collections.Generic; using System.Drawing; +using System.Linq; using System.Windows.Forms; +using System.Xml; namespace X12UtilsFRM { public class SkiaMapper : SKControl { + + private SKPoint _canvasPanOffset = new SKPoint(0, 0); + private Point _lastMousePosition; + private bool _isPanningCanvas = false; + // Virtual Drag and Drop Trackers + private SchemaNodeItem _draggedVirtualNode = null; + private Point _dragStartPoint; + private const int DragThreshold = 5; // Pixels to move before realizing it's a "drag" and not a "click" + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + // Canvas Data Models public List Connections { get; set; } = new List(); + public List FlatSchemaRegistry { get; set; } = new List(); + public List FlatTargetSchemaRegistry { get; set; } = new List(); + + // Virtual Column Trackers + private VirtualRegion _leftSchemaRegion = new VirtualRegion { Name = "LeftSchema" }; + private VirtualRegion _centerCanvasRegion = new VirtualRegion { Name = "CenterCanvas" }; + private VirtualRegion _rightSchemaRegion = new VirtualRegion { Name = "RightSchema" }; + + // Splitter Coordinates & State + private float _splitterLeftX; + private float _splitterRightX; + private const float SplitterHitWidth = 6f; + + private bool _isDraggingLeftSplitter = false; + private bool _isDraggingRightSplitter = false; + private ContextMenuStrip _lineContextMenu; private MappingConnection _selectedConnectionForDelete; @@ -17,6 +47,12 @@ public SkiaMapper() { this.Dock = DockStyle.Fill; InitializeLineContextMenu(); + + // Native input sub-bindings + this.MouseDown += Mapper_MouseDown; + this.MouseMove += Mapper_MouseMove; + this.MouseUp += Mapper_MouseUp; + this.MouseWheel += Mapper_MouseWheel; } private void InitializeLineContextMenu() @@ -35,10 +71,34 @@ private void InitializeLineContextMenu() _lineContextMenu.Items.Add(deleteItem); } + public void RecalculateVirtualLayout() + { + float height = this.Height; + float width = this.Width; + + if (height <= 0 || width <= 0) return; + + // If layout hasn't been initialized by the form yet, set up default even distribution + if (_splitterLeftX == 0 && _splitterRightX == 0) + { + _splitterLeftX = width / 3f; + _splitterRightX = _splitterLeftX * 2f; + } + + _leftSchemaRegion.Bounds = new SKRect(0, 0, _splitterLeftX, height); + _centerCanvasRegion.Bounds = new SKRect(_splitterLeftX, 0, _splitterRightX, height); + _rightSchemaRegion.Bounds = new SKRect(_splitterRightX, 0, width, height); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + RecalculateVirtualLayout(); + this.Invalidate(); + } + protected override void WndProc(ref Message m) { - const int WM_NCHITTEST = 0x0084; - const int HTTRANSPARENT = -1; const int WM_RBUTTONDOWN = 0x0204; if (m.Msg == WM_RBUTTONDOWN) @@ -47,27 +107,29 @@ protected override void WndProc(ref Message m) CheckForLineRightClick(clientPt); } - if (m.Msg == WM_NCHITTEST) - { - m.Result = (IntPtr)HTTRANSPARENT; - } - else - { - base.WndProc(ref m); - } + base.WndProc(ref m); } - // NEW HELPER METHOD: Seamlessly finds the correct UI component to map paths to - - private void CheckForLineRightClick(Point clickPt) { SKPoint skClick = new SKPoint(clickPt.X, clickPt.Y); foreach (var conn in Connections) { - var visualSource = ResolveSourceControl(conn.Source); - var visualTarget = ResolveSourceControl(conn.Target); // Fixed to use dynamic lookups! + object visualSource = conn.Source; + object visualTarget = conn.Target; + + if (conn.Source is XmlNode sourceXml) + { + var matchingSource = FlatSchemaRegistry.FirstOrDefault(sni => sni.XmlSourceNode == sourceXml); + if (matchingSource != null) visualSource = matchingSource; + } + + if (conn.Target is XmlNode targetXml) + { + var matchingTarget = FlatTargetSchemaRegistry.FirstOrDefault(sni => sni.XmlSourceNode == targetXml); + if (matchingTarget != null) visualTarget = matchingTarget; + } var start = GetControlPoint(visualSource, isSource: true); var end = GetControlPoint(visualTarget, isSource: false); @@ -110,32 +172,202 @@ private bool IsPointNearBezier(SKPoint clickPt, SKPoint start, SKPoint end, floa float dy = clickPt.Y - y; float distance = (float)Math.Sqrt(dx * dx + dy * dy); - if (distance <= tolerance) + if (distance <= tolerance) return true; + } + return false; + } + + public void RenderEngine(SKCanvas canvas, int width, int height) + { + canvas.Clear(Color.FromArgb(245, 247, 250).ToSKColor()); + + // --- DRAW BACKGROUND REGIONS --- + using (var paint = new SKPaint()) + { + paint.Color = SKColors.White; + canvas.DrawRect(_leftSchemaRegion.Bounds, paint); + canvas.DrawRect(_rightSchemaRegion.Bounds, paint); + } + + // --- DRAW TREE NODES (VIRTUAL CHANNELS) --- + RenderVirtualTreeNodes(canvas, FlatSchemaRegistry, _leftSchemaRegion); + RenderVirtualTreeNodes(canvas, FlatTargetSchemaRegistry, _rightSchemaRegion); + + // --- DRAW MAPPER CONNECTIONS --- + OnPaintSurfaceEngine(canvas); + + // --- DRAW SPLITTER SEPARATORS --- + using (var paint = new SKPaint { Color = Color.FromArgb(210, 214, 219).ToSKColor(), StrokeWidth = 2 }) + { + canvas.DrawLine(_splitterLeftX, 0, _splitterLeftX, height, paint); + canvas.DrawLine(_splitterRightX, 0, _splitterRightX, height, paint); + } + } + + private void RenderVirtualTreeNodes(SKCanvas canvas, List nodes, VirtualRegion region) + { + canvas.Save(); + canvas.ClipRect(region.Bounds); + + float currentY = 20 + region.ScrollOffset; + float indentStep = 20f; + + using (var textPaint = new SKPaint { Color = Color.FromArgb(40, 44, 52).ToSKColor(), TextSize = 13f, IsAntialias = true }) + { + foreach (var node in nodes) { - return true; + if (!IsNodeChainVisible(node, nodes)) continue; + + float xPosition = region.Bounds.Left + 15f + (node.Depth * indentStep); + string prefix = node.ChildNodes.Count > 0 ? (node.IsExpanded ? "▼ " : "► ") : " "; + + canvas.DrawText($"{prefix}{node.XmlSourceNode.Name}", xPosition, currentY, textPaint); + + node.Tag = new SKRect(region.Bounds.Left, currentY - 15, region.Bounds.Right, currentY + 5); + currentY += 28f; } } + region.MaxScrollHeight = Math.Max(0, currentY - region.ScrollOffset); + canvas.Restore(); + } - return false; + private bool IsNodeChainVisible(SchemaNodeItem item, List registry) + { + var current = item; + while (current != null) + { + var parent = registry.Find(p => p.ChildNodes.Contains(current)); + if (parent != null && !parent.IsExpanded) return false; + current = parent; + } + return true; + } + + private void Mapper_MouseDown(object sender, MouseEventArgs e) + { + if (Math.Abs(e.X - _splitterLeftX) <= SplitterHitWidth / 2) + { + _isDraggingLeftSplitter = true; + } + else if (Math.Abs(e.X - _splitterRightX) <= SplitterHitWidth / 2) + { + _isDraggingRightSplitter = true; + } + else + { + // Check if hitting a schema item node row + var activeRegistry = _leftSchemaRegion.Bounds.Contains(e.X, e.Y) ? FlatSchemaRegistry : FlatTargetSchemaRegistry; + SchemaNodeItem clickedNode = null; + + foreach (var item in activeRegistry) + { + if (item.Tag is SKRect rowBounds && rowBounds.Contains(e.X, e.Y)) + { + clickedNode = item; + break; + } + } + + if (clickedNode != null) + { + _draggedVirtualNode = clickedNode; + _dragStartPoint = e.Location; + } + } } + private void Mapper_MouseMove(object sender, MouseEventArgs e) + { + // 1. Handle Virtual Node Drag Initiation + if (_draggedVirtualNode != null && e.Button == MouseButtons.Left) + { + int deltaX = Math.Abs(e.X - _dragStartPoint.X); + int deltaY = Math.Abs(e.Y - _dragStartPoint.Y); + + if (deltaX > DragThreshold || deltaY > DragThreshold) + { + TreeNode dragPayload = new TreeNode(_draggedVirtualNode.XmlSourceNode.Name) + { + Tag = _draggedVirtualNode.XmlSourceNode + }; + + _draggedVirtualNode = null; // Clear state before block loop + this.DoDragDrop(dragPayload, DragDropEffects.Copy | DragDropEffects.Link); + return; + } + } + + // 2. Handle Splitter Dragging Changes + if (_isDraggingLeftSplitter) + { + _splitterLeftX = Clamp(e.X, 100, _splitterRightX - 100); + RecalculateVirtualLayout(); + this.Invalidate(); + } + else if (_isDraggingRightSplitter) + { + _splitterRightX = Clamp(e.X, _splitterLeftX + 100, this.Width - 100); + RecalculateVirtualLayout(); + this.Invalidate(); + } + + // 3. Splitter Cursor Overrides + if (Math.Abs(e.X - _splitterLeftX) <= SplitterHitWidth / 2 || + Math.Abs(e.X - _splitterRightX) <= SplitterHitWidth / 2) + { + this.Cursor = Cursors.VSplit; + } + else + { + this.Cursor = Cursors.Default; + } + } + + private void Mapper_MouseUp(object sender, MouseEventArgs e) + { + _isDraggingLeftSplitter = false; + _isDraggingRightSplitter = false; + + // Click fallback: Toggle expansion + if (_draggedVirtualNode != null) + { + _draggedVirtualNode.IsExpanded = !_draggedVirtualNode.IsExpanded; + Logger.Info($"Virtual Node Click Expanded Toggle: {_draggedVirtualNode.XmlSourceNode.Name}"); + _draggedVirtualNode = null; + this.Invalidate(); + } + } + + private void Mapper_MouseWheel(object sender, MouseEventArgs e) + { + if (_leftSchemaRegion.Bounds.Contains(e.X, e.Y)) + { + _leftSchemaRegion.ScrollOffset = Clamp(_leftSchemaRegion.ScrollOffset + (e.Delta > 0 ? 30 : -30), -_leftSchemaRegion.MaxScrollHeight, 0); + this.Invalidate(); + } + else if (_rightSchemaRegion.Bounds.Contains(e.X, e.Y)) + { + _rightSchemaRegion.ScrollOffset = Clamp(_rightSchemaRegion.ScrollOffset + (e.Delta > 0 ? 30 : -30), -_rightSchemaRegion.MaxScrollHeight, 0); + this.Invalidate(); + } + } protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { - var canvas = e.Surface.Canvas; - canvas.Clear(SKColors.Transparent); + RenderEngine(e.Surface.Canvas, e.Info.Width, e.Info.Height); + } + private void OnPaintSurfaceEngine(SKCanvas canvas) + { using (var paint = new SKPaint()) using (var textPaint = new SKPaint()) { - // 1. Curve Rendering Parameters paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 2; paint.Color = SKColors.DodgerBlue; paint.IsAntialias = true; - // 2. Line Text Label Parameters - textPaint.Color = Color.FromArgb(70, 80, 110).ToSKColor(); // Clean Slate-Gray color palette + textPaint.Color = Color.FromArgb(70, 80, 110).ToSKColor(); textPaint.TextSize = 10.5f; textPaint.IsAntialias = true; textPaint.Typeface = SKTypeface.FromFamilyName("Segoe UI", SKFontStyle.Bold); @@ -143,22 +375,33 @@ protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) foreach (var conn in Connections) { - // Trace dynamic visual container references on the layout panel - var visualSource = ResolveSourceControl(conn.Source); - var visualTarget = ResolveSourceControl(conn.Target); + // Look up internal schema text records by matching their XmlNodes directly + object visualSource = conn.Source; + object visualTarget = conn.Target; + + if (conn.Source is XmlNode sourceXml) + { + var matchingSource = FlatSchemaRegistry.FirstOrDefault(sni => sni.XmlSourceNode == sourceXml); + if (matchingSource != null) visualSource = matchingSource; + } + + if (conn.Target is XmlNode targetXml) + { + var matchingTarget = FlatTargetSchemaRegistry.FirstOrDefault(sni => sni.XmlSourceNode == targetXml); + if (matchingTarget != null) visualTarget = matchingTarget; + } var start = GetControlPoint(visualSource, isSource: true); var end = GetControlPoint(visualTarget, isSource: false); if (start != SKPoint.Empty && end != SKPoint.Empty) { - // --- DEFAULT NAME EXTRACTION PIPELINE --- string sourceLabelText = ""; if (visualSource is SchemaNodeItem srcSni) sourceLabelText = srcSni.XmlSourceNode.Name; else if (visualSource is BizTalkFunctoidNode srcFunctoid) sourceLabelText = srcFunctoid.FunctoidName; - else if (conn.Source is System.Xml.XmlNode srcXmlNode) + else if (conn.Source is XmlNode srcXmlNode) sourceLabelText = srcXmlNode.Name; string targetLabelText = ""; @@ -166,53 +409,42 @@ protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) targetLabelText = tgtSni.XmlSourceNode.Name; else if (visualTarget is BizTalkFunctoidNode tgtFunctoid) targetLabelText = tgtFunctoid.FunctoidName; - else if (conn.Target is System.Xml.XmlNode tgtXmlNode) + else if (conn.Target is XmlNode tgtXmlNode) targetLabelText = tgtXmlNode.Name; - // --- DETERMINISTIC SIDE CLASSIFIERS --- - bool isSourceSchema = (visualSource is SchemaNodeItem) || (conn.Source is System.Xml.XmlNode); - bool isTargetSchema = (visualTarget is SchemaNodeItem) || (conn.Target is System.Xml.XmlNode); + bool isSourceSchema = (visualSource is SchemaNodeItem) || (conn.Source is XmlNode); + bool isTargetSchema = (visualTarget is SchemaNodeItem) || (conn.Target is XmlNode); bool isSourceFunctoid = visualSource is BizTalkFunctoidNode; bool isTargetFunctoid = visualTarget is BizTalkFunctoidNode; - // --- LABEL RULE ROUTER --- if (isSourceFunctoid && isTargetFunctoid) { - // Case A: Functoid -> Functoid cascade chain - // Completely hide both labels to keep the workspace clean sourceLabelText = string.Empty; targetLabelText = string.Empty; } else if (isSourceSchema && isTargetFunctoid) { - // Case B: Left Schema Node -> Functoid Capsule - // Keep the source node name, hide the target capsule label targetLabelText = string.Empty; } else if (isSourceFunctoid && isTargetSchema) { - // Case C: Functoid Capsule -> Right Schema Node - // Hide the source capsule label, show the destination schema node name sourceLabelText = string.Empty; } else if (isSourceSchema && isTargetSchema) { - // Case D: Direct Left Schema Node -> Right Schema Node link - // Clear the source label and display a single badge on the target side sourceLabelText = string.Empty; } else if (!string.IsNullOrEmpty(sourceLabelText) && sourceLabelText == targetLabelText) { - // Fallback E: Universal exact text match safety catcher sourceLabelText = string.Empty; } - // Render out the connection line curve with text badges pinned safely onto it DrawBezierLine(canvas, paint, textPaint, start, end, sourceLabelText, targetLabelText); } } } } + private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, SKPoint start, SKPoint end, string sourceLabel, string targetLabel) { float controlOffset = Math.Abs(start.X - end.X) / 2; @@ -222,7 +454,6 @@ private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, S SKPoint p2 = new SKPoint(end.X - controlOffset, end.Y); SKPoint p3 = end; - // A. Draw the main Bezier curve link line using (var path = new SKPath()) { path.MoveTo(start); @@ -230,14 +461,12 @@ private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, S canvas.DrawPath(path, paint); } - // B. Render Source Label Badge near the first third mark (t = 0.30) if (!string.IsNullOrEmpty(sourceLabel)) { SKPoint pointOnCurve = GetCubicBezierPoint(0.30f, p0, p1, p2, p3); DrawLabelBadge(canvas, textPaint, pointOnCurve, sourceLabel); } - // C. Render Target Label Badge near the last third mark (t = 0.70) if (!string.IsNullOrEmpty(targetLabel)) { SKPoint pointOnCurve = GetCubicBezierPoint(0.70f, p0, p1, p2, p3); @@ -245,7 +474,6 @@ private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, S } } - // HELPER: Calculates exact XY positions along a Cubic Bezier curve at a given 't' percentage split private SKPoint GetCubicBezierPoint(float t, SKPoint p0, SKPoint p1, SKPoint p2, SKPoint p3) { float u = 1 - t; @@ -260,86 +488,78 @@ private SKPoint GetCubicBezierPoint(float t, SKPoint p0, SKPoint p1, SKPoint p2, return new SKPoint(x, y); } - // HELPER: Renders a clean white protective text capsule card over the line layout canvas private void DrawLabelBadge(SKCanvas canvas, SKPaint textPaint, SKPoint position, string text) { float textWidth = textPaint.MeasureText(text); - // Draw background masking box so intersecting lines do not cut through the text characters using (var bgPaint = new SKPaint { Color = SKColors.White, Style = SKPaintStyle.Fill }) { var bgRect = new SKRect(position.X - (textWidth / 2) - 5, position.Y - 13, position.X + (textWidth / 2) + 5, position.Y + 3); canvas.DrawRoundRect(bgRect, 4, 4, bgPaint); } - // Print the clean centered text label canvas.DrawText(text, position.X, position.Y - 1, textPaint); } - private Control ResolveSourceControl(object source) + + private SKPoint GetControlPoint(object visualElement, bool isSource) { - if (source is Control ctrl) return ctrl; + if (visualElement == null) return SKPoint.Empty; - if (source is System.Xml.XmlNode xmlNode && this.Parent != null) + // SCENARIO A: The element is a virtual schema node item row + if (visualElement is SchemaNodeItem sni) { - // 1. Scan Left Column (Source Schema Tree Pane Container) - foreach (Control c in this.Parent.Controls) + if (sni.Tag is SKRect rect) { - if (c is FlowLayoutPanel pnlScroll && pnlScroll.Name == "pnlSchemaScrollContainer") - { - foreach (Control subCtrl in pnlScroll.Controls) - { - if (subCtrl is SchemaNodeItem sni && sni.XmlSourceNode == xmlNode) - { - return sni; - } - } - } - - // 2. Scan Right Column (Target Schema Tree Pane Container) - if (c is FlowLayoutPanel pnlTargetScroll && pnlTargetScroll.Name == "pnlTargetSchemaScrollContainer") - { - foreach (Control subCtrl in pnlTargetScroll.Controls) - { - if (subCtrl is SchemaNodeItem sni && sni.XmlSourceNode == xmlNode) - { - return sni; - } - } - } + float x = isSource ? rect.Right : rect.Left; + float y = rect.Top + (rect.Height / 2f); + return new SKPoint(x, y); } + return SKPoint.Empty; } - return null; - } - private SKPoint GetControlPoint(Control ctrl, bool isSource) - { - if (ctrl == null || ctrl.Parent == null) return SKPoint.Empty; - - try + // SCENARIO B: The element is a physical WinForms control + if (visualElement is Control ctrl) { - // If it's a source, line should emerge from the RIGHT edge. - // If it's a target, line should snap into the LEFT edge. - int targetX = isSource ? ctrl.Width : 0; - Point localAnchorPt = new Point(targetX, ctrl.Height / 2); + if (ctrl.Parent == null) return SKPoint.Empty; + try + { + int targetX = isSource ? ctrl.Width : 0; + Point localAnchorPt = new Point(targetX, ctrl.Height / 2); - Point screenPt = ctrl.PointToScreen(localAnchorPt); - Point localPt = this.PointToClient(screenPt); + Point screenPt = ctrl.PointToScreen(localAnchorPt); + Point localPt = this.PointToClient(screenPt); - return new SKPoint(localPt.X, localPt.Y); - } - catch (Exception) - { - return SKPoint.Empty; + return new SKPoint(localPt.X, localPt.Y); + } + catch (Exception) + { + return SKPoint.Empty; + } } + + return SKPoint.Empty; + } + + private float Clamp(float value, float min, float max) + { + if (value < min) return min; + if (value > max) return max; + return value; } - } public class MappingConnection { - // REVERTED TO OBJECT: Restores perfect compilation type safety across files public object Source { get; set; } public object Target { get; set; } public SKColor LineColor { get; set; } = SKColors.DodgerBlue; } + + public class VirtualRegion + { + public string Name { get; set; } + public SKRect Bounds { get; set; } + public float ScrollOffset { get; set; } = 0; + public float MaxScrollHeight { get; set; } = 0; + } } \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index f0c8d1c4..036e90c8 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -33,6 +33,7 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.lbxTargetSchema = new System.Windows.Forms.ListBox(); this.chkBrowse = new System.Windows.Forms.CheckBox(); this.btnMap = new System.Windows.Forms.Button(); this.btnFindSpec = new System.Windows.Forms.Button(); @@ -55,11 +56,9 @@ private void InitializeComponent() this.FormLocations = new System.Windows.Forms.TabPage(); this.rtLocations = new System.Windows.Forms.RichTextBox(); this.tbpMap = new System.Windows.Forms.TabPage(); - this.splitContainer2 = new System.Windows.Forms.SplitContainer(); this.pnlFunctoids = new System.Windows.Forms.Panel(); this.trvTarget = new System.Windows.Forms.TreeView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.lbxTargetSchema = new System.Windows.Forms.ListBox(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -70,9 +69,6 @@ private void InitializeComponent() this.browser.SuspendLayout(); this.FormLocations.SuspendLayout(); this.tbpMap.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); - this.splitContainer2.Panel1.SuspendLayout(); - this.splitContainer2.SuspendLayout(); this.SuspendLayout(); // // statusStrip1 @@ -146,6 +142,15 @@ private void InitializeComponent() this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // + // lbxTargetSchema + // + this.lbxTargetSchema.FormattingEnabled = true; + this.lbxTargetSchema.Location = new System.Drawing.Point(3, 283); + this.lbxTargetSchema.Margin = new System.Windows.Forms.Padding(2); + this.lbxTargetSchema.Name = "lbxTargetSchema"; + this.lbxTargetSchema.Size = new System.Drawing.Size(356, 147); + this.lbxTargetSchema.TabIndex = 13; + // // chkBrowse // this.chkBrowse.AutoSize = true; @@ -362,7 +367,7 @@ private void InitializeComponent() this.browser.Margin = new System.Windows.Forms.Padding(2); this.browser.Name = "browser"; this.browser.Padding = new System.Windows.Forms.Padding(2); - this.browser.Size = new System.Drawing.Size(1290, 519); + this.browser.Size = new System.Drawing.Size(1290, 742); this.browser.TabIndex = 1; this.browser.Text = "Browser"; this.browser.UseVisualStyleBackColor = true; @@ -375,7 +380,7 @@ private void InitializeComponent() this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(1286, 515); + this.webBrowser1.Size = new System.Drawing.Size(1286, 738); this.webBrowser1.TabIndex = 0; // // FormLocations @@ -384,7 +389,7 @@ private void InitializeComponent() this.FormLocations.Location = new System.Drawing.Point(4, 22); this.FormLocations.Name = "FormLocations"; this.FormLocations.Padding = new System.Windows.Forms.Padding(3); - this.FormLocations.Size = new System.Drawing.Size(1290, 519); + this.FormLocations.Size = new System.Drawing.Size(1290, 742); this.FormLocations.TabIndex = 2; this.FormLocations.Text = "Form locations"; this.FormLocations.UseVisualStyleBackColor = true; @@ -397,39 +402,26 @@ private void InitializeComponent() this.rtLocations.ForeColor = System.Drawing.Color.Lime; this.rtLocations.Location = new System.Drawing.Point(3, 3); this.rtLocations.Name = "rtLocations"; - this.rtLocations.Size = new System.Drawing.Size(1284, 513); + this.rtLocations.Size = new System.Drawing.Size(1284, 736); this.rtLocations.TabIndex = 2; this.rtLocations.Text = "aaaa"; // // tbpMap // - this.tbpMap.Controls.Add(this.splitContainer2); + this.tbpMap.Controls.Add(this.pnlFunctoids); this.tbpMap.Location = new System.Drawing.Point(4, 22); this.tbpMap.Name = "tbpMap"; - this.tbpMap.Size = new System.Drawing.Size(1290, 519); + this.tbpMap.Size = new System.Drawing.Size(1290, 742); this.tbpMap.TabIndex = 3; this.tbpMap.Text = "Mapper"; this.tbpMap.UseVisualStyleBackColor = true; // - // splitContainer2 - // - this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer2.Location = new System.Drawing.Point(0, 0); - this.splitContainer2.Name = "splitContainer2"; - // - // splitContainer2.Panel1 - // - this.splitContainer2.Panel1.Controls.Add(this.pnlFunctoids); - this.splitContainer2.Size = new System.Drawing.Size(1290, 519); - this.splitContainer2.SplitterDistance = 430; - this.splitContainer2.TabIndex = 0; - // // pnlFunctoids // this.pnlFunctoids.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlFunctoids.Location = new System.Drawing.Point(0, 0); this.pnlFunctoids.Name = "pnlFunctoids"; - this.pnlFunctoids.Size = new System.Drawing.Size(430, 519); + this.pnlFunctoids.Size = new System.Drawing.Size(1290, 742); this.pnlFunctoids.TabIndex = 0; this.pnlFunctoids.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragDrop); this.pnlFunctoids.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragEnter); @@ -443,15 +435,6 @@ private void InitializeComponent() this.trvTarget.Size = new System.Drawing.Size(441, 519); this.trvTarget.TabIndex = 1; // - // lbxTargetSchema - // - this.lbxTargetSchema.FormattingEnabled = true; - this.lbxTargetSchema.Location = new System.Drawing.Point(3, 283); - this.lbxTargetSchema.Margin = new System.Windows.Forms.Padding(2); - this.lbxTargetSchema.Name = "lbxTargetSchema"; - this.lbxTargetSchema.Size = new System.Drawing.Size(356, 147); - this.lbxTargetSchema.TabIndex = 13; - // // X12UtilsFRM // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -476,9 +459,6 @@ private void InitializeComponent() this.browser.ResumeLayout(false); this.FormLocations.ResumeLayout(false); this.tbpMap.ResumeLayout(false); - this.splitContainer2.Panel1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); - this.splitContainer2.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -513,7 +493,6 @@ private void InitializeComponent() private System.Windows.Forms.RichTextBox rtLocations; private System.Windows.Forms.Button btnMap; private System.Windows.Forms.TabPage tbpMap; - private System.Windows.Forms.SplitContainer splitContainer2; private System.Windows.Forms.TreeView trvTarget; private System.Windows.Forms.CheckBox chkBrowse; private System.Windows.Forms.Panel pnlFunctoids; diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 7006cbf2..4c48040d 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -1,5 +1,6 @@ using NLog; using NLog.Windows.Forms; +using SkiaSharp; using System; using System.Collections.Generic; using System.Configuration; @@ -16,7 +17,6 @@ using X12.Parsing; using X12.Shared.Models; using X12.Transformations; -using static X12UtilsFRM.SkiaMapper; using Label = System.Windows.Forms.Label; using Rectangle = System.Drawing.Rectangle; @@ -29,29 +29,71 @@ public enum enmTabPages formLocations, map } + public partial class X12UtilsFRM : Form { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + private SkiaMapper _mapper; private List toolboxCategories = new List(); private Panel pnlToolboxContainer = null; - //-- DRAGGING STATE TRACKERS (CRITICAL for smooth UX) -- - private bool _isDraggingFunctoid = false; - private Point _dragStartMousePos; - private Point _dragStartControlPos; - //-- END DRAGGING STATE TRACKERS -- - // This flat registry will hold every single node item for quick access during layout calculations and visibility checks - // Define these class-level variables inside X12UtilsFRM.cs private Panel pnlToolboxWrapper = null; - private FlowLayoutPanel pnlToolboxCategoriesContainer = null; - private List flatSchemaRegistry = new List(); - // Add this field at the top of X12UtilsFRM.cs with your other panel declarations - private FlowLayoutPanel pnlTargetSchemaScrollContainer; - private List flatTargetSchemaRegistry = new List(); + private FlowLayoutPanel pnlToolboxCategoriesContainer = null; private Button btnToolboxToggle = null; private bool _isToolboxExpanded = true; private const int ToolboxWidth = 245; + + // Draggable capsule tracking properties + private bool _isDraggingFunctoid = false; + private Point _dragStartMousePos; + private Point _dragStartControlPos; + + List interchanges = null; + ToolTip tt = null; + private string locationsFile = ""; + private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; + static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; + + public X12UtilsFRM() + { + InitializeComponent(); + + // Instantiate our updated 100% pure Skia layout manager canvas + _mapper = new SkiaMapper(); + _mapper.Dock = DockStyle.Fill; + + if (this.pnlFunctoids != null) + { + this.pnlFunctoids.Controls.Add(_mapper); + _mapper.SendToBack(); + + // Track control resizing changes so the virtual splits adapt smoothly + this.pnlFunctoids.Resize += (s, e) => + { + _mapper.RecalculateVirtualLayout(); + _mapper.Invalidate(); + }; + } + + this.pnlFunctoids.AllowDrop = true; + _mapper.AllowDrop = true; + + // Wire drag-drop routing mechanics onto the primary canvas + _mapper.DragEnter += pnlFunctoids_DragEnter; + _mapper.DragOver += pnlFunctoids_DragEnter; + _mapper.DragDrop += pnlFunctoids_DragDrop; + } + + private static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") + { + Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); + Trace.Flush(); + } + + #region Toolbox Implementation + private void InitializeToolbox() { - // 1. The main master wrapper panel pinned to the far right edge of the workspace canvas pnlToolboxWrapper = new Panel { Width = ToolboxWidth + 20, @@ -62,7 +104,6 @@ private void InitializeToolbox() pnlFunctoids.Controls.Add(pnlToolboxWrapper); pnlToolboxWrapper.BringToFront(); - // 2. The thin, vertical toggle bar button btnToolboxToggle = new Button { Text = "»", @@ -78,20 +119,18 @@ private void InitializeToolbox() btnToolboxToggle.Click += ToggleToolbox_Click; pnlToolboxWrapper.Controls.Add(btnToolboxToggle); - // 3. REVISED: Scrollable Flow Layout Container pnlToolboxCategoriesContainer = new FlowLayoutPanel { Dock = DockStyle.Fill, BackColor = Color.Transparent, - FlowDirection = FlowDirection.TopDown, // Force items to stack vertically - WrapContents = false, // Prevent side-by-side wrapping of categories - AutoScroll = true, // Automatically show vertical scrollbar when needed - Padding = new Padding(20, 20, 20, 20) // Top padding matching + FlowDirection = FlowDirection.TopDown, + WrapContents = false, + AutoScroll = true, + Padding = new Padding(20, 20, 20, 20) }; pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); pnlToolboxCategoriesContainer.BringToFront(); - // 4. Register your default operational utility items var stringTools = new List { "Concatenate", "String Left", "String Right", "Trim", "Uppercase", "Lowercase" }; var mathTools = new List { "Add", "Subtract", "Multiply", "Divide", "Modulus", "Absolute" }; var dateTools = new List { "Current Date", "Date Format", "Add Days", "Date Diff" }; @@ -105,6 +144,7 @@ private void InitializeToolbox() RenderToolboxLayout(); } + private void RenderToolboxLayout() { if (pnlToolboxCategoriesContainer == null) return; @@ -114,24 +154,18 @@ private void RenderToolboxLayout() foreach (var category in toolboxCategories) { - // Allocate a predictable fixed layout width that fits safely inside the container view - // regardless of whether the vertical scrollbar is currently visible or hidden. category.Width = 205; - - // Apply width parameters downwards into the category inner containers category.UpdateHeight(); - category.Margin = new Padding(6, 0, 0, 6); - pnlToolboxCategoriesContainer.Controls.Add(category); } pnlToolboxCategoriesContainer.ResumeLayout(true); } + private void ToggleToolbox_Click(object sender, EventArgs e) { _isToolboxExpanded = !_isToolboxExpanded; - pnlFunctoids.SuspendLayout(); if (_isToolboxExpanded) @@ -140,8 +174,6 @@ private void ToggleToolbox_Click(object sender, EventArgs e) pnlToolboxWrapper.Location = new Point(pnlFunctoids.Width - pnlToolboxWrapper.Width, 0); pnlToolboxCategoriesContainer.Visible = true; btnToolboxToggle.Text = "»"; - - // Force the layout engine to recalculate child widths immediately upon expansion RenderToolboxLayout(); } else @@ -155,37 +187,26 @@ private void ToggleToolbox_Click(object sender, EventArgs e) pnlFunctoids.ResumeLayout(true); _mapper.Invalidate(); } - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - List interchanges = null; - ToolTip tt = null; - private string locationsFile = ""; - private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; - static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; - static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") - { - Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); - Trace.Flush(); - } + #endregion + + #region Drag and Drop Handling Logic + private void MakeControlDraggable(Control masterControl) { - // Route dragging events from the master wrapper panel container itself AttachDragEvents(masterControl, masterControl); - - // Recursively bind child controls so clicking the text label or icon block drags the whole node! foreach (Control child in masterControl.Controls) { AttachDragEvents(child, masterControl); } } + private void AttachDragEvents(Control eventTriggerControl, Control actualMovingTarget) { eventTriggerControl.MouseDown += (sender, e) => { if (e.Button == MouseButtons.Left) { - // FIX PART 1: If Shift is held, skip this moving logic completely - // so BizTalkFunctoidNode's connection hook can fire! if (Control.ModifierKeys == Keys.Shift) return; _isDraggingFunctoid = true; @@ -197,7 +218,6 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT eventTriggerControl.MouseMove += (sender, e) => { - // FIX PART 2: Safety guard block if (Control.ModifierKeys == Keys.Shift) { _isDraggingFunctoid = false; @@ -214,7 +234,6 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT _dragStartControlPos.Y + deltaY ); - // Smoothly recalculate connection positions in real-time _mapper.Invalidate(); } }; @@ -227,146 +246,52 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT } }; } - private FlowLayoutPanel pnlSchemaScrollContainer = new FlowLayoutPanel - { - Name = "pnlSchemaScrollContainer", // CRITICAL: Allows SkiaMapper to instantly detect it - Width = 285, - Location = new Point(20, 20), - Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left, - FlowDirection = FlowDirection.TopDown, - WrapContents = false, - AutoScroll = true, - BackColor = Color.Transparent - }; + + #endregion + + #region Embedded Schema Virtual Setup + private void InitializeEmbeddedSchemaLayout(string sourceXmlPath, string targetXmlPath) { - pnlFunctoids.Controls.Clear(); + // Clear connections and bind data directly into the background Skia registries _mapper.Connections.Clear(); - flatSchemaRegistry.Clear(); - flatTargetSchemaRegistry.Clear(); // Reset the destination registry + _mapper.FlatSchemaRegistry.Clear(); + _mapper.FlatTargetSchemaRegistry.Clear(); - pnlFunctoids.BackColor = Color.Transparent; + // Set up default initial coordinate divisions + float initialWidth = pnlFunctoids.Width; + _mapper.RecalculateVirtualLayout(); - // 1. Setup background Skia drawing canvas - _mapper.Dock = DockStyle.Fill; - pnlFunctoids.Controls.Add(_mapper); - _mapper.SendToBack(); - - // 2. Left Column: Full-Height Source Document Tree Container - pnlSchemaScrollContainer = new FlowLayoutPanel - { - Name = "pnlSchemaScrollContainer", - Width = 285, - Location = new Point(0, 0), - Height = pnlFunctoids.Height, - Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left, - FlowDirection = FlowDirection.TopDown, - WrapContents = false, - AutoScroll = true, - BackColor = Color.Transparent - }; - pnlSchemaScrollContainer.Scroll += (s, e) => { _mapper.Invalidate(); }; - pnlFunctoids.Controls.Add(pnlSchemaScrollContainer); - pnlSchemaScrollContainer.BringToFront(); - - // 3. NEW: Right Column: Full-Height Target Document Tree Container - // Positions it perfectly adjacent to the right edge toolbox panel boundary - int targetLeftCoordinate = pnlFunctoids.Width - 285 - (pnlToolboxWrapper?.Width ?? 220); - pnlTargetSchemaScrollContainer = new FlowLayoutPanel - { - Name = "pnlTargetSchemaScrollContainer", - Width = 285, - Location = new Point(targetLeftCoordinate, 0), - Height = pnlFunctoids.Height, - Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right, // Anchors right! - FlowDirection = FlowDirection.TopDown, - WrapContents = false, - AutoScroll = true, - BackColor = Color.Transparent, - AllowDrop = true - }; - // FIX 2: Wire up the DragEnter and DragOver events to accept incoming mapping links - pnlTargetSchemaScrollContainer.DragEnter += TargetSchemaPanel_DragEnterOrOver; - pnlTargetSchemaScrollContainer.DragOver += TargetSchemaPanel_DragEnterOrOver; - pnlTargetSchemaScrollContainer.DragDrop += pnlFunctoids_DragDrop; - // Keep your scrolling refresh trigger intact - pnlTargetSchemaScrollContainer.Scroll += (s, e) => { _mapper.Invalidate(); }; - pnlFunctoids.Controls.Add(pnlTargetSchemaScrollContainer); - pnlTargetSchemaScrollContainer.BringToFront(); - - // 4. Load Source XML Data + // Load Source XML Data Tree Structures straight to data variables XmlDocument sourceDoc = new XmlDocument(); sourceDoc.Load(sourceXmlPath); BuildCustomSchemaTree(sourceDoc.DocumentElement, 0, isTargetSchema: false); - RenderCustomSchemaLayout(isTargetSchema: false); - // 5. Load Target XML Data + // Load Target XML Data Tree Structures straight to data variables XmlDocument targetDoc = new XmlDocument(); targetDoc.Load(targetXmlPath); BuildCustomSchemaTree(targetDoc.DocumentElement, 0, isTargetSchema: true); - RenderCustomSchemaLayout(isTargetSchema: true); - // Initialize right-hand toolbox panel accordion panels InitializeToolbox(); - - pnlFunctoids.AllowDrop = true; _mapper.Invalidate(); } - private void RenderCustomSchemaLayout(bool isTargetSchema) - { - FlowLayoutPanel container = isTargetSchema ? pnlTargetSchemaScrollContainer : pnlSchemaScrollContainer; - List registry = isTargetSchema ? flatTargetSchemaRegistry : flatSchemaRegistry; - if (container == null) return; - - container.SuspendLayout(); - container.Controls.Clear(); - - bool isFirstItem = true; - - foreach (var item in registry) - { - // Calculate visible collapse expansion loops hierarchy states - if (IsNodeChainVisible(item)) - { - item.Width = container.Width - 25; - - if (isFirstItem) - { - item.Margin = new Padding(0, 10, 0, 2); - isFirstItem = false; - } - else - { - item.Margin = new Padding(0, 0, 0, 2); - } - - container.Controls.Add(item); - } - } - - container.ResumeLayout(true); - } private void BuildCustomSchemaTree(XmlNode node, int depth, bool isTargetSchema) { if (node == null) return; SchemaNodeItem item = new SchemaNodeItem(node, depth, (clickedItem) => { - RenderCustomSchemaLayout(isTargetSchema); - _mapper.Invalidate(); + _mapper.Invalidate(); // Redraw vector elements cleanly }); if (isTargetSchema) { - flatTargetSchemaRegistry.Add(item); - - // FIX: Deep-wire the drag-and-drop validation rules down to the subcomponent layer! - EnableTargetNodeDragDropInteractions(item); + _mapper.FlatTargetSchemaRegistry.Add(item); } else { - flatSchemaRegistry.Add(item); + _mapper.FlatSchemaRegistry.Add(item); } if (node.Attributes != null) @@ -385,305 +310,127 @@ private void BuildCustomSchemaTree(XmlNode node, int depth, bool isTargetSchema) } } } - private void EnableTargetNodeDragDropInteractions(Control rootTargetControl) - { - rootTargetControl.AllowDrop = true; - rootTargetControl.DragEnter += TargetSchemaPanel_DragEnterOrOver; - rootTargetControl.DragOver += TargetSchemaPanel_DragEnterOrOver; - rootTargetControl.DragDrop += pnlFunctoids_DragDrop; - // Loop through nested controls (like the text label and icon inside SchemaNodeItem) - foreach (Control childControl in rootTargetControl.Controls) - { - childControl.AllowDrop = true; - childControl.DragEnter += TargetSchemaPanel_DragEnterOrOver; - childControl.DragOver += TargetSchemaPanel_DragEnterOrOver; - childControl.DragDrop += pnlFunctoids_DragDrop; + #endregion - // Go deeper if your row item has nested layouts - if (childControl.HasChildren) - { - EnableTargetNodeDragDropInteractions(childControl); - } - } - } - private void RenderCustomSchemaLayout() - { - if (pnlSchemaScrollContainer == null) return; - // Lock UI drawing updates temporarily to prevent visible scroll layout flickering - pnlSchemaScrollContainer.SuspendLayout(); - pnlSchemaScrollContainer.Controls.Clear(); - foreach (var item in flatSchemaRegistry) - { - if (IsNodeChainVisible(item)) - { - // Lock control item width slightly lower than the container size - // so the text doesn't slide under the scrollbar track - item.Width = pnlSchemaScrollContainer.Width - 25; - item.Margin = new Padding(0, 0, 0, 2); // Subtle horizontal row padding row gap + #region Form Controls & Life Cycle - pnlSchemaScrollContainer.Controls.Add(item); - } - } - pnlSchemaScrollContainer.ResumeLayout(true); - } - private bool IsNodeChainVisible(SchemaNodeItem item) - { - // Climb up the registry tree chain to see if any parent structural block is collapsed - var current = item; - while (current != null) - { - // Find who owns this child node in the flat registry list - var parent = flatSchemaRegistry.Find(p => p.ChildNodes.Contains(current)); - if (parent != null && !parent.IsExpanded) return false; - current = parent; - } - return true; - } - public string X12Tohtml(string x12) - { - var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); - return htmlService.Transform(x12); - } - public string X12ToXml(string x12) - { - using (MemoryStream memStream = new MemoryStream(1000)) - { - interchanges.First().Serialize(memStream); - memStream.Seek(0, 0); - StreamReader sr = new StreamReader(memStream); - return sr.ReadToEnd(); - } - } - private SkiaMapper _mapper; - private void UpdateMap() - { // This is where you'd update the _mapper.Connections based on the current state of your UI controls - _mapper.Invalidate(); - } protected override void OnLoad(EventArgs e) { base.OnLoad(e); - - // Ensure RichTextBox target points to this form and control - //this also reroute the console to RTB RichTextBoxTarget.ReInitializeAllTextboxes(this); - - // Test logging - Logger.Info("RichTextBox target initialized successfully, any existing Console logging will be routed to this RichTextBox "); - Logger.Debug("Debug message to RichTextBox"); + Logger.Info("RichTextBox target initialized successfully."); } + protected override void OnShown(EventArgs e) { base.OnShown(e); - RichTextBoxTarget.ReInitializeAllTextboxes(this); // In case form was not loaded when logging started */ + RichTextBoxTarget.ReInitializeAllTextboxes(this); Logger.Info("RichTextBox logging attached (UI-safe)."); } - #region form - public X12UtilsFRM() - { - InitializeComponent(); - _mapper = new SkiaMapper(); - _mapper.Dock = DockStyle.Fill; - - // FIX: Add it to the specific Panel you created in the designer, - // NOT the SplitContainer.Panel2 directly. - if (this.pnlFunctoids != null) - { - this.pnlFunctoids.Controls.Add(_mapper); - _mapper.SendToBack(); - } - - this.pnlFunctoids.AllowDrop = true; - - } - private void Form1_Load(object sender, EventArgs e) { - rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML" ? true : false; + rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML"; tt = new ToolTip(); - tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder} to the Listbox below.."); - if (String.IsNullOrEmpty(Properties.Settings.Default.fileList)) + tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder}"); + + if (string.IsNullOrEmpty(Properties.Settings.Default.fileList)) { btnAddFiles_Click(null, null); - } lbxInfileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); lbxTargetSchema.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); + lbxInfileList.SelectedIndex = 5; + lbxTargetSchema.SelectedIndex = 5; btnParse.Enabled = false; - Logger.Trace("Trace message"); - Logger.Debug("Debug message"); - Logger.Info("Info message"); - Logger.Warn("Warning message"); - // Logger.Error("Error message"); - Logger.Fatal("Fatal message"); } + private void X12UtilsFRM_FormClosing(object sender, FormClosingEventArgs e) { Properties.Settings.Default.Save(); } - #endregion form - private void DisplayHtml(string html) - { - webBrowser1.Navigate("about:blank"); - webBrowser1.AllowWebBrowserDrop = false; - webBrowser1.AllowNavigation = false; + #endregion - try - { - if (webBrowser1.Document != null) - { - webBrowser1.Document.Write(string.Empty); - } - } - catch (Exception e) - { + #region File Processing Actions - } - webBrowser1.DocumentText = html; - webBrowser1.AllowNavigation = true; - } - private void displayPdf(string file) + private void btnMap_Click(object sender, EventArgs e) { - webBrowser1.AllowNavigation = true; + string inputFileName = lbxInfileList.Text; + string outputFileName = lbxTargetSchema.Text; - if (this.webBrowser1.Document != null) + if (string.IsNullOrEmpty(inputFileName) || string.IsNullOrEmpty(outputFileName)) { - this.webBrowser1.Navigate(file); + MessageBox.Show("Please select both source and target XML files for mapping."); + return; } - } - private void rbXml_CheckedChanged(object sender, EventArgs e) - { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - private void rbHtml_CheckedChanged(object sender, EventArgs e) - { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - public string ContentFromFile(string filename/*fullPath*/) - { - using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) + + if (Path.GetExtension(inputFileName) != ".xml") { - return new StreamReader(filename).ReadToEnd(); + MessageBox.Show("File extension must be an XML"); + return; } + + tabControl1.SelectedIndex = (int)enmTabPages.map; + InitializeEmbeddedSchemaLayout(inputFileName, outputFileName); } - private Encoding GetEncoding(string fname) + + private void btnParse_Click(object sender, EventArgs e) { - byte[] header = new byte[6]; - using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read)) + string x = ""; + switch (Properties.Settings.Default.TransformFormat) { - fs.Read(header, 0, 6);// peak 6 characters to detemind encoding - fs.Close(); + case "HTML": x = X12Tohtml(rtxInterchangeFile.Text); break; + case "XML": x = X12ToXml(rtxInterchangeFile.Text); break; } - return (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; + DisplayHtml(x); + tabControl1.SelectedIndex = (int)enmTabPages.browser; } - public string ReadFromStream(Stream strm) - { - // Log(strm.Position.ToString()); - - using (StreamReader sr = new StreamReader(strm)) - return sr.ReadToEnd(); - } - private void lblInterchangeCount_TextChanged(object sender, EventArgs e) + public string X12Tohtml(string x12) { - int fcount = int.Parse(((Label)sender).Text); - btnParse.Enabled = fcount == 1 ? true : false; + var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); + return htmlService.Transform(x12); } - private void lbxInputFileList(object sender, EventArgs e) - { - string fileName = ((ListBox)sender).Text; - if (String.IsNullOrEmpty(fileName)) return; - tt.SetToolTip(lbxInfileList, fileName + " is Selected now.."); - if (chkBrowse.Checked) + public string X12ToXml(string x12) + { + using (MemoryStream memStream = new MemoryStream(1000)) { - switch (Path.GetExtension(fileName)) - { - case ".txt": - DisplayHtml(X12ToXml(ContentFromFile(fileName))); - break; - case ".xml": - DisplayHtml(ContentFromFile(fileName)); - tabControl1.SelectedIndex = (int)enmTabPages.browser; - break; - default: - break; - } - return; + interchanges.First().Serialize(memStream); + memStream.Seek(0, 0); + StreamReader sr = new StreamReader(memStream); + return sr.ReadToEnd(); } - - - - - - //lblSelectedFile.Text = Path.GetFileName(inputFileName); - //Log($"inputFileName={inputFileName}"); - - - - //bool throwException = Properties.Settings.Default.throwExceptions; - //rtxInterchangeFile.Text = ContentFromFile(inputFileName); - - //X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), throwException); - - //parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); - - //interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); - //lblInterchangeCount.Text = interchanges.Count.ToString(); - - - } - private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args)// => throw new NotImplementedException(); + + private void DisplayHtml(string html) { - Log($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); + webBrowser1.Navigate("about:blank"); + webBrowser1.AllowWebBrowserDrop = false; + webBrowser1.AllowNavigation = false; + + try + { + if (webBrowser1.Document != null) webBrowser1.Document.Write(string.Empty); + } + catch { } + webBrowser1.DocumentText = html; + webBrowser1.AllowNavigation = true; } + private void btnAddFiles_Click(object sender, EventArgs e) { - OpenFileDialog fd = new OpenFileDialog(); - fd.InitialDirectory = Properties.Settings.Default.X12Folder; - fd.Filter = "Text Files(*.txt)|*.txt|X12 Files|*.x12"; - fd.FilterIndex = 0; - lbxInfileList.Items.Clear(); lbxInfileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); lbxInfileList.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); string[] ss = new string[lbxInfileList.Items.Count]; lbxInfileList.Items.CopyTo(ss, 0); - Properties.Settings.Default.fileList = String.Join(",", ss); + Properties.Settings.Default.fileList = string.Join(",", ss); Properties.Settings.Default.Save(); - - - - - } - #region buttons - private void btnParse_Click(object sender, EventArgs e) - { - string x = ""; - switch (Properties.Settings.Default.TransformFormat) - { - - case "HTML": - x = X12Tohtml(rtxInterchangeFile.Text); - break; - case "XML": - x = X12ToXml(rtxInterchangeFile.Text); - break; - } - DisplayHtml(x); - tabControl1.SelectedIndex = (int)enmTabPages.browser; - } private void btnFindSpec_Click(object sender, EventArgs e) { @@ -708,366 +455,60 @@ private void btnFindSpec_Click(object sender, EventArgs e) MessageBox.Show($"Spec Not Found for 856"); } } - private void btnHippaParse_Click(object sender, EventArgs e) - { - if (lbxInfileList.SelectedItem == null) - { - MessageBox.Show("Please choose a file .."); - return; - } - Stream stream = new FileStream($"{lbxInfileList.SelectedItem}", FileMode.Open, FileAccess.Read); - - - - // new up a ClaimTransformationService object - InstitutionalClaimToUb04ClaimFormTransformation ict = new InstitutionalClaimToUb04ClaimFormTransformation($"{TestImageDirectory}\\UB04_Red.gif"); - ict.DebugFile += Ict_DebugFile; - - ict.DebugFile += (s, file) => - { - try - { - Logger.Info($"Debug file generated: {file}"); - - this.locationsFile = file; - - this.Invoke((MethodInvoker)delegate - { - MessageBox.Show($"Found: {file}"); - }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine(ex.Message); - } - }; - - var service = new ClaimFormTransformationService( - new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif"), - ict, - new ProfessionalClaimToHcfa1500FormTransformation($"{TestImageDirectory}\\HCFA1500_Red.gif")); - - - - String outfile = $"{lbxInfileList.SelectedItem}.pdf"; - try - { - if (File.Exists(outfile)) - File.Delete(outfile); - } - catch (Exception ex) - { - MessageBox.Show($"Error deleting file {outfile}.\n{ex.Message}", "Error Deleting File", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - using (FileStream pdfoutput = new FileStream(outfile, FileMode.Create, FileAccess.Write)) - { - ClaimDocument document = service.Transform837ToClaimDocument(stream); - var fonetDocument = new XmlDocument(); - string fonetXml = service.TransformClaimDocumentToFoXml(document); - fonetDocument.LoadXml(fonetXml); - Fonet.FonetDriver driver = Fonet.FonetDriver.Make(); - driver.CloseOnExit = true; - driver.Render(fonetDocument, pdfoutput); - pdfoutput.Close(); - } - string pdfout = $"file:///{outfile}"; - webBrowser1.Navigate(pdfout); - tabControl1.SelectedTab = tabControl1.TabPages["browser"]; - - - } - - private void AddXmlNodes(XmlNode xmlNode, TreeNode treeNode) - { - // 1. Add Attributes first (BizTalk style shows these with a different icon/prefix) - if (xmlNode.Attributes != null) - { - foreach (XmlAttribute attr in xmlNode.Attributes) - { - TreeNode attrNode = new TreeNode("@" + attr.Name); - attrNode.Tag = attr; // Store the actual attribute object - attrNode.ForeColor = Color.DarkBlue; // Visual distinction - treeNode.Nodes.Add(attrNode); - } - } - - // 2. Add Child Elements - foreach (XmlNode childXmlNode in xmlNode.ChildNodes) - { - if (childXmlNode.NodeType == XmlNodeType.Element) - { - TreeNode childTreeNode = new TreeNode(childXmlNode.Name); - - // This is the key line you asked about: - childTreeNode.Tag = childXmlNode; - - treeNode.Nodes.Add(childTreeNode); - - // Recurse - AddXmlNodes(childXmlNode, childTreeNode); - } - } - } - - private TreeNode FindTreeNodeByTag(TreeNodeCollection nodes, object xmlNodeTarget) - { - foreach (TreeNode node in nodes) - { - if (node.Tag == xmlNodeTarget) - { - return node; - } - - // Deep search recursively through child branches - if (node.Nodes.Count > 0) - { - TreeNode found = FindTreeNodeByTag(node.Nodes, xmlNodeTarget); - if (found != null) return found; - } - } - return null; - } - private void LoadSchemaAsDiagramStart(string xmlFilePath) - { - if (!File.Exists(xmlFilePath)) - { - Logger.Warn($"Schema file not found: {xmlFilePath}"); - return; - } - - XmlDocument doc = new XmlDocument(); - doc.Load(xmlFilePath); - - // Clear out any previous dynamic mappings - pnlFunctoids.Controls.Clear(); - _mapper.Connections.Clear(); - - // Crucial: Re-add your SkiaMapper canvas so it remains the background! - pnlFunctoids.Controls.Add(_mapper); - _mapper.SendToBack(); - - // Start placing structural components at a fixed margin - int initialX = 20; // Left margin inside the panel - int initialY = 20; // Top margin inside the panel - int verticalSpacing = 45; // Space between each functoid block - - int currentY = initialY; - - // Loop through the main document segments (e.g., ISA, GS, ST, or Loops) - foreach (XmlNode childXmlNode in doc.DocumentElement.ChildNodes) - { - if (childXmlNode.NodeType == XmlNodeType.Element) - { - // 1. Automatically generate the Functoid Control UI - Point location = new Point(initialX, currentY); - Control functoidControl = CreateFunctoid(childXmlNode.Name, location); - - // 2. Add it to the panel - pnlFunctoids.Controls.Add(functoidControl); - functoidControl.BringToFront(); - - // 3. Find the matching TreeNode in trvSource to build the initial connection - // TreeNode matchingNode = FindTreeNodeByTag(trvSource.Nodes, childXmlNode); - - //if (matchingNode != null) - //{ - // // Auto-link the visual curve from the tree to the newly spawned functoid - // _mapper.Connections.Add(new MappingConnection - // { - // Source = matchingNode, - // Target = functoidControl - // }); - //} - - // Increment Y position for the next element block - currentY += verticalSpacing; - } - } - - // Force SkiaSharp to render all the newly created curves instantly - _mapper.Invalidate(); - Logger.Info("Input schema successfully mapped to diagram initialization state."); - } - private void btnMap_Click(object sender, EventArgs e) - { - string inputFileName = lbxInfileList.Text; - string outputFileName = lbxTargetSchema.Text; - if(String.IsNullOrEmpty(inputFileName) || String.IsNullOrEmpty(outputFileName)) - { - MessageBox.Show("Please select both source and target XML files for mapping."); - return; - } - - if (Path.GetExtension(inputFileName) != ".xml") - { - MessageBox.Show("File extension must be an XML"); - return; - } - - // Shift focus straight to your Map workspace tab - _mapper.Invalidate(); - tabControl1.SelectedIndex = (int)enmTabPages.map; - - // Initialize our single embedded layout canvas—No more trvSource duplicate setup! - InitializeEmbeddedSchemaLayout(inputFileName, outputFileName); - } - #endregion buttons - private void Ict_DebugFile(object sender, string e) - - { - this.Text = $"Debug file generated: {e}"; - - } - private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) - { - Logger.Info($"tab={tabControl1.SelectedIndex} name={tabControl1.TabPages[tabControl1.SelectedIndex].Name}"); - switch (tabControl1.SelectedIndex) - { - case (int)enmTabPages.parse: - break; - case (int)enmTabPages.browser: - break; - case (int)enmTabPages.formLocations: - rtLocations.Text = File.Exists(locationsFile) ? File.ReadAllText(locationsFile) : $"Locations file not found: {locationsFile}"; - break; - case (int)enmTabPages.map: - - break; - } - } - #region treecontrols - private void trvSource_AfterSelect(object sender, TreeViewEventArgs e) - { - if (e.Node.Tag is XmlElement element) - { - Logger.Info($"Selected Element: {element.Name}, Path: {element.ParentNode?.Name}/{element.Name}"); - } - else if (e.Node.Tag is XmlAttribute attribute) - { - Logger.Info($"Selected Attribute: {attribute.Name}, Value: {attribute.Value}"); - } - } - - private void trvSource_DragEnter(object sender, DragEventArgs e) - { - if (e.Data.GetDataPresent(typeof(TreeNode))) - { - // Sets the cursor to show a "Link" or "Copy" icon - e.Effect = DragDropEffects.Link; - } - else - { - // Keeps the cursor as "Not Allowed" - e.Effect = DragDropEffects.None; - } - } - - private void trvSource_ItemDrag(object sender, ItemDragEventArgs e) - { - // Cast dynamically so it works flawlessly for whichever TreeView fired it - if (sender is TreeView activeTree) - { - activeTree.SelectedNode = (TreeNode)e.Item; - Logger.Info($"Embedded tree item drag initiated: {activeTree.SelectedNode.Text}"); - activeTree.DoDragDrop(e.Item, DragDropEffects.Copy | DragDropEffects.Link); - } - } - - - #endregion treeControls - #region pnlFunctoids + #endregion + #region Functional Canvas Drag-Drop Core Engine private Control ResolveActualTargetNode(Control control, Point clientPt) { if (control == null) return null; - // 1. If dropping onto the Skia background surface, check if a control is physically underneath + // If dropping directly onto the Skia background surface, check if a physical + // Functoid control is sitting underneath the cursor coordinates if (control is SkiaMapper) { - // Check functoids and right panel items first foreach (Control c in pnlFunctoids.Controls) { - if (c != _mapper && c.Bounds.Contains(clientPt)) + // Skip the background mapper canvas itself and the toolbox wrapper + if (c != _mapper && c != pnlToolboxWrapper && c.Bounds.Contains(clientPt)) { return ResolveActualTargetNode(c, clientPt); } } - } - // 2. NEW: If the mouse is over a child label inside a SchemaNodeItem, find its parent row item - if (control.Parent is SchemaNodeItem targetSchemaItem) - { - // Ensure this row item actually lives inside the target panel registry - if (flatTargetSchemaRegistry.Contains(targetSchemaItem)) - { - return targetSchemaItem; - } + // If it hits empty canvas space, return the mapper itself as a valid placement target + return _mapper; } - // 3. If the mouse is over a child label inside a Functoid capsule, find its parent functoid - if (control.Parent is BizTalkFunctoidNode targetCapsule) - { - return targetCapsule; - } - - // 4. Return the control directly if it's already a valid base target type - if (control is BizTalkFunctoidNode || control is SchemaNodeItem) - { - return control; - } + // Handle dropping onto nested child components inside an existing Functoid capsule + if (control.Parent is BizTalkFunctoidNode targetCapsule) return targetCapsule; + if (control is BizTalkFunctoidNode) return control; return control; } - - private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) - { - // Check if the data being dragged is a TreeNode payload or a Functoid capsule - if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) - { - e.Effect = DragDropEffects.Copy | DragDropEffects.Link; - } - else - { - e.Effect = DragDropEffects.None; - } - } - private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) { - // 1. Calculate drop coordinates relative to the central panel space + // 1. Calculate drop coordinates relative to the central pnlFunctoids working area Point clientPoint = pnlFunctoids.PointToClient(new Point(e.X, e.Y)); - - // Resolve the exact parent container control under the mouse pointer Control rawTarget = pnlFunctoids.GetChildAtPoint(clientPoint); Control targetControl = ResolveActualTargetNode(rawTarget, clientPoint); - // 2. Clear out any background container boundary obstructions - if (targetControl == pnlSchemaScrollContainer || - targetControl == pnlTargetSchemaScrollContainer || - targetControl == pnlToolboxWrapper || - targetControl == pnlToolboxCategoriesContainer || - targetControl == btnToolboxToggle || - (pnlSchemaScrollContainer != null && pnlSchemaScrollContainer.Bounds.Contains(clientPoint)) || - (pnlTargetSchemaScrollContainer != null && pnlTargetSchemaScrollContainer.Bounds.Contains(clientPoint)) || - (pnlToolboxWrapper != null && pnlToolboxWrapper.Bounds.Contains(clientPoint))) - { + // Block drops completely if they clip over the right-hand toolbox panel boundaries + if (targetControl == pnlToolboxWrapper || targetControl == pnlToolboxCategoriesContainer || targetControl == btnToolboxToggle) return; - } object connectionSource = null; + bool isSourceANode = false; - // --- PACKAGING UNIFIED SOURCE PAYLOADS --- + // --- 2. EXTRACT SOURCE DATA PAYLOAD --- if (e.Data.GetDataPresent(typeof(TreeNode))) { TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); if (sourceNode != null) { - // Case A: Dropping a brand-new functoid from the toolbox panel list + // If dragging an abstract template item from the toolbox, spawn a new functoid control if (sourceNode.Tag as string == "FUNCTOID_TEMPLATE") { Control customFunctoidBlock = CreateFunctoid(sourceNode.Text, clientPoint); @@ -1077,133 +518,75 @@ private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) return; } - // Case B: Left or Right Tree Panel Data Element - if (sourceNode.Tag is System.Xml.XmlNode realXmlNode) + // If it's a virtual schema node payload generated by our SkiaMapper + if (sourceNode.Tag is XmlNode realXmlNode) { connectionSource = realXmlNode; + isSourceANode = true; } } } else if (e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) { - // Case C: Center Panel Functoid capsule being dragged + // Source is an existing central functoid capsule being dragged to form a link connectionSource = e.Data.GetData(typeof(BizTalkFunctoidNode)) as BizTalkFunctoidNode; } - // --- PIPELINE VALIDATION & CONNECTION STORAGE --- + // --- 3. PROCESS PATH CONNECTIONS --- if (connectionSource != null) { - // Intercept and check if the dragged node belongs to the right panel (Target Schema Registry) - bool isRightPanelNode = false; - if (e.Data.GetDataPresent(typeof(TreeNode))) - { - TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); - if (sourceNode != null && sourceNode.Tag is XmlNode realXmlNode) - { - isRightPanelNode = flatTargetSchemaRegistry.Any(sni => sni.XmlSourceNode == realXmlNode); - } - } + // Determine if this XML node belongs to the destination target schema registry + bool isRightPanelNode = isSourceANode && _mapper.FlatTargetSchemaRegistry.Any(sni => sni.XmlSourceNode == (XmlNode)connectionSource); if (isRightPanelNode) { - // FIX: If dragged from the right panel onto a functoid, invert the roles. - // The functoid becomes the data SOURCE (right side connection point), - // and the right panel node becomes the data TARGET. + // Reverse Drop Rule: If dragged from Right Schema onto a Functoid, link Functoid -> Schema Node if (targetControl is BizTalkFunctoidNode functoid) { - bool connectionExists = _mapper.Connections.Exists(c => c.Source == functoid && c.Target == connectionSource); - if (!connectionExists) + if (!_mapper.Connections.Exists(c => c.Source == functoid && c.Target == connectionSource)) { - _mapper.Connections.Add(new MappingConnection - { - Source = functoid, - Target = connectionSource - }); + _mapper.Connections.Add(new MappingConnection { Source = functoid, Target = connectionSource }); } _mapper.Invalidate(); } - else if (targetControl == null || targetControl is SkiaMapper) - { - // Fallback: If a right-panel node is dropped into empty space, spawn an inline functoid - // that feeds its output forward cleanly into the right panel node target. - TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); - Control autoFunctoid = CreateFunctoid(sourceNode.Text, clientPoint); - pnlFunctoids.Controls.Add(autoFunctoid); - autoFunctoid.BringToFront(); - - _mapper.Connections.Add(new MappingConnection - { - Source = autoFunctoid, - Target = connectionSource - }); - _mapper.Invalidate(); - } return; } - // Standard Flow: Left panel nodes or center functoids dragging to targets + // Standard Flow: Left panel schema node or center functoid dragging towards something else if (targetControl != null && targetControl != connectionSource) { - bool isValidTarget = false; - - // Target option A: Landing on a center functional capsule + // Scenario A: Dropping onto a center functoid control capsule if (targetControl is BizTalkFunctoidNode) { - isValidTarget = true; - } - // Target option B: Landing directly on a right-side destination schema node! - else if (targetControl is SchemaNodeItem targetSni && flatTargetSchemaRegistry.Contains(targetSni)) - { - isValidTarget = true; - } - - if (isValidTarget) - { - // Verify if an identical duplicate connection already exists on the canvas - bool connectionExists = _mapper.Connections.Exists(c => c.Source == connectionSource && c.Target == targetControl); - - if (!connectionExists) + if (!_mapper.Connections.Exists(c => c.Source == connectionSource && c.Target == targetControl)) { - _mapper.Connections.Add(new MappingConnection - { - Source = connectionSource, - Target = targetControl - }); + _mapper.Connections.Add(new MappingConnection { Source = connectionSource, Target = targetControl }); } - - _mapper.Invalidate(); // Repaint the Skia drawing layer immediately + _mapper.Invalidate(); } - else + // Scenario B: Dropping onto empty space on the SkiaMapper background canvas + else if (targetControl is SkiaMapper && isSourceANode) { - // Fallback: If it's a left node dropped into completely empty canvas air, spawn an inline capsule - if (e.Data.GetDataPresent(typeof(TreeNode)) && (targetControl == null || targetControl is SkiaMapper)) + // If a source node is dropped into empty gray space, auto-generate a new intermediate functoid capsule + Control autoFunctoid = CreateFunctoid(((XmlNode)connectionSource).Name, clientPoint); + pnlFunctoids.Controls.Add(autoFunctoid); + autoFunctoid.BringToFront(); + + _mapper.Connections.Add(new MappingConnection { - TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); - Control autoFunctoid = CreateFunctoid(sourceNode.Text, clientPoint); - pnlFunctoids.Controls.Add(autoFunctoid); - autoFunctoid.BringToFront(); - - _mapper.Connections.Add(new MappingConnection - { - Source = connectionSource, - Target = autoFunctoid - }); - _mapper.Invalidate(); - } + Source = connectionSource, + Target = autoFunctoid + }); + _mapper.Invalidate(); } } } } - - - #endregion pnlFunctoids - private void TargetSchemaPanel_DragEnterOrOver(object sender, DragEventArgs e) + private void pnlFunctoids_DragEnter(object sender, DragEventArgs e) { - // Check if the payload is a Left Tree Node or an active Canvas Functoid if (e.Data.GetDataPresent(typeof(TreeNode)) || e.Data.GetDataPresent(typeof(BizTalkFunctoidNode))) { - // Force the OS to display the clean link/drop pointer instead of the disallowed circle! - e.Effect = DragDropEffects.Link; + e.Effect = DragDropEffects.Copy | DragDropEffects.Link; } else { @@ -1216,26 +599,20 @@ private Control CreateFunctoid(string text, Point location) MakeControlDraggable(functoidNode); ContextMenuStrip functoidMenu = new ContextMenuStrip(); - - // NEW ITEM: Configure Script Editor var editScriptItem = new ToolStripMenuItem("Configure Script Properties..."); - editScriptItem.Image = SystemIcons.Question.ToBitmap(); // Add a clean systematic glyph contextually if wanted editScriptItem.Click += (sender, e) => { - // Open our modal dialog window, seeding it with the node's current custom script string using (var editorDlg = new FunctoidScriptEditorForm(functoidNode.FunctoidName, functoidNode.CustomScript)) { if (editorDlg.ShowDialog(this) == DialogResult.OK) { - // Update the capsule's stored script state with the developer's raw modifications functoidNode.CustomScript = editorDlg.CompiledScriptText; } } }; functoidMenu.Items.Add(editScriptItem); - functoidMenu.Items.Add(new ToolStripSeparator()); // Visual partition bar splitter line + functoidMenu.Items.Add(new ToolStripSeparator()); - // Existing Delete Functoid Item var deleteItem = new ToolStripMenuItem("Delete Functoid"); deleteItem.Click += (sender, e) => { @@ -1246,132 +623,83 @@ private Control CreateFunctoid(string text, Point location) }; functoidMenu.Items.Add(deleteItem); - // Assign context configurations across all nested component areas functoidNode.ContextMenuStrip = functoidMenu; functoidNode.LblIcon.ContextMenuStrip = functoidMenu; functoidNode.LblText.ContextMenuStrip = functoidMenu; - functoidNode.BringToFront(); return functoidNode; } + + #endregion + + #region Code Compilation Utilities (Xslt Outbound Maps) + public string CompileMapToXslt() { StringBuilder xslt = new StringBuilder(); - - // 1. Generate the standard BizTalk-compliant XSLT stylesheet headers xslt.AppendLine(""); xslt.AppendLine(""); xslt.AppendLine(" "); xslt.AppendLine(" "); xslt.AppendLine(); - - // 2. Main Entry Template Match (Targets the inbound root document segment) xslt.AppendLine(" "); - xslt.AppendLine(" "); - // 3. Process every active connection line on the Skia canvas foreach (var conn in _mapper.Connections) { - // Resolve the underlying immutable source data node structural footprint if (conn.Source is XmlNode sourceXmlNode) { - // Build the absolute absolute XPath locator string (e.g., Interchange/FunctionalGroup/Transaction/Element) string sourceXPath = BuildAbsoluteXPath(sourceXmlNode); - // CASE A: The line connects to an operational BizTalk Scripting Capsule if (conn.Target is BizTalkFunctoidNode functoid) { string targetNodeName = functoid.FunctoidName.Replace(" ", "_"); - string snippet = ""; - - // If the developer has customized the script via the script dialog window, use it - if (!string.IsNullOrEmpty(functoid.CustomScript) && !functoid.CustomScript.Contains("SOURCE_XPATH_PLACEHOLDER")) - { - snippet = functoid.CustomScript; - } - else - { - // Fall back to compiling our standard default rule sets from our compiler factory - snippet = FunctoidXsltCompiler.GetXsltSnippet(functoid.FunctoidName, sourceXPath, targetNodeName); - } + string snippet = !string.IsNullOrEmpty(functoid.CustomScript) && !functoid.CustomScript.Contains("SOURCE_XPATH_PLACEHOLDER") + ? functoid.CustomScript + : FunctoidXsltCompiler.GetXsltSnippet(functoid.FunctoidName, sourceXPath, targetNodeName); - // Swap out the placeholder trace with the real computed absolute XPath string - snippet = snippet.Replace("SOURCE_XPATH_PLACEHOLDER", sourceXPath); - - xslt.AppendLine($" {snippet}"); + xslt.AppendLine($" {snippet.Replace("SOURCE_XPATH_PLACEHOLDER", sourceXPath)}"); } - // CASE B: Direct continuous mapping connection line link case (No intermediate functoid) else if (conn.Target is SchemaNodeItem targetSchemaItem) { string targetNodeName = targetSchemaItem.XmlSourceNode.Name; - string snippet = FunctoidXsltCompiler.GetXsltSnippet("DirectLink", sourceXPath, targetNodeName); - - xslt.AppendLine($" {snippet}"); + xslt.AppendLine($" {FunctoidXsltCompiler.GetXsltSnippet("DirectLink", sourceXPath, targetNodeName)}"); } } } xslt.AppendLine(" "); xslt.AppendLine(""); - return xslt.ToString(); } - // Helper tool to find whatever control or node feeds into a target capsule's input port - private string TraceInputExpression(object targetControl) - { - foreach (var conn in _mapper.Connections) - { - if (conn.Target == targetControl) - { - if (conn.Source is XmlNode sourceXmlNode) - { - return BuildAbsoluteXPath(sourceXmlNode); - } - else if (conn.Source is BizTalkFunctoidNode parentFunctoid) - { - // RECURSION: Evaluate what is driving the parent functoid first! - string upstreamExpression = TraceInputExpression(parentFunctoid); - string currentTargetName = parentFunctoid.FunctoidName.Replace(" ", "_"); - - // Nest the parent script directly around the upstream value - string rawSnippet = FunctoidXsltCompiler.GetXsltSnippet(parentFunctoid.FunctoidName, "UPSTREAM_PLACEHOLDER", currentTargetName); - - // Strip outer XML tag structures for inline variable cascading evaluation injection - string pureExpression = ExtractInlineXsltExpression(rawSnippet); - return pureExpression.Replace("UPSTREAM_PLACEHOLDER", upstreamExpression); - } - } - } - return "''"; // Fallback empty string if input path breaks - } - - private string ExtractInlineXsltExpression(string xmlSnippet) - { - // Helper to pull 'translate(...)' or 'normalize-space(...)' out of raw tag sets like - int start = xmlSnippet.IndexOf("select=\""); - if (start == -1) return xmlSnippet; - start += 8; - int end = xmlSnippet.IndexOf("\"", start); - return xmlSnippet.Substring(start, end - start); - } - - // HELPER METHOD: Climbs the XML DOM tree recursively to output perfect structural absolute XPaths private string BuildAbsoluteXPath(XmlNode node) { - if (node == null || node.NodeType == XmlNodeType.Document) - return ""; - - // If it's an attribute node, prepend the '@' selector switch character + if (node == null || node.NodeType == XmlNodeType.Document) return ""; if (node.NodeType == XmlNodeType.Attribute) return BuildAbsoluteXPath(((XmlAttribute)node).OwnerElement) + "/@" + node.Name; string parentPath = BuildAbsoluteXPath(node.ParentNode); + return string.IsNullOrEmpty(parentPath) ? node.Name : parentPath + "/" + node.Name; + } - if (string.IsNullOrEmpty(parentPath)) - return node.Name; + #endregion - return parentPath + "/" + node.Name; + // Cleaned up legacy residual functions (trvSource overrides, Hippo wrappers, etc.) + private void rbXml_CheckedChanged(object sender, EventArgs e) { } + private void lbxInputFileList(object sender, EventArgs e) { } + private void btnHippaParse_Click(object sender, EventArgs e) { } + private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { } + private void lblInterchangeCount_TextChanged(object sender, EventArgs e) + { + int fcount = int.Parse(((Label)sender).Text); + btnParse.Enabled = fcount == 1 ? true : false; + } + private void rbHtml_CheckedChanged(object sender, EventArgs e) + { + RadioButton r = (RadioButton)sender; + Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; + Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); + Properties.Settings.Default.Save(); } } -} +} \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 4e6771c9..6f2ee377 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -118,7 +118,7 @@ - Component + UserControl Component diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 935065a9..22c85480 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -123,4 +123,7 @@ 133, 17 + + 133, 17 + \ No newline at end of file From 9a149f1098df3d349ca8227bde55b5e4ac435322 Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 18 May 2026 09:11:13 -0400 Subject: [PATCH 12/22] wip --- X12UtilsFRM/SkiaMapper.cs | 139 ++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 45 deletions(-) diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index 91b6fa70..3f0f62a2 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -12,16 +12,18 @@ namespace X12UtilsFRM { public class SkiaMapper : SKControl { - - private SKPoint _canvasPanOffset = new SKPoint(0, 0); - private Point _lastMousePosition; - private bool _isPanningCanvas = false; // Virtual Drag and Drop Trackers private SchemaNodeItem _draggedVirtualNode = null; private Point _dragStartPoint; - private const int DragThreshold = 5; // Pixels to move before realizing it's a "drag" and not a "click" + private const int DragThreshold = 5; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + // --- NEW: INFINITE FLOATING CANVAS TRACKERS --- + private SKPoint _canvasPanOffset = new SKPoint(0, 0); + private Point _lastMousePosition; + private bool _isPanningCanvas = false; + // ---------------------------------------------- + // Canvas Data Models public List Connections { get; set; } = new List(); public List FlatSchemaRegistry { get; set; } = new List(); @@ -78,7 +80,6 @@ public void RecalculateVirtualLayout() if (height <= 0 || width <= 0) return; - // If layout hasn't been initialized by the form yet, set up default even distribution if (_splitterLeftX == 0 && _splitterRightX == 0) { _splitterLeftX = width / 3f; @@ -136,7 +137,11 @@ private void CheckForLineRightClick(Point clickPt) if (start != SKPoint.Empty && end != SKPoint.Empty) { - if (IsPointNearBezier(skClick, start, end, 8.0f)) + // Factor in panning matrix when analyzing right clicks over lines + SKPoint startPanned = new SKPoint(start.X + _canvasPanOffset.X, start.Y + _canvasPanOffset.Y); + SKPoint endPanned = new SKPoint(end.X + _canvasPanOffset.X, end.Y + _canvasPanOffset.Y); + + if (IsPointNearBezier(skClick, startPanned, endPanned, 8.0f)) { _selectedConnectionForDelete = conn; _lineContextMenu.Show(Cursor.Position); @@ -253,9 +258,18 @@ private void Mapper_MouseDown(object sender, MouseEventArgs e) { _isDraggingRightSplitter = true; } + // MMB or Left Click + Space triggers layout engine canvas panning shifts + else if (e.Button == MouseButtons.Middle || (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Space)) + { + if (_centerCanvasRegion.Bounds.Contains(e.X, e.Y)) + { + _isPanningCanvas = true; + _lastMousePosition = e.Location; + this.Cursor = Cursors.NoMove2D; + } + } else { - // Check if hitting a schema item node row var activeRegistry = _leftSchemaRegion.Bounds.Contains(e.X, e.Y) ? FlatSchemaRegistry : FlatTargetSchemaRegistry; SchemaNodeItem clickedNode = null; @@ -278,7 +292,32 @@ private void Mapper_MouseDown(object sender, MouseEventArgs e) private void Mapper_MouseMove(object sender, MouseEventArgs e) { - // 1. Handle Virtual Node Drag Initiation + // 1. Handle Infinite Canvas Panning Translations + if (_isPanningCanvas) + { + float deltaX = e.X - _lastMousePosition.X; + float deltaY = e.Y - _lastMousePosition.Y; + _lastMousePosition = e.Location; + + _canvasPanOffset = new SKPoint(_canvasPanOffset.X + deltaX, _canvasPanOffset.Y + deltaY); + + // Dynamically translate all physical Functoid custom controls resting in the parent panel container + if (this.Parent != null) + { + foreach (Control ctrl in this.Parent.Controls) + { + if (ctrl != this && !(ctrl.Name.Contains("Toolbox"))) + { + ctrl.Location = new Point(ctrl.Location.X + (int)deltaX, ctrl.Location.Y + (int)deltaY); + } + } + } + + this.Invalidate(); + return; + } + + // 2. Handle Virtual Node Drag Initiation if (_draggedVirtualNode != null && e.Button == MouseButtons.Left) { int deltaX = Math.Abs(e.X - _dragStartPoint.X); @@ -291,13 +330,13 @@ private void Mapper_MouseMove(object sender, MouseEventArgs e) Tag = _draggedVirtualNode.XmlSourceNode }; - _draggedVirtualNode = null; // Clear state before block loop + _draggedVirtualNode = null; this.DoDragDrop(dragPayload, DragDropEffects.Copy | DragDropEffects.Link); return; } } - // 2. Handle Splitter Dragging Changes + // 3. Handle Splitter Dragging Changes if (_isDraggingLeftSplitter) { _splitterLeftX = Clamp(e.X, 100, _splitterRightX - 100); @@ -311,7 +350,7 @@ private void Mapper_MouseMove(object sender, MouseEventArgs e) this.Invalidate(); } - // 3. Splitter Cursor Overrides + // 4. Splitter Cursor Overrides if (Math.Abs(e.X - _splitterLeftX) <= SplitterHitWidth / 2 || Math.Abs(e.X - _splitterRightX) <= SplitterHitWidth / 2) { @@ -325,10 +364,16 @@ private void Mapper_MouseMove(object sender, MouseEventArgs e) private void Mapper_MouseUp(object sender, MouseEventArgs e) { + if (_isPanningCanvas) + { + _isPanningCanvas = false; + this.Cursor = Cursors.Default; + return; + } + _isDraggingLeftSplitter = false; _isDraggingRightSplitter = false; - // Click fallback: Toggle expansion if (_draggedVirtualNode != null) { _draggedVirtualNode.IsExpanded = !_draggedVirtualNode.IsExpanded; @@ -359,6 +404,14 @@ protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) private void OnPaintSurfaceEngine(SKCanvas canvas) { + canvas.Save(); + + // Clip rendering specifically to avoid connection lines drawing on top of side tree bars + canvas.ClipRect(_centerCanvasRegion.Bounds); + + // Shift drawing canvas alignment to follow infinite panning coordinates matrix + canvas.Translate(_canvasPanOffset.X, _canvasPanOffset.Y); + using (var paint = new SKPaint()) using (var textPaint = new SKPaint()) { @@ -375,7 +428,6 @@ private void OnPaintSurfaceEngine(SKCanvas canvas) foreach (var conn in Connections) { - // Look up internal schema text records by matching their XmlNodes directly object visualSource = conn.Source; object visualTarget = conn.Target; @@ -391,58 +443,59 @@ private void OnPaintSurfaceEngine(SKCanvas canvas) if (matchingTarget != null) visualTarget = matchingTarget; } + // Subtract the pan offset when reading control coordinates to avoid double-offset drift var start = GetControlPoint(visualSource, isSource: true); var end = GetControlPoint(visualTarget, isSource: false); + if (visualSource is SchemaNodeItem) + { + start.X -= _canvasPanOffset.X; + start.Y -= _canvasPanOffset.Y; + } + if (visualTarget is SchemaNodeItem) + { + end.X -= _canvasPanOffset.X; + end.Y -= _canvasPanOffset.Y; + } + if (start != SKPoint.Empty && end != SKPoint.Empty) { - string sourceLabelText = ""; - if (visualSource is SchemaNodeItem srcSni) - sourceLabelText = srcSni.XmlSourceNode.Name; - else if (visualSource is BizTalkFunctoidNode srcFunctoid) - sourceLabelText = srcFunctoid.FunctoidName; - else if (conn.Source is XmlNode srcXmlNode) - sourceLabelText = srcXmlNode.Name; - - string targetLabelText = ""; - if (visualTarget is SchemaNodeItem tgtSni) - targetLabelText = tgtSni.XmlSourceNode.Name; - else if (visualTarget is BizTalkFunctoidNode tgtFunctoid) - targetLabelText = tgtFunctoid.FunctoidName; - else if (conn.Target is XmlNode tgtXmlNode) - targetLabelText = tgtXmlNode.Name; + // 1. Extract raw label text safely based on underlying node types + string sourceLabelText = visualSource is SchemaNodeItem srcSni ? srcSni.XmlSourceNode.Name : + visualSource is BizTalkFunctoidNode srcFunctoid ? srcFunctoid.FunctoidName : ""; + string targetLabelText = visualTarget is SchemaNodeItem tgtSni ? tgtSni.XmlSourceNode.Name : + visualTarget is BizTalkFunctoidNode tgtFunctoid ? tgtFunctoid.FunctoidName : ""; + + // 2. Identify contextual types for badge rules bool isSourceSchema = (visualSource is SchemaNodeItem) || (conn.Source is XmlNode); - bool isTargetSchema = (visualTarget is SchemaNodeItem) || (conn.Target is XmlNode); bool isSourceFunctoid = visualSource is BizTalkFunctoidNode; bool isTargetFunctoid = visualTarget is BizTalkFunctoidNode; - if (isSourceFunctoid && isTargetFunctoid) - { - sourceLabelText = string.Empty; - targetLabelText = string.Empty; - } - else if (isSourceSchema && isTargetFunctoid) + // --- LABEL VISIBILITY ENGINE --- + if (isSourceSchema) { + // Rule 1: Lines dragging out of the left source schema drop the second target label completely targetLabelText = string.Empty; } - else if (isSourceFunctoid && isTargetSchema) - { - sourceLabelText = string.Empty; - } - else if (isSourceSchema && isTargetSchema) + else if (isSourceFunctoid && isTargetFunctoid) { + // Rule 2: Inter-functoid jumps suppress both badges to prevent center canvas clutter sourceLabelText = string.Empty; + targetLabelText = string.Empty; } else if (!string.IsNullOrEmpty(sourceLabelText) && sourceLabelText == targetLabelText) { + // Rule 3: Deduplicate identical label text instances if any catch-all conditions clip names sourceLabelText = string.Empty; } + // Render the final Bezier vector with the calculated badge flags DrawBezierLine(canvas, paint, textPaint, start, end, sourceLabelText, targetLabelText); } } } + canvas.Restore(); } private void DrawBezierLine(SKCanvas canvas, SKPaint paint, SKPaint textPaint, SKPoint start, SKPoint end, string sourceLabel, string targetLabel) @@ -505,7 +558,6 @@ private SKPoint GetControlPoint(object visualElement, bool isSource) { if (visualElement == null) return SKPoint.Empty; - // SCENARIO A: The element is a virtual schema node item row if (visualElement is SchemaNodeItem sni) { if (sni.Tag is SKRect rect) @@ -517,7 +569,6 @@ private SKPoint GetControlPoint(object visualElement, bool isSource) return SKPoint.Empty; } - // SCENARIO B: The element is a physical WinForms control if (visualElement is Control ctrl) { if (ctrl.Parent == null) return SKPoint.Empty; @@ -547,14 +598,12 @@ private float Clamp(float value, float min, float max) return value; } } - public class MappingConnection { public object Source { get; set; } public object Target { get; set; } public SKColor LineColor { get; set; } = SKColors.DodgerBlue; } - public class VirtualRegion { public string Name { get; set; } From ff0d3f9b1837ae60a7812765038535ad3dd26e3d Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 18 May 2026 10:16:23 -0400 Subject: [PATCH 13/22] wip --- X12UtilsFRM/SkiaMapper.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index 3f0f62a2..bd7c210e 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -469,15 +469,21 @@ private void OnPaintSurfaceEngine(SKCanvas canvas) // 2. Identify contextual types for badge rules bool isSourceSchema = (visualSource is SchemaNodeItem) || (conn.Source is XmlNode); + bool isTargetSchema = (visualTarget is SchemaNodeItem) || (conn.Target is XmlNode); bool isSourceFunctoid = visualSource is BizTalkFunctoidNode; bool isTargetFunctoid = visualTarget is BizTalkFunctoidNode; - // --- LABEL VISIBILITY ENGINE --- + // --- REVISED LABEL VISIBILITY ENGINE --- if (isSourceSchema) { - // Rule 1: Lines dragging out of the left source schema drop the second target label completely + // Rule 1: Lines dragging out of the left source schema drop the target label completely targetLabelText = string.Empty; } + else if (isTargetSchema) + { + // Rule 4: Lines landing on the right target schema (reverse drag drop) drop the first source label completely + sourceLabelText = string.Empty; + } else if (isSourceFunctoid && isTargetFunctoid) { // Rule 2: Inter-functoid jumps suppress both badges to prevent center canvas clutter @@ -486,7 +492,7 @@ private void OnPaintSurfaceEngine(SKCanvas canvas) } else if (!string.IsNullOrEmpty(sourceLabelText) && sourceLabelText == targetLabelText) { - // Rule 3: Deduplicate identical label text instances if any catch-all conditions clip names + // Rule 3: Deduplicate identical label text instances if names match exactly sourceLabelText = string.Empty; } From caa942893c45c2aaf0c56865dc76dfa0da7fd7e8 Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 18 May 2026 10:20:35 -0400 Subject: [PATCH 14/22] wip --- X12UtilsFRM/SkiaMapper.cs | 48 ++++++++++++--------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index bd7c210e..0092809d 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -18,11 +18,10 @@ public class SkiaMapper : SKControl private const int DragThreshold = 5; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - // --- NEW: INFINITE FLOATING CANVAS TRACKERS --- + // --- INFINITE FLOATING CANVAS TRACKERS --- private SKPoint _canvasPanOffset = new SKPoint(0, 0); private Point _lastMousePosition; private bool _isPanningCanvas = false; - // ---------------------------------------------- // Canvas Data Models public List Connections { get; set; } = new List(); @@ -137,11 +136,7 @@ private void CheckForLineRightClick(Point clickPt) if (start != SKPoint.Empty && end != SKPoint.Empty) { - // Factor in panning matrix when analyzing right clicks over lines - SKPoint startPanned = new SKPoint(start.X + _canvasPanOffset.X, start.Y + _canvasPanOffset.Y); - SKPoint endPanned = new SKPoint(end.X + _canvasPanOffset.X, end.Y + _canvasPanOffset.Y); - - if (IsPointNearBezier(skClick, startPanned, endPanned, 8.0f)) + if (IsPointNearBezier(skClick, start, end, 8.0f)) { _selectedConnectionForDelete = conn; _lineContextMenu.Show(Cursor.Position); @@ -258,7 +253,7 @@ private void Mapper_MouseDown(object sender, MouseEventArgs e) { _isDraggingRightSplitter = true; } - // MMB or Left Click + Space triggers layout engine canvas panning shifts + // MMB or Left Click + Space triggers canvas panning else if (e.Button == MouseButtons.Middle || (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Space)) { if (_centerCanvasRegion.Bounds.Contains(e.X, e.Y)) @@ -292,7 +287,7 @@ private void Mapper_MouseDown(object sender, MouseEventArgs e) private void Mapper_MouseMove(object sender, MouseEventArgs e) { - // 1. Handle Infinite Canvas Panning Translations + // 1. Handle Infinite Canvas Panning Transformations if (_isPanningCanvas) { float deltaX = e.X - _lastMousePosition.X; @@ -301,7 +296,7 @@ private void Mapper_MouseMove(object sender, MouseEventArgs e) _canvasPanOffset = new SKPoint(_canvasPanOffset.X + deltaX, _canvasPanOffset.Y + deltaY); - // Dynamically translate all physical Functoid custom controls resting in the parent panel container + // Dynamically translate all physical Functoid custom controls if (this.Parent != null) { foreach (Control ctrl in this.Parent.Controls) @@ -406,11 +401,12 @@ private void OnPaintSurfaceEngine(SKCanvas canvas) { canvas.Save(); - // Clip rendering specifically to avoid connection lines drawing on top of side tree bars + // Clip rendering to the center canvas area canvas.ClipRect(_centerCanvasRegion.Bounds); - // Shift drawing canvas alignment to follow infinite panning coordinates matrix - canvas.Translate(_canvasPanOffset.X, _canvasPanOffset.Y); + // --- FIX: REMOVED canvas.Translate HERE --- + // Panning physically relocates the WinForms controls, so our lines should + // be drawn directly in standard coordinate space to prevent double-offset skewing! using (var paint = new SKPaint()) using (var textPaint = new SKPaint()) @@ -443,60 +439,43 @@ private void OnPaintSurfaceEngine(SKCanvas canvas) if (matchingTarget != null) visualTarget = matchingTarget; } - // Subtract the pan offset when reading control coordinates to avoid double-offset drift + // Look up coordinates (returns absolute positions relative to the canvas control) var start = GetControlPoint(visualSource, isSource: true); var end = GetControlPoint(visualTarget, isSource: false); - if (visualSource is SchemaNodeItem) - { - start.X -= _canvasPanOffset.X; - start.Y -= _canvasPanOffset.Y; - } - if (visualTarget is SchemaNodeItem) - { - end.X -= _canvasPanOffset.X; - end.Y -= _canvasPanOffset.Y; - } - if (start != SKPoint.Empty && end != SKPoint.Empty) { - // 1. Extract raw label text safely based on underlying node types + // Extract label texts based on type configurations string sourceLabelText = visualSource is SchemaNodeItem srcSni ? srcSni.XmlSourceNode.Name : visualSource is BizTalkFunctoidNode srcFunctoid ? srcFunctoid.FunctoidName : ""; string targetLabelText = visualTarget is SchemaNodeItem tgtSni ? tgtSni.XmlSourceNode.Name : visualTarget is BizTalkFunctoidNode tgtFunctoid ? tgtFunctoid.FunctoidName : ""; - // 2. Identify contextual types for badge rules bool isSourceSchema = (visualSource is SchemaNodeItem) || (conn.Source is XmlNode); bool isTargetSchema = (visualTarget is SchemaNodeItem) || (conn.Target is XmlNode); bool isSourceFunctoid = visualSource is BizTalkFunctoidNode; bool isTargetFunctoid = visualTarget is BizTalkFunctoidNode; - // --- REVISED LABEL VISIBILITY ENGINE --- + // Apply visibility filters if (isSourceSchema) { - // Rule 1: Lines dragging out of the left source schema drop the target label completely targetLabelText = string.Empty; } else if (isTargetSchema) { - // Rule 4: Lines landing on the right target schema (reverse drag drop) drop the first source label completely sourceLabelText = string.Empty; } else if (isSourceFunctoid && isTargetFunctoid) { - // Rule 2: Inter-functoid jumps suppress both badges to prevent center canvas clutter sourceLabelText = string.Empty; targetLabelText = string.Empty; } else if (!string.IsNullOrEmpty(sourceLabelText) && sourceLabelText == targetLabelText) { - // Rule 3: Deduplicate identical label text instances if names match exactly sourceLabelText = string.Empty; } - // Render the final Bezier vector with the calculated badge flags DrawBezierLine(canvas, paint, textPaint, start, end, sourceLabelText, targetLabelText); } } @@ -583,6 +562,7 @@ private SKPoint GetControlPoint(object visualElement, bool isSource) int targetX = isSource ? ctrl.Width : 0; Point localAnchorPt = new Point(targetX, ctrl.Height / 2); + // Convert position straight into local mapper canvas coordinate map space Point screenPt = ctrl.PointToScreen(localAnchorPt); Point localPt = this.PointToClient(screenPt); @@ -604,12 +584,14 @@ private float Clamp(float value, float min, float max) return value; } } + public class MappingConnection { public object Source { get; set; } public object Target { get; set; } public SKColor LineColor { get; set; } = SKColors.DodgerBlue; } + public class VirtualRegion { public string Name { get; set; } From c95d894093b085321a7f38b465319e78a22ac129 Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 18 May 2026 10:36:34 -0400 Subject: [PATCH 15/22] wip --- X12UtilsFRM/X12UtilsFRM.cs | 82 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 4c48040d..fbafbf6a 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -47,6 +47,10 @@ public partial class X12UtilsFRM : Form private bool _isDraggingFunctoid = false; private Point _dragStartMousePos; private Point _dragStartControlPos; + private Form _detachedWorkspaceWindow = null; + private Point _originalPanelLocation; + private Size _originalPanelSize; + private AnchorStyles _originalPanelAnchor; List interchanges = null; ToolTip tt = null; @@ -192,6 +196,84 @@ private void ToggleToolbox_Click(object sender, EventArgs e) #region Drag and Drop Handling Logic + + private void ToggleWorkspaceDetachment() + { + // If the workspace isn't detached yet, pop it out into its own separate OS window + if (_detachedWorkspaceWindow == null) + { + // 1. Cache the original layout positions so we can restore them cleanly later + _originalPanelLocation = pnlFunctoids.Location; + _originalPanelSize = pnlFunctoids.Size; + _originalPanelAnchor = pnlFunctoids.Anchor; + + // 2. Instantiate a brand new tool window container frame + _detachedWorkspaceWindow = new Form + { + Text = "X12 Schema Mapping Studio - Detached Workspace", + Size = new Size(1200, 800), + StartPosition = FormStartPosition.CenterScreen, + FormBorderStyle = FormBorderStyle.SizableToolWindow, // Gives it a clean tool panel border + MinimizeBox = false + }; + + // Ensure that if the developer clicks the "X" button on the floating window, + // it intercepts destruction and re-docks itself back to the parent form safely. + _detachedWorkspaceWindow.FormClosing += (s, e) => + { + if (e.CloseReason == CloseReason.UserClosing) + { + e.Cancel = true; // Abort form disposal + ReDockWorkspaceToMainForm(); + } + }; + + // 3. Tear the workspace out of the primary main form control tree + this.Controls.Remove(pnlFunctoids); + + // 4. Mount it into the detached window container frame + _detachedWorkspaceWindow.Controls.Add(pnlFunctoids); + pnlFunctoids.Dock = DockStyle.Fill; // Let it expand to the whole size of the window + + // 5. Display the window to the user (passing 'this' keeps it grouped on top of the app) + _detachedWorkspaceWindow.Show(this); + + // 6. Force Skia to recalculate boundaries based on the new dimensions + _mapper.RecalculateVirtualLayout(); + _mapper.Invalidate(); + } + else + { + // If it's already detached, call the reverse re-dock method + ReDockWorkspaceToMainForm(); + } + } + + private void ReDockWorkspaceToMainForm() + { + if (_detachedWorkspaceWindow != null) + { + // 1. Strip the panel out of the detached floating frame container + _detachedWorkspaceWindow.Controls.Remove(pnlFunctoids); + + // 2. Destroy the temporary floating form window frame manager safely + _detachedWorkspaceWindow.Dispose(); + _detachedWorkspaceWindow = null; + + // 3. Restore the panel control back into its original spot on the main app form + pnlFunctoids.Dock = DockStyle.None; + pnlFunctoids.Location = _originalPanelLocation; + pnlFunctoids.Size = _originalPanelSize; + pnlFunctoids.Anchor = _originalPanelAnchor; + + this.Controls.Add(pnlFunctoids); + pnlFunctoids.BringToFront(); + + // 4. Refresh the virtual split positions + _mapper.RecalculateVirtualLayout(); + _mapper.Invalidate(); + } + } private void MakeControlDraggable(Control masterControl) { AttachDragEvents(masterControl, masterControl); From 105a27328b8dc5e8c56208e282bfb4ef2679767d Mon Sep 17 00:00:00 2001 From: apeiris Date: Mon, 18 May 2026 10:53:46 -0400 Subject: [PATCH 16/22] wip --- X12UtilsFRM/X12UtilsFRM.cs | 70 ++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index fbafbf6a..248f282d 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -44,6 +44,10 @@ public partial class X12UtilsFRM : Form private const int ToolboxWidth = 245; // Draggable capsule tracking properties + + private bool _isDraggingToolbox = false; + private Point _toolboxDragStartMousePos; + private Point _toolboxDragStartPanelPos; private bool _isDraggingFunctoid = false; private Point _dragStartMousePos; private Point _dragStartControlPos; @@ -98,16 +102,19 @@ private static void Log(String s, [CallerMemberName] string cn = "", [CallerLine private void InitializeToolbox() { + // 1. Create the main wrapper panel. Remove Anchor properties so it can move freely. pnlToolboxWrapper = new Panel { Width = ToolboxWidth + 20, - Location = new Point(pnlFunctoids.Width - (ToolboxWidth + 20), 0), - Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right, - BackColor = Color.Transparent + Height = pnlFunctoids.Height - 40, // Give it a nice padding from top/bottom + Location = new Point(pnlFunctoids.Width - (ToolboxWidth + 40), 20), + BackColor = Color.FromArgb(235, 240, 250), // Give it a solid background so canvas lines don't bleed through + BorderStyle = BorderStyle.FixedSingle }; pnlFunctoids.Controls.Add(pnlToolboxWrapper); pnlToolboxWrapper.BringToFront(); + // 2. Create the toggle button on the left edge of the toolbox wrapper btnToolboxToggle = new Button { Text = "»", @@ -115,7 +122,7 @@ private void InitializeToolbox() Width = 20, Dock = DockStyle.Left, FlatStyle = FlatStyle.Popup, - BackColor = Color.FromArgb(220, 225, 235), + BackColor = Color.FromArgb(210, 215, 225), ForeColor = Color.FromArgb(50, 50, 80), Cursor = Cursors.Hand }; @@ -123,6 +130,7 @@ private void InitializeToolbox() btnToolboxToggle.Click += ToggleToolbox_Click; pnlToolboxWrapper.Controls.Add(btnToolboxToggle); + // 3. Create the container where categories flow vertically pnlToolboxCategoriesContainer = new FlowLayoutPanel { Dock = DockStyle.Fill, @@ -130,11 +138,16 @@ private void InitializeToolbox() FlowDirection = FlowDirection.TopDown, WrapContents = false, AutoScroll = true, - Padding = new Padding(20, 20, 20, 20) + Padding = new Padding(10, 10, 10, 10) }; pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); pnlToolboxCategoriesContainer.BringToFront(); + // --- NEW: WIRE UP DRAG-TO-MOVE EVENTS --- + // Let the user drag the toolbox by holding and dragging the toggle button assembly strip + AttachToolboxDragEvents(btnToolboxToggle); + // ---------------------------------------- + var stringTools = new List { "Concatenate", "String Left", "String Right", "Trim", "Uppercase", "Lowercase" }; var mathTools = new List { "Add", "Subtract", "Multiply", "Divide", "Modulus", "Absolute" }; var dateTools = new List { "Current Date", "Date Format", "Add Days", "Date Diff" }; @@ -148,7 +161,50 @@ private void InitializeToolbox() RenderToolboxLayout(); } + private void AttachToolboxDragEvents(Control dragHandle) + { + dragHandle.MouseDown += (sender, e) => + { + if (e.Button == MouseButtons.Left) + { + _isDraggingToolbox = true; + _toolboxDragStartMousePos = Cursor.Position; + _toolboxDragStartPanelPos = pnlToolboxWrapper.Location; + pnlToolboxWrapper.BringToFront(); + } + }; + + dragHandle.MouseMove += (sender, e) => + { + if (_isDraggingToolbox) + { + int deltaX = Cursor.Position.X - _toolboxDragStartMousePos.X; + int deltaY = Cursor.Position.Y - _toolboxDragStartMousePos.Y; + + // Compute the new target position + int newX = _toolboxDragStartPanelPos.X + deltaX; + int newY = _toolboxDragStartPanelPos.Y + deltaY; + // Optional: Clamp the toolbox so it can't be dragged completely off screen edges + if (pnlFunctoids != null) + { + newX = Math.Max(0, Math.Min(newX, pnlFunctoids.Width - pnlToolboxWrapper.Width)); + newY = Math.Max(0, Math.Min(newY, pnlFunctoids.Height - 30)); + } + + pnlToolboxWrapper.Location = new Point(newX, newY); + _mapper.Invalidate(); // Refresh lines to redraw cleanly around it + } + }; + + dragHandle.MouseUp += (sender, e) => + { + if (e.Button == MouseButtons.Left) + { + _isDraggingToolbox = false; + } + }; + } private void RenderToolboxLayout() { if (pnlToolboxCategoriesContainer == null) return; @@ -174,17 +230,17 @@ private void ToggleToolbox_Click(object sender, EventArgs e) if (_isToolboxExpanded) { + // Expand outward keeping its current X coordinate placement intact pnlToolboxWrapper.Width = ToolboxWidth + 20; - pnlToolboxWrapper.Location = new Point(pnlFunctoids.Width - pnlToolboxWrapper.Width, 0); pnlToolboxCategoriesContainer.Visible = true; btnToolboxToggle.Text = "»"; RenderToolboxLayout(); } else { + // Collapse down to just show the little grab handle tab bar pnlToolboxCategoriesContainer.Visible = false; pnlToolboxWrapper.Width = btnToolboxToggle.Width; - pnlToolboxWrapper.Location = new Point(pnlFunctoids.Width - pnlToolboxWrapper.Width, 0); btnToolboxToggle.Text = "«"; } From 79bcc051075d0c9ea0ffbeb3b6c8e60b39157bc0 Mon Sep 17 00:00:00 2001 From: apeiris Date: Wed, 20 May 2026 11:17:47 -0400 Subject: [PATCH 17/22] UI revisions --- X12UtilsFRM/InstitutionalClaim5010.xslt | 52 +++ X12UtilsFRM/SkiaMapper.cs | 44 +++ X12UtilsFRM/X12UtilsFRM.Designer.cs | 142 +++++++-- X12UtilsFRM/X12UtilsFRM.cs | 401 ++++++++++++++++++------ X12UtilsFRM/X12UtilsFRM.csproj | 2 + X12UtilsFRM/X12UtilsFRM.resx | 4 +- X12UtilsFRM/XsltMapGenerator.cs | 243 ++++++++++++++ src/X12.Parsing/X12StreamReader.cs | 4 + 8 files changed, 782 insertions(+), 110 deletions(-) create mode 100644 X12UtilsFRM/InstitutionalClaim5010.xslt create mode 100644 X12UtilsFRM/XsltMapGenerator.cs diff --git a/X12UtilsFRM/InstitutionalClaim5010.xslt b/X12UtilsFRM/InstitutionalClaim5010.xslt new file mode 100644 index 00000000..a6b534ed --- /dev/null +++ b/X12UtilsFRM/InstitutionalClaim5010.xslt @@ -0,0 +1,52 @@ + + + + + + + + + + + type="text/xsl" href=" + + " + + + + + + + + + + + + + + + + + + + + + + + diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index 0092809d..c5c3ac87 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -583,6 +583,48 @@ private float Clamp(float value, float min, float max) if (value > max) return max; return value; } + public static void DrawToolboxIcon(SKCanvas canvas, SKPoint position, float size, SKColor color) + { + using (var paint = new SKPaint()) + { + paint.Style = SKPaintStyle.Stroke; + paint.StrokeWidth = size * 0.1f; + paint.Color = color; + paint.IsAntialias = true; + paint.StrokeCap = SKStrokeCap.Round; + paint.StrokeJoin = SKStrokeJoin.Round; + + // 1. Draw main toolbox body container box + float boxWidth = size; + float boxHeight = size * 0.7f; + var bodyRect = new SKRect( + position.X - boxWidth / 2f, + position.Y - boxHeight / 2f + (size * 0.1f), + position.X + boxWidth / 2f, + position.Y + boxHeight / 2f + (size * 0.1f) + ); + canvas.DrawRoundRect(bodyRect, size * 0.1f, size * 0.1f, paint); + + // 2. Draw top handle attachment loop + using (var handlePath = new SKPath()) + { + handlePath.MoveTo(position.X - size * 0.25f, bodyRect.Top); + handlePath.LineTo(position.X - size * 0.25f, bodyRect.Top - size * 0.2f); + handlePath.LineTo(position.X + size * 0.25f, bodyRect.Top - size * 0.2f); + handlePath.LineTo(position.X + size * 0.25f, bodyRect.Top); + canvas.DrawPath(handlePath, paint); + } + + // 3. Draw central latch point accent line + canvas.DrawLine( + position.X, + bodyRect.Top, + position.X, + bodyRect.Top + (boxHeight * 0.3f), + paint + ); + } + } } public class MappingConnection @@ -599,4 +641,6 @@ public class VirtualRegion public float ScrollOffset { get; set; } = 0; public float MaxScrollHeight { get; set; } = 0; } + + } \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 036e90c8..7bafc7dd 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -33,6 +33,7 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.chkTargetSchema = new System.Windows.Forms.CheckBox(); this.lbxTargetSchema = new System.Windows.Forms.ListBox(); this.chkBrowse = new System.Windows.Forms.CheckBox(); this.btnMap = new System.Windows.Forms.Button(); @@ -56,9 +57,15 @@ private void InitializeComponent() this.FormLocations = new System.Windows.Forms.TabPage(); this.rtLocations = new System.Windows.Forms.RichTextBox(); this.tbpMap = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.pnlFunctoids = new System.Windows.Forms.Panel(); + this.btnGenerateXsltFromCanvas = new System.Windows.Forms.Button(); this.trvTarget = new System.Windows.Forms.TreeView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.label2 = new System.Windows.Forms.Label(); + this.lblSaveAs = new System.Windows.Forms.Label(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -69,15 +76,17 @@ private void InitializeComponent() this.browser.SuspendLayout(); this.FormLocations.SuspendLayout(); this.tbpMap.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); this.SuspendLayout(); // // statusStrip1 // this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.statusStrip1.Location = new System.Drawing.Point(0, 768); + this.statusStrip1.Location = new System.Drawing.Point(0, 749); this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); - this.statusStrip1.Size = new System.Drawing.Size(1298, 22); + this.statusStrip1.Size = new System.Drawing.Size(1545, 22); this.statusStrip1.TabIndex = 0; this.statusStrip1.Text = "statusStrip1"; // @@ -92,7 +101,7 @@ private void InitializeComponent() this.tabControl1.Margin = new System.Windows.Forms.Padding(2); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1298, 768); + this.tabControl1.Size = new System.Drawing.Size(1545, 749); this.tabControl1.TabIndex = 1; this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); // @@ -103,7 +112,7 @@ private void InitializeComponent() this.parse.Margin = new System.Windows.Forms.Padding(2); this.parse.Name = "parse"; this.parse.Padding = new System.Windows.Forms.Padding(2); - this.parse.Size = new System.Drawing.Size(1290, 742); + this.parse.Size = new System.Drawing.Size(1537, 723); this.parse.TabIndex = 0; this.parse.Text = "Parse"; this.parse.UseVisualStyleBackColor = true; @@ -118,6 +127,7 @@ private void InitializeComponent() // // splitContainer1.Panel1 // + this.splitContainer1.Panel1.Controls.Add(this.chkTargetSchema); this.splitContainer1.Panel1.Controls.Add(this.lbxTargetSchema); this.splitContainer1.Panel1.Controls.Add(this.chkBrowse); this.splitContainer1.Panel1.Controls.Add(this.btnMap); @@ -137,11 +147,23 @@ private void InitializeComponent() // this.splitContainer1.Panel2.Controls.Add(this.rtLog); this.splitContainer1.Panel2.Controls.Add(this.rtxInterchangeFile); - this.splitContainer1.Size = new System.Drawing.Size(1286, 738); + this.splitContainer1.Size = new System.Drawing.Size(1533, 719); this.splitContainer1.SplitterDistance = 363; this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // + // chkTargetSchema + // + this.chkTargetSchema.AutoSize = true; + this.chkTargetSchema.Checked = global::X12UtilsFRM.Properties.Settings.Default.BrowseWhenSelected; + this.chkTargetSchema.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "BrowseWhenSelected", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.chkTargetSchema.Location = new System.Drawing.Point(5, 435); + this.chkTargetSchema.Name = "chkTargetSchema"; + this.chkTargetSchema.Size = new System.Drawing.Size(127, 17); + this.chkTargetSchema.TabIndex = 14; + this.chkTargetSchema.Text = "Brows when selected"; + this.chkTargetSchema.UseVisualStyleBackColor = true; + // // lbxTargetSchema // this.lbxTargetSchema.FormattingEnabled = true; @@ -150,6 +172,7 @@ private void InitializeComponent() this.lbxTargetSchema.Name = "lbxTargetSchema"; this.lbxTargetSchema.Size = new System.Drawing.Size(356, 147); this.lbxTargetSchema.TabIndex = 13; + this.lbxTargetSchema.SelectedIndexChanged += new System.EventHandler(this.lbxfileList_SelectedIndexChanged); // // chkBrowse // @@ -337,7 +360,7 @@ private void InitializeComponent() this.lbxInfileList.Name = "lbxInfileList"; this.lbxInfileList.Size = new System.Drawing.Size(356, 121); this.lbxInfileList.TabIndex = 0; - this.lbxInfileList.SelectedIndexChanged += new System.EventHandler(this.lbxInputFileList); + this.lbxInfileList.SelectedIndexChanged += new System.EventHandler(this.lbxfileList_SelectedIndexChanged); // // rtLog // @@ -347,7 +370,7 @@ private void InitializeComponent() this.rtLog.ForeColor = System.Drawing.Color.Lime; this.rtLog.Location = new System.Drawing.Point(0, 0); this.rtLog.Name = "rtLog"; - this.rtLog.Size = new System.Drawing.Size(920, 738); + this.rtLog.Size = new System.Drawing.Size(1167, 719); this.rtLog.TabIndex = 1; this.rtLog.Text = "aaaa"; // @@ -362,12 +385,12 @@ private void InitializeComponent() // // browser // - this.browser.Controls.Add(this.webBrowser1); + this.browser.Controls.Add(this.tableLayoutPanel2); this.browser.Location = new System.Drawing.Point(4, 22); this.browser.Margin = new System.Windows.Forms.Padding(2); this.browser.Name = "browser"; this.browser.Padding = new System.Windows.Forms.Padding(2); - this.browser.Size = new System.Drawing.Size(1290, 742); + this.browser.Size = new System.Drawing.Size(1537, 723); this.browser.TabIndex = 1; this.browser.Text = "Browser"; this.browser.UseVisualStyleBackColor = true; @@ -375,12 +398,13 @@ private void InitializeComponent() // webBrowser1 // this.webBrowser1.AllowWebBrowserDrop = false; + this.tableLayoutPanel2.SetColumnSpan(this.webBrowser1, 2); this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; - this.webBrowser1.Location = new System.Drawing.Point(2, 2); + this.webBrowser1.Location = new System.Drawing.Point(2, 27); this.webBrowser1.Margin = new System.Windows.Forms.Padding(2); this.webBrowser1.MinimumSize = new System.Drawing.Size(15, 16); this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(1286, 738); + this.webBrowser1.Size = new System.Drawing.Size(1529, 670); this.webBrowser1.TabIndex = 0; // // FormLocations @@ -389,7 +413,7 @@ private void InitializeComponent() this.FormLocations.Location = new System.Drawing.Point(4, 22); this.FormLocations.Name = "FormLocations"; this.FormLocations.Padding = new System.Windows.Forms.Padding(3); - this.FormLocations.Size = new System.Drawing.Size(1290, 742); + this.FormLocations.Size = new System.Drawing.Size(1537, 723); this.FormLocations.TabIndex = 2; this.FormLocations.Text = "Form locations"; this.FormLocations.UseVisualStyleBackColor = true; @@ -402,30 +426,55 @@ private void InitializeComponent() this.rtLocations.ForeColor = System.Drawing.Color.Lime; this.rtLocations.Location = new System.Drawing.Point(3, 3); this.rtLocations.Name = "rtLocations"; - this.rtLocations.Size = new System.Drawing.Size(1284, 736); + this.rtLocations.Size = new System.Drawing.Size(1531, 717); this.rtLocations.TabIndex = 2; this.rtLocations.Text = "aaaa"; // // tbpMap // - this.tbpMap.Controls.Add(this.pnlFunctoids); + this.tbpMap.Controls.Add(this.tableLayoutPanel1); this.tbpMap.Location = new System.Drawing.Point(4, 22); this.tbpMap.Name = "tbpMap"; - this.tbpMap.Size = new System.Drawing.Size(1290, 742); + this.tbpMap.Size = new System.Drawing.Size(1537, 723); this.tbpMap.TabIndex = 3; this.tbpMap.Text = "Mapper"; this.tbpMap.UseVisualStyleBackColor = true; // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.pnlFunctoids, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.btnGenerateXsltFromCanvas, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(1537, 723); + this.tableLayoutPanel1.TabIndex = 1; + // // pnlFunctoids // this.pnlFunctoids.Dock = System.Windows.Forms.DockStyle.Fill; - this.pnlFunctoids.Location = new System.Drawing.Point(0, 0); + this.pnlFunctoids.Location = new System.Drawing.Point(3, 3); this.pnlFunctoids.Name = "pnlFunctoids"; - this.pnlFunctoids.Size = new System.Drawing.Size(1290, 742); + this.pnlFunctoids.Size = new System.Drawing.Size(1531, 682); this.pnlFunctoids.TabIndex = 0; this.pnlFunctoids.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragDrop); this.pnlFunctoids.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragEnter); // + // btnGenerateXsltFromCanvas + // + this.btnGenerateXsltFromCanvas.Location = new System.Drawing.Point(3, 691); + this.btnGenerateXsltFromCanvas.Name = "btnGenerateXsltFromCanvas"; + this.btnGenerateXsltFromCanvas.Size = new System.Drawing.Size(97, 29); + this.btnGenerateXsltFromCanvas.TabIndex = 1; + this.btnGenerateXsltFromCanvas.Text = "Transform"; + this.btnGenerateXsltFromCanvas.UseVisualStyleBackColor = true; + this.btnGenerateXsltFromCanvas.Click += new System.EventHandler(this.btnGenerateXsltFromCanvas_Click); + // // trvTarget // this.trvTarget.Dock = System.Windows.Forms.DockStyle.Fill; @@ -435,11 +484,58 @@ private void InitializeComponent() this.trvTarget.Size = new System.Drawing.Size(441, 519); this.trvTarget.TabIndex = 1; // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 2; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1467F)); + this.tableLayoutPanel2.Controls.Add(this.lblSaveAs, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.webBrowser1, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.label2, 0, 0); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(2, 2); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 3; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(1533, 719); + this.tableLayoutPanel2.TabIndex = 1; + // + // saveFileDialog1 + // + this.saveFileDialog1.DefaultExt = "Save As.."; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(3, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(53, 25); + this.label2.TabIndex = 1; + this.label2.Text = "Save As.."; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblSaveAs + // + this.lblSaveAs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.lblSaveAs.AutoSize = true; + this.lblSaveAs.Location = new System.Drawing.Point(69, 0); + this.lblSaveAs.Name = "lblSaveAs"; + this.lblSaveAs.Size = new System.Drawing.Size(53, 25); + this.lblSaveAs.TabIndex = 2; + this.lblSaveAs.Text = "lblSaveas"; + this.lblSaveAs.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // // X12UtilsFRM // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1298, 790); + this.ClientSize = new System.Drawing.Size(1545, 771); this.Controls.Add(this.tabControl1); this.Controls.Add(this.statusStrip1); this.Margin = new System.Windows.Forms.Padding(2); @@ -459,6 +555,9 @@ private void InitializeComponent() this.browser.ResumeLayout(false); this.FormLocations.ResumeLayout(false); this.tbpMap.ResumeLayout(false); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -497,6 +596,13 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox chkBrowse; private System.Windows.Forms.Panel pnlFunctoids; private System.Windows.Forms.ListBox lbxTargetSchema; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Button btnGenerateXsltFromCanvas; + private System.Windows.Forms.CheckBox chkTargetSchema; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lblSaveAs; } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 248f282d..7fb67428 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -1,6 +1,8 @@ using NLog; using NLog.Windows.Forms; +using PdfX.App.Services; using SkiaSharp; +using SkiaSharp.Views.Desktop; using System; using System.Collections.Generic; using System.Configuration; @@ -12,12 +14,16 @@ using System.Text; using System.Windows.Forms; using System.Xml; +using System.Xml.Xsl; using X12.Hipaa.Claims; using X12.Hipaa.Claims.Services; using X12.Parsing; using X12.Shared.Models; using X12.Transformations; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button; +using GroupBox = System.Windows.Forms.GroupBox; using Label = System.Windows.Forms.Label; +using RadioButton = System.Windows.Forms.RadioButton; using Rectangle = System.Drawing.Rectangle; namespace X12UtilsFRM @@ -43,6 +49,10 @@ public partial class X12UtilsFRM : Form private bool _isToolboxExpanded = true; private const int ToolboxWidth = 245; + private Button btnToolboxVerticalToggle = null; + private bool _isToolboxExpandedVertical = true; + private int _originalFloatingHeight = 400; // Default expanded height memory + // Draggable capsule tracking properties private bool _isDraggingToolbox = false; @@ -102,35 +112,81 @@ private static void Log(String s, [CallerMemberName] string cn = "", [CallerLine private void InitializeToolbox() { - // 1. Create the main wrapper panel. Remove Anchor properties so it can move freely. + _originalFloatingHeight = pnlFunctoids.Height - 40; + + // Create the main workspace panel frame block pnlToolboxWrapper = new Panel { Width = ToolboxWidth + 20, - Height = pnlFunctoids.Height - 40, // Give it a nice padding from top/bottom + Height = _originalFloatingHeight, Location = new Point(pnlFunctoids.Width - (ToolboxWidth + 40), 20), - BackColor = Color.FromArgb(235, 240, 250), // Give it a solid background so canvas lines don't bleed through + BackColor = Color.FromArgb(235, 240, 250), BorderStyle = BorderStyle.FixedSingle }; pnlFunctoids.Controls.Add(pnlToolboxWrapper); pnlToolboxWrapper.BringToFront(); - // 2. Create the toggle button on the left edge of the toolbox wrapper - btnToolboxToggle = new Button + // 1. The "Functoids" Top Header Title Strip + Panel pnlHeaderBar = new Panel + { + Height = 25, + Dock = DockStyle.Top, + BackColor = Color.FromArgb(220, 225, 235) + }; + pnlToolboxWrapper.Controls.Add(pnlHeaderBar); + + // 2. The Vertical Toggle Button placed directly onto the right side of the HeaderBar + btnToolboxVerticalToggle = new Button { - Text = "»", - Font = new Font("Segoe UI", 9, FontStyle.Bold), - Width = 20, - Dock = DockStyle.Left, + Text = "▲", + Font = new Font("Segoe UI", 7, FontStyle.Bold), + Size = new Size(22, 21), + // Position it on the far right of the header bar with a small 2px padding offset + Location = new Point(pnlToolboxWrapper.Width - 26, 2), FlatStyle = FlatStyle.Popup, - BackColor = Color.FromArgb(210, 215, 225), + BackColor = Color.FromArgb(195, 200, 215), ForeColor = Color.FromArgb(50, 50, 80), - Cursor = Cursors.Hand + Cursor = Cursors.Hand, + Anchor = AnchorStyles.Top | AnchorStyles.Right }; - btnToolboxToggle.FlatAppearance.BorderSize = 0; - btnToolboxToggle.Click += ToggleToolbox_Click; - pnlToolboxWrapper.Controls.Add(btnToolboxToggle); + btnToolboxVerticalToggle.FlatAppearance.BorderSize = 0; + btnToolboxVerticalToggle.Click += ToggleToolboxVertical_Click; + pnlHeaderBar.Controls.Add(btnToolboxVerticalToggle); - // 3. Create the container where categories flow vertically + // Handle title text and icon drawing manually via GDI+ to Skia bridging + pnlHeaderBar.Paint += (sender, e) => + { + var info = new SKImageInfo(pnlHeaderBar.Width, pnlHeaderBar.Height); + using (var surface = SKSurface.Create(info)) + { + SKCanvas canvas = surface.Canvas; + canvas.Clear(Color.FromArgb(220, 225, 235).ToSKColor()); + + // Define position parameters for our custom vector icon + SKPoint iconPosition = new SKPoint(15, pnlHeaderBar.Height / 2f); + float iconSize = 12f; + SKColor iconColor = Color.Red.ToSKColor(); + + // Call the vector method we placed in SkiaMapper + SkiaMapper.DrawToolboxIcon(canvas, iconPosition, iconSize, iconColor); + + // Draw the "Functoids" text next to the icon manually + using (var textPaint = new SKPaint { Color = iconColor, IsAntialias = true }) + using (var textFont = new SKFont(SKTypeface.FromFamilyName("Segoe UI", SKFontStyle.Bold), 12)) + { + canvas.DrawText("Functoids", 28, (pnlHeaderBar.Height / 2f) + 4.5f, textFont, textPaint); + } + + canvas.Flush(); + using (var snapshot = surface.Snapshot()) + using (var bitmap = snapshot.ToBitmap()) + { + e.Graphics.DrawImage(bitmap, 0, 0); + } + } + }; + + // 3. Create the main categories scroll container view pnlToolboxCategoriesContainer = new FlowLayoutPanel { Dock = DockStyle.Fill, @@ -143,10 +199,8 @@ private void InitializeToolbox() pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); pnlToolboxCategoriesContainer.BringToFront(); - // --- NEW: WIRE UP DRAG-TO-MOVE EVENTS --- - // Let the user drag the toolbox by holding and dragging the toggle button assembly strip - AttachToolboxDragEvents(btnToolboxToggle); - // ---------------------------------------- + // Tie movement drag actions onto the header bar background layer + AttachToolboxDragEvents(pnlHeaderBar); var stringTools = new List { "Concatenate", "String Left", "String Right", "Trim", "Uppercase", "Lowercase" }; var mathTools = new List { "Add", "Subtract", "Multiply", "Divide", "Modulus", "Absolute" }; @@ -161,6 +215,68 @@ private void InitializeToolbox() RenderToolboxLayout(); } + private void ToggleToolboxVertical_Click(object sender, EventArgs e) + { + // If the palette is fully collapsed horizontally, ignore vertical commands + if (!_isToolboxExpanded) return; + + _isToolboxExpandedVertical = !_isToolboxExpandedVertical; + pnlFunctoids.SuspendLayout(); + + if (_isToolboxExpandedVertical) + { + // Restore height back out to our expanded memory size state + pnlToolboxWrapper.Height = _originalFloatingHeight; + pnlToolboxCategoriesContainer.Visible = true; + btnToolboxVerticalToggle.Text = "▲"; + } + else + { + // Save the current height dynamically before crushing it down (in case the user resized the form) + if (pnlToolboxWrapper.Height > 60) + { + _originalFloatingHeight = pnlToolboxWrapper.Height; + } + + // Collapse down vertically to perfectly clear room for lines below it + pnlToolboxCategoriesContainer.Visible = false; + pnlToolboxWrapper.Height = 52; // Height of the button strip elements combined + btnToolboxVerticalToggle.Text = "▼"; + } + + pnlFunctoids.ResumeLayout(true); + _mapper.Invalidate(); + } + private void ToggleToolbox_Click(object sender, EventArgs e) + { + _isToolboxExpanded = !_isToolboxExpanded; + pnlFunctoids.SuspendLayout(); + + if (_isToolboxExpanded) + { + pnlToolboxWrapper.Width = ToolboxWidth + 20; + btnToolboxVerticalToggle.Visible = true; // Show vertical control strip option back + + // Respect the current vertical state profile + pnlToolboxCategoriesContainer.Visible = _isToolboxExpandedVertical; + pnlToolboxWrapper.Height = _isToolboxExpandedVertical ? _originalFloatingHeight : 52; + + btnToolboxToggle.Text = "»"; + RenderToolboxLayout(); + } + else + { + // Minimize completely into a sleek sidebar profile line + pnlToolboxCategoriesContainer.Visible = false; + btnToolboxVerticalToggle.Visible = false; // Hide vertical arrow + pnlToolboxWrapper.Width = btnToolboxToggle.Width; + pnlToolboxWrapper.Height = 25; // Just high enough for the single << character button + btnToolboxToggle.Text = "«"; + } + + pnlFunctoids.ResumeLayout(true); + _mapper.Invalidate(); + } private void AttachToolboxDragEvents(Control dragHandle) { dragHandle.MouseDown += (sender, e) => @@ -223,30 +339,7 @@ private void RenderToolboxLayout() pnlToolboxCategoriesContainer.ResumeLayout(true); } - private void ToggleToolbox_Click(object sender, EventArgs e) - { - _isToolboxExpanded = !_isToolboxExpanded; - pnlFunctoids.SuspendLayout(); - if (_isToolboxExpanded) - { - // Expand outward keeping its current X coordinate placement intact - pnlToolboxWrapper.Width = ToolboxWidth + 20; - pnlToolboxCategoriesContainer.Visible = true; - btnToolboxToggle.Text = "»"; - RenderToolboxLayout(); - } - else - { - // Collapse down to just show the little grab handle tab bar - pnlToolboxCategoriesContainer.Visible = false; - pnlToolboxWrapper.Width = btnToolboxToggle.Width; - btnToolboxToggle.Text = "«"; - } - - pnlFunctoids.ResumeLayout(true); - _mapper.Invalidate(); - } #endregion @@ -515,14 +608,40 @@ private void btnMap_Click(object sender, EventArgs e) tabControl1.SelectedIndex = (int)enmTabPages.map; InitializeEmbeddedSchemaLayout(inputFileName, outputFileName); } + private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args) + { + Logger.Info($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); + } + private string checkedOption(GroupBox grp) + { + var checkedControl = grp.Controls.Cast().FirstOrDefault(c =>((dynamic) c).Checked == true); + Logger.Info($"Found control type: {checkedControl.Name}"); + return checkedControl.Text; + } private void btnParse_Click(object sender, EventArgs e) { string x = ""; - switch (Properties.Settings.Default.TransformFormat) + string _checkedOption = checkedOption(groupBox1); + + try { - case "HTML": x = X12Tohtml(rtxInterchangeFile.Text); break; - case "XML": x = X12ToXml(rtxInterchangeFile.Text); break; + switch (_checkedOption) + { + case "HTML": x = X12Tohtml(rtxInterchangeFile.Text); break; + case "XML": + rtxInterchangeFile.Text = ContentFromFile(lbxInfileList.Text); + X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), true); + parser.ParserWarning += new X12.Parsing.X12Parser.X12ParserWarningEventHandler(parser_ParserWarning); + interchanges = parser.ParseMultiple(rtxInterchangeFile.Text); + x = X12ToXml(rtxInterchangeFile.Text); + break; + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + return; } DisplayHtml(x); tabControl1.SelectedIndex = (int)enmTabPages.browser; @@ -536,6 +655,8 @@ public string X12Tohtml(string x12) public string X12ToXml(string x12) { + if (string.IsNullOrEmpty(x12)) return string.Empty; + using (MemoryStream memStream = new MemoryStream(1000)) { interchanges.First().Serialize(memStream); @@ -772,53 +893,9 @@ private Control CreateFunctoid(string text, Point location) #region Code Compilation Utilities (Xslt Outbound Maps) - public string CompileMapToXslt() - { - StringBuilder xslt = new StringBuilder(); - xslt.AppendLine(""); - xslt.AppendLine(""); - xslt.AppendLine(" "); - xslt.AppendLine(" "); - xslt.AppendLine(); - xslt.AppendLine(" "); - foreach (var conn in _mapper.Connections) - { - if (conn.Source is XmlNode sourceXmlNode) - { - string sourceXPath = BuildAbsoluteXPath(sourceXmlNode); - - if (conn.Target is BizTalkFunctoidNode functoid) - { - string targetNodeName = functoid.FunctoidName.Replace(" ", "_"); - string snippet = !string.IsNullOrEmpty(functoid.CustomScript) && !functoid.CustomScript.Contains("SOURCE_XPATH_PLACEHOLDER") - ? functoid.CustomScript - : FunctoidXsltCompiler.GetXsltSnippet(functoid.FunctoidName, sourceXPath, targetNodeName); - xslt.AppendLine($" {snippet.Replace("SOURCE_XPATH_PLACEHOLDER", sourceXPath)}"); - } - else if (conn.Target is SchemaNodeItem targetSchemaItem) - { - string targetNodeName = targetSchemaItem.XmlSourceNode.Name; - xslt.AppendLine($" {FunctoidXsltCompiler.GetXsltSnippet("DirectLink", sourceXPath, targetNodeName)}"); - } - } - } - xslt.AppendLine(" "); - xslt.AppendLine(""); - return xslt.ToString(); - } - - private string BuildAbsoluteXPath(XmlNode node) - { - if (node == null || node.NodeType == XmlNodeType.Document) return ""; - if (node.NodeType == XmlNodeType.Attribute) - return BuildAbsoluteXPath(((XmlAttribute)node).OwnerElement) + "/@" + node.Name; - - string parentPath = BuildAbsoluteXPath(node.ParentNode); - return string.IsNullOrEmpty(parentPath) ? node.Name : parentPath + "/" + node.Name; - } #endregion @@ -826,7 +903,36 @@ private string BuildAbsoluteXPath(XmlNode node) private void rbXml_CheckedChanged(object sender, EventArgs e) { } private void lbxInputFileList(object sender, EventArgs e) { } private void btnHippaParse_Click(object sender, EventArgs e) { } - private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { } + private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) + { + enmTabPages currentTab = (enmTabPages)tabControl1.SelectedIndex; + switch (currentTab) + { + case enmTabPages.parse: + // Action when user switches to the Parse tab + Log("Switched to Parse tab."); + // e.g., Refresh file list or reset parsing states if needed + break; + + case enmTabPages.browser: + // Action when user switches to the Browser tab + Log("Switched to Browser tab."); + // e.g., Ensure a document is loaded or focus the webBrowser1 control + lblSaveAs.Text = lbxInfileList.Text; + using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + { + saveFileDialog.InitialDirectory = Path.GetDirectoryName(lbxInfileList.Text); + webBrowser1.ShowSaveAsDialog(); + } + webBrowser1.Focus(); + break; + + default: + Log($"Unknown tab index: {tabControl1.SelectedIndex}"); + break; + } + + } private void lblInterchangeCount_TextChanged(object sender, EventArgs e) { int fcount = int.Parse(((Label)sender).Text); @@ -839,5 +945,120 @@ private void rbHtml_CheckedChanged(object sender, EventArgs e) Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); Properties.Settings.Default.Save(); } + + public void LinkXsltToSourceXmlFile(string sourceXmlPath, string xsltFilePath) + { + if (string.IsNullOrEmpty(sourceXmlPath) || !File.Exists(sourceXmlPath)) + throw new FileNotFoundException("Source XML file could not be found.", sourceXmlPath); + + // Load the source XML document + XmlDocument doc = new XmlDocument(); + doc.Load(sourceXmlPath); + + // Extract pure file name (e.g., "M850.xslt") to keep the path relative inside the XML + string pureXsltName = Path.GetFileName(xsltFilePath); + string piData = $"type=\"text/xsl\" href=\"{pureXsltName}\""; + + // Check if an xml-stylesheet link already exists so we don't duplicate it + XmlProcessingInstruction existingPi = doc.ChildNodes + .OfType() + .FirstOrDefault(pi => pi.Name == "xml-stylesheet"); + + if (existingPi != null) + { + // Update the existing link path + existingPi.Data = piData; + } + else + { + // Create a new independent processing instruction node + XmlProcessingInstruction newPi = doc.CreateProcessingInstruction("xml-stylesheet", piData); + + // Safely insert it right after the standard declaration if present + XmlNode xmlDeclaration = doc.ChildNodes.OfType().FirstOrDefault(); + if (xmlDeclaration != null) + { + doc.InsertAfter(newPi, xmlDeclaration); + } + else + { + doc.PrependChild(newPi); + } + } + + // Save the modified source XML file back to its location + using (var writer = new XmlTextWriter(sourceXmlPath, Encoding.UTF8)) + { + writer.Formatting = Formatting.Indented; + doc.Save(writer); + } + } + private void btnGenerateXsltFromCanvas_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(lbxInfileList.Text)) + { + MessageBox.Show("Please select a source file from the list first.", "Missing Source Context"); + return; + } + try + { + var generator = new XsltMapGenerator(_mapper); + string directory = Path.GetDirectoryName(lbxInfileList.Text); + string filenameWithoutExt = Path.GetFileNameWithoutExtension(lbxInfileList.Text); + string targetSchemaFileName = Path.Combine(directory, "Transforms", filenameWithoutExt + ".xslt"); + string transformDirectory = Path.GetDirectoryName(targetSchemaFileName); + if (!Directory.Exists(transformDirectory)) + { + Directory.CreateDirectory(transformDirectory); + } + string compiledXslt = generator.GenerateXsltFromCanvas(lbxInfileList.Text, targetSchemaFileName); + File.WriteAllText(targetSchemaFileName, compiledXslt); + LinkXsltToSourceXmlFile(lbxInfileList.Text, targetSchemaFileName); + + MessageBox.Show($"XSLT Map generated successfully at:\n{targetSchemaFileName}", "Success"); + } + catch (Exception ex) + { + MessageBox.Show($"Failed to generate XSLT map layout:\n{ex.Message}", "Generation Error"); + } + } + public string ContentFromFile(string filename/*fullPath*/) + { + using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) + { + return new StreamReader(filename).ReadToEnd(); + } + } + private void lbxfileList_SelectedIndexChanged(object sender, EventArgs e) + { + string fileName = ((ListBox)sender).Text; + if (String.IsNullOrEmpty(fileName)) return; + tt.SetToolTip(lbxInfileList, fileName + " is Selected now.."); + lblInterchangeCount.Text = "0"; + lblInterchangeCount.Text = "1"; + + + if (chkBrowse.Checked) + { + switch (Path.GetExtension(fileName)) + { + case ".txt": + DisplayHtml(X12ToXml(ContentFromFile(fileName))); + break; + case ".xml": + DisplayHtml(ContentFromFile(fileName)); + tabControl1.SelectedIndex = (int)enmTabPages.browser; + break; + default: + break; + } + return; + } + } + + private void label4_Click(object sender, EventArgs e) + { + + } } } \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 6f2ee377..0c27fce4 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -117,6 +117,7 @@ Form + UserControl @@ -152,6 +153,7 @@ X12UtilsFRM.cs Designer + PreserveNewest diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 22c85480..3dcbd0f4 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -123,7 +123,7 @@ 133, 17 - - 133, 17 + + 230, 17 \ No newline at end of file diff --git a/X12UtilsFRM/XsltMapGenerator.cs b/X12UtilsFRM/XsltMapGenerator.cs new file mode 100644 index 00000000..3729b0bf --- /dev/null +++ b/X12UtilsFRM/XsltMapGenerator.cs @@ -0,0 +1,243 @@ +using System; +using System.Text; +using System.Xml; +using System.Linq; +using System.Collections.Generic; + +namespace PdfX.App.Services +{ + public class XsltMapGenerator + { + private readonly dynamic _mapper; + + public XsltMapGenerator(dynamic mapper) + { + _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); + } + + /// + /// CONSOLIDATED LOGIC: Moved directly inside the generator class. + /// Recursively constructs the absolute XPath for a given XML node or attribute. + /// + private string BuildAbsoluteXPath(XmlNode node) + { + if (node == null || node.NodeType == XmlNodeType.Document) return ""; + if (node.NodeType == XmlNodeType.Attribute) + return BuildAbsoluteXPath(((XmlAttribute)node).OwnerElement) + "/@" + node.Name; + + string parentPath = BuildAbsoluteXPath(node.ParentNode); + return string.IsNullOrEmpty(parentPath) ? node.Name : parentPath + "/" + node.Name; + } + + /// + /// Builds the complete XSLT map layout based entirely on internal logic. + /// + /// Name of the input source data file context. + /// Name of this mapping XSLT file to associate. + public string GenerateXsltFromCanvas( + string sourceFileName = "unknown_source_payload.xml", + string xsltFileName = "BizTalkTransformMap.xslt") + { + if (_mapper.Connections == null || _mapper.Connections.Count == 0) + { + return string.Empty; + } + + if (!string.IsNullOrEmpty(sourceFileName) && (sourceFileName.Contains("\\") || sourceFileName.Contains("/"))) + sourceFileName = System.IO.Path.GetFileName(sourceFileName); + + if (!string.IsNullOrEmpty(xsltFileName) && (xsltFileName.Contains("\\") || xsltFileName.Contains("/"))) + xsltFileName = System.IO.Path.GetFileName(xsltFileName); + + StringBuilder xslt = new StringBuilder(); + + // 1. Core Header Definitions + xslt.AppendLine(""); + xslt.AppendLine(""); + xslt.AppendLine(" "); + xslt.AppendLine(); + + // 2. Global Metadata Parameters + xslt.AppendLine(" "); + xslt.AppendLine($" "); + xslt.AppendLine($" "); + xslt.AppendLine(); + + // 3. Root Template Match Entry Point with Processing Instruction + xslt.AppendLine(" "); + xslt.AppendLine(" "); + xslt.AppendLine(" type=\"text/xsl\" href=\""); + xslt.AppendLine(" "); + xslt.AppendLine(" \""); + xslt.AppendLine(" "); + xslt.AppendLine(" "); + xslt.AppendLine(" "); + xslt.AppendLine(); + + var flatSchemaRegistry = (IEnumerable)_mapper.FlatSchemaRegistry; + var flatTargetSchemaRegistry = (IEnumerable)_mapper.FlatTargetSchemaRegistry; + var connections = (IEnumerable)_mapper.Connections; + + string sourceRootName = flatSchemaRegistry.FirstOrDefault()?.XmlSourceNode.Name ?? "SOURCE_ROOT"; + string targetRootName = flatTargetSchemaRegistry.FirstOrDefault()?.XmlSourceNode.Name ?? "ROOT"; + + xslt.AppendLine($" "); + xslt.AppendLine($" <{targetRootName}>"); + xslt.AppendLine(" "); + xslt.AppendLine(); + + int variableCounter = 1; + Dictionary uniqueScriptMethodsRegistry = new Dictionary(); + + var targetBoundConnections = connections.Where(c => + c.Target is XmlNode || c.Target.GetType().Name == "SchemaNodeItem").ToList(); + + foreach (var conn in targetBoundConnections) + { + XmlNode targetXmlNode = conn.Target is XmlNode xmlTgt ? xmlTgt : conn.Target.XmlSourceNode; + if (targetXmlNode == null) continue; + + xslt.AppendLine($" <{targetXmlNode.Name}>"); + + // CASE A: Direct Link (Now calling internal BuildAbsoluteXPath method) + if (conn.Source is XmlNode || conn.Source.GetType().Name == "SchemaNodeItem") + { + XmlNode srcXmlNode = conn.Source is XmlNode xmlSrc ? xmlSrc : conn.Source.XmlSourceNode; + string structuralXPath = BuildAbsoluteXPath(srcXmlNode).Replace(sourceRootName + "/", ""); + xslt.AppendLine($" "); + } + // CASE B: Series-Connected Functoid Chain + else if (conn.Source.GetType().Name == "BizTalkFunctoidNode") + { + string varName = $"var:v{variableCounter}"; + + string inlineExpressionCall = ResolveFunctoidExpression( + conn.Source, + sourceRootName, + uniqueScriptMethodsRegistry, + connections + ); + + xslt.AppendLine($" "); + xslt.AppendLine($" "); + + variableCounter++; + } + + xslt.AppendLine($" "); + } + + xslt.AppendLine($" "); + xslt.AppendLine(" "); + xslt.AppendLine(); + + // 4. Mount consolidated deduplicated C# script functions + if (uniqueScriptMethodsRegistry.Count > 0) + { + xslt.AppendLine(" "); + xslt.AppendLine(" "); + xslt.AppendLine(" "); + } + + xslt.AppendLine(""); + return xslt.ToString(); + } + + private string ResolveFunctoidExpression( + dynamic functoidNode, + string sourceRootName, + Dictionary scriptRegistry, + IEnumerable connections) + { + var inputLinks = connections.Where(c => object.ReferenceEquals(c.Target, functoidNode)).ToList(); + List optimizedArguments = new List(); + List formalParameters = new List(); + + int argIdx = 1; + foreach (var inputConn in inputLinks) + { + if (inputConn.Source is XmlNode || inputConn.Source.GetType().Name == "SchemaNodeItem") + { + XmlNode inputXmlNode = inputConn.Source is XmlNode xmlIn ? xmlIn : inputConn.Source.XmlSourceNode; + if (inputXmlNode != null) + { + // Now calling internal BuildAbsoluteXPath method directly + string inputPath = BuildAbsoluteXPath(inputXmlNode).Replace(sourceRootName + "/", ""); + optimizedArguments.Add($"string({inputPath})"); + formalParameters.Add($"string p_arg{argIdx}"); + argIdx++; + } + } + else if (inputConn.Source.GetType().Name == "BizTalkFunctoidNode") + { + string nestedExpression = ResolveFunctoidExpression(inputConn.Source, sourceRootName, scriptRegistry, connections); + optimizedArguments.Add(nestedExpression); + formalParameters.Add($"string p_arg{argIdx}"); + argIdx++; + } + } + + string toolName = functoidNode.FunctoidName; + var standardTools = new List { "Concatenate", "Add", "Subtract", "Trim", "Uppercase", "Lowercase" }; + if (!standardTools.Contains(toolName)) toolName = "DirectPassThrough"; + + int argumentCount = optimizedArguments.Count; + string functionName = $"Fct_{toolName}_{argumentCount}"; + + if (!scriptRegistry.ContainsKey(functionName)) + { + StringBuilder methodBody = new StringBuilder(); + string paramsJoined = string.Join(", ", formalParameters); + + switch (toolName) + { + case "Concatenate": + methodBody.AppendLine($" public string {functionName}(params string[] segments)"); + methodBody.AppendLine(" {"); + methodBody.AppendLine(" return string.Concat(segments);"); + methodBody.AppendLine(" }"); + break; + + case "Add": + methodBody.AppendLine($" public string {functionName}(params string[] numbers)"); + methodBody.AppendLine(" {"); + methodBody.AppendLine(" double total = 0;"); + methodBody.AppendLine(" foreach(var num in numbers) { if (double.TryParse(num, out double val)) total += val; }"); + methodBody.AppendLine(" return total.ToString();"); + methodBody.AppendLine(" }"); + break; + + case "Uppercase": + methodBody.AppendLine($" public string {functionName}({paramsJoined})"); + methodBody.AppendLine(" {"); + string upperParam = formalParameters.Count > 0 ? formalParameters[0].Split(' ')[1] : "\"\""; + methodBody.AppendLine($" return ({upperParam} ?? \"\").ToUpper();"); + methodBody.AppendLine(" }"); + break; + + default: + methodBody.AppendLine($" public string {functionName}({paramsJoined})"); + methodBody.AppendLine(" {"); + string fallbackParam = formalParameters.Count > 0 ? formalParameters[0].Split(' ')[1] : "\"\""; + methodBody.AppendLine($" return {fallbackParam};"); + methodBody.AppendLine(" }"); + break; + } + + scriptRegistry.Add(functionName, methodBody.ToString()); + } + + return $"userCSharp:{functionName}({string.Join(", ", optimizedArguments)})"; + } + } +} \ No newline at end of file diff --git a/src/X12.Parsing/X12StreamReader.cs b/src/X12.Parsing/X12StreamReader.cs index 6169fa35..68d2ee1d 100644 --- a/src/X12.Parsing/X12StreamReader.cs +++ b/src/X12.Parsing/X12StreamReader.cs @@ -22,12 +22,16 @@ public class X12StreamReader : IDisposable /// used for reading /// used for properly reading the stream /// Array of characters to be ignored while reading + /// + + public X12StreamReader(Stream stream, Encoding encoding, char[] ignoredChars) { this.reader = new StreamReader(stream, encoding); var header = new char[106]; if (this.reader.Read(header, 0, 106) < 106) { + throw new ArgumentException(Resources.X12ReaderInvalidHeader); } From 7c541400b00d55099eefb40fe6269e120c544e4d Mon Sep 17 00:00:00 2001 From: apeiris Date: Thu, 21 May 2026 10:12:47 -0400 Subject: [PATCH 18/22] moved map save and transform to tool pallete --- X12UtilsFRM/App.config | 22 +- X12UtilsFRM/Properties/Settings.Designer.cs | 60 ++++- X12UtilsFRM/Properties/Settings.settings | 16 +- X12UtilsFRM/SkiaShared.cs | 36 +++ X12UtilsFRM/X12UtilsFRM.Designer.cs | 210 ++++++++---------- X12UtilsFRM/X12UtilsFRM.cs | 231 +++++++++++--------- X12UtilsFRM/X12UtilsFRM.csproj | 35 ++- X12UtilsFRM/X12UtilsFRM.resx | 3 + X12UtilsFRM/XsltMapGenerator.cs | 86 +++++--- X12UtilsFRM/packages.config | 14 +- 10 files changed, 432 insertions(+), 281 deletions(-) create mode 100644 X12UtilsFRM/SkiaShared.cs diff --git a/X12UtilsFRM/App.config b/X12UtilsFRM/App.config index eb12900b..99043489 100644 --- a/X12UtilsFRM/App.config +++ b/X12UtilsFRM/App.config @@ -31,27 +31,39 @@ False - + + True + + + False + + False - + False + + 5 + + + 5 + - + - + - + diff --git a/X12UtilsFRM/Properties/Settings.Designer.cs b/X12UtilsFRM/Properties/Settings.Designer.cs index af15026e..134cb396 100644 --- a/X12UtilsFRM/Properties/Settings.Designer.cs +++ b/X12UtilsFRM/Properties/Settings.Designer.cs @@ -107,27 +107,75 @@ public bool throwExceptions { } } + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ParseToXML { + get { + return ((bool)(this["ParseToXML"])); + } + set { + this["ParseToXML"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool ParseToHTML { + get { + return ((bool)(this["ParseToHTML"])); + } + set { + this["ParseToHTML"] = value; + } + } + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool BrowseWhenClicked { + public bool chkBrowseCheked { get { - return ((bool)(this["BrowseWhenClicked"])); + return ((bool)(this["chkBrowseCheked"])); } set { - this["BrowseWhenClicked"] = value; + this["chkBrowseCheked"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool BrowseWhenSelected { + public bool chkTargetSchemaChecked { + get { + return ((bool)(this["chkTargetSchemaChecked"])); + } + set { + this["chkTargetSchemaChecked"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("5")] + public int SelectedInfile { + get { + return ((int)(this["SelectedInfile"])); + } + set { + this["SelectedInfile"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("5")] + public int SelectedTargetSchema { get { - return ((bool)(this["BrowseWhenSelected"])); + return ((int)(this["SelectedTargetSchema"])); } set { - this["BrowseWhenSelected"] = value; + this["SelectedTargetSchema"] = value; } } } diff --git a/X12UtilsFRM/Properties/Settings.settings b/X12UtilsFRM/Properties/Settings.settings index bbca507f..9a0ad1fe 100644 --- a/X12UtilsFRM/Properties/Settings.settings +++ b/X12UtilsFRM/Properties/Settings.settings @@ -23,11 +23,23 @@ False - + + True + + + False + + False - + False + + 5 + + + 5 + \ No newline at end of file diff --git a/X12UtilsFRM/SkiaShared.cs b/X12UtilsFRM/SkiaShared.cs new file mode 100644 index 00000000..91c03338 --- /dev/null +++ b/X12UtilsFRM/SkiaShared.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace X12UtilsFRM +{ + public class CanvasSaveState + { + public string SourceSchemaFile { get; set; } + public string TargetSchemaFile { get; set; } + public List Functoids { get; set; } = new List(); + public List Wires { get; set; } = new List(); + } + + public class CanvasFunctoidDto + { + public string Id { get; set; } + public string FunctoidName { get; set; } + public float X { get; set; } + public float Y { get; set; } + } + + public class CanvasConnectionDto + { + public string SourceType { get; set; } // "SchemaNode" or "Functoid" + public string SourceIdOrXPath { get; set; } + + public string TargetType { get; set; } // "SchemaNode" or "Functoid" + public string TargetIdOrXPath { get; set; } + } + + +} + diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 7bafc7dd..a3ca44b7 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -33,9 +33,7 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.chkTargetSchema = new System.Windows.Forms.CheckBox(); this.lbxTargetSchema = new System.Windows.Forms.ListBox(); - this.chkBrowse = new System.Windows.Forms.CheckBox(); this.btnMap = new System.Windows.Forms.Button(); this.btnFindSpec = new System.Windows.Forms.Button(); this.btnHippaParse = new System.Windows.Forms.Button(); @@ -46,14 +44,15 @@ private void InitializeComponent() this.lblSelectedFile = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.rbHtml = new System.Windows.Forms.RadioButton(); - this.rbXml = new System.Windows.Forms.RadioButton(); this.btnAddFiles = new System.Windows.Forms.Button(); this.lbxInfileList = new System.Windows.Forms.ListBox(); this.rtLog = new System.Windows.Forms.RichTextBox(); this.rtxInterchangeFile = new System.Windows.Forms.RichTextBox(); this.browser = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.lblSaveAs = new System.Windows.Forms.Label(); this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.label2 = new System.Windows.Forms.Label(); this.FormLocations = new System.Windows.Forms.TabPage(); this.rtLocations = new System.Windows.Forms.RichTextBox(); this.tbpMap = new System.Windows.Forms.TabPage(); @@ -62,10 +61,10 @@ private void InitializeComponent() this.btnGenerateXsltFromCanvas = new System.Windows.Forms.Button(); this.trvTarget = new System.Windows.Forms.TreeView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); - this.label2 = new System.Windows.Forms.Label(); - this.lblSaveAs = new System.Windows.Forms.Label(); + this.rbHtml = new System.Windows.Forms.RadioButton(); + this.rbXml = new System.Windows.Forms.RadioButton(); + this.button2 = new System.Windows.Forms.Button(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -74,10 +73,11 @@ private void InitializeComponent() this.splitContainer1.SuspendLayout(); this.groupBox1.SuspendLayout(); this.browser.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); this.FormLocations.SuspendLayout(); this.tbpMap.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); - this.tableLayoutPanel2.SuspendLayout(); + this.pnlFunctoids.SuspendLayout(); this.SuspendLayout(); // // statusStrip1 @@ -127,9 +127,7 @@ private void InitializeComponent() // // splitContainer1.Panel1 // - this.splitContainer1.Panel1.Controls.Add(this.chkTargetSchema); this.splitContainer1.Panel1.Controls.Add(this.lbxTargetSchema); - this.splitContainer1.Panel1.Controls.Add(this.chkBrowse); this.splitContainer1.Panel1.Controls.Add(this.btnMap); this.splitContainer1.Panel1.Controls.Add(this.btnFindSpec); this.splitContainer1.Panel1.Controls.Add(this.btnHippaParse); @@ -152,40 +150,16 @@ private void InitializeComponent() this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // - // chkTargetSchema - // - this.chkTargetSchema.AutoSize = true; - this.chkTargetSchema.Checked = global::X12UtilsFRM.Properties.Settings.Default.BrowseWhenSelected; - this.chkTargetSchema.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "BrowseWhenSelected", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.chkTargetSchema.Location = new System.Drawing.Point(5, 435); - this.chkTargetSchema.Name = "chkTargetSchema"; - this.chkTargetSchema.Size = new System.Drawing.Size(127, 17); - this.chkTargetSchema.TabIndex = 14; - this.chkTargetSchema.Text = "Brows when selected"; - this.chkTargetSchema.UseVisualStyleBackColor = true; - // // lbxTargetSchema // this.lbxTargetSchema.FormattingEnabled = true; - this.lbxTargetSchema.Location = new System.Drawing.Point(3, 283); + this.lbxTargetSchema.Location = new System.Drawing.Point(2, 283); this.lbxTargetSchema.Margin = new System.Windows.Forms.Padding(2); this.lbxTargetSchema.Name = "lbxTargetSchema"; - this.lbxTargetSchema.Size = new System.Drawing.Size(356, 147); + this.lbxTargetSchema.Size = new System.Drawing.Size(356, 186); this.lbxTargetSchema.TabIndex = 13; this.lbxTargetSchema.SelectedIndexChanged += new System.EventHandler(this.lbxfileList_SelectedIndexChanged); // - // chkBrowse - // - this.chkBrowse.AutoSize = true; - this.chkBrowse.Checked = global::X12UtilsFRM.Properties.Settings.Default.BrowseWhenSelected; - this.chkBrowse.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "BrowseWhenSelected", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.chkBrowse.Location = new System.Drawing.Point(5, 213); - this.chkBrowse.Name = "chkBrowse"; - this.chkBrowse.Size = new System.Drawing.Size(127, 17); - this.chkBrowse.TabIndex = 12; - this.chkBrowse.Text = "Brows when selected"; - this.chkBrowse.UseVisualStyleBackColor = true; - // // btnMap // this.btnMap.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); @@ -311,33 +285,6 @@ private void InitializeComponent() this.groupBox1.TabStop = false; this.groupBox1.Text = "Transform.."; // - // rbHtml - // - this.rbHtml.AutoSize = true; - this.rbHtml.Checked = true; - this.rbHtml.Location = new System.Drawing.Point(68, 24); - this.rbHtml.Margin = new System.Windows.Forms.Padding(2); - this.rbHtml.Name = "rbHtml"; - this.rbHtml.Size = new System.Drawing.Size(74, 24); - this.rbHtml.TabIndex = 1; - this.rbHtml.TabStop = true; - this.rbHtml.Text = "HTML"; - this.rbHtml.UseVisualStyleBackColor = true; - this.rbHtml.CheckedChanged += new System.EventHandler(this.rbHtml_CheckedChanged); - // - // rbXml - // - this.rbXml.AutoSize = true; - this.rbXml.Location = new System.Drawing.Point(4, 24); - this.rbXml.Margin = new System.Windows.Forms.Padding(2); - this.rbXml.Name = "rbXml"; - this.rbXml.Size = new System.Drawing.Size(63, 24); - this.rbXml.TabIndex = 0; - this.rbXml.TabStop = true; - this.rbXml.Text = "XML"; - this.rbXml.UseVisualStyleBackColor = true; - this.rbXml.CheckedChanged += new System.EventHandler(this.rbXml_CheckedChanged); - // // btnAddFiles // this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); @@ -355,10 +302,10 @@ private void InitializeComponent() // lbxInfileList // this.lbxInfileList.FormattingEnabled = true; - this.lbxInfileList.Location = new System.Drawing.Point(5, 87); + this.lbxInfileList.Location = new System.Drawing.Point(4, 87); this.lbxInfileList.Margin = new System.Windows.Forms.Padding(2); this.lbxInfileList.Name = "lbxInfileList"; - this.lbxInfileList.Size = new System.Drawing.Size(356, 121); + this.lbxInfileList.Size = new System.Drawing.Size(356, 186); this.lbxInfileList.TabIndex = 0; this.lbxInfileList.SelectedIndexChanged += new System.EventHandler(this.lbxfileList_SelectedIndexChanged); // @@ -395,6 +342,37 @@ private void InitializeComponent() this.browser.Text = "Browser"; this.browser.UseVisualStyleBackColor = true; // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 2; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1467F)); + this.tableLayoutPanel2.Controls.Add(this.lblSaveAs, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.webBrowser1, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.label2, 0, 0); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(2, 2); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 3; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(1533, 719); + this.tableLayoutPanel2.TabIndex = 1; + // + // lblSaveAs + // + this.lblSaveAs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.lblSaveAs.AutoSize = true; + this.lblSaveAs.Location = new System.Drawing.Point(69, 0); + this.lblSaveAs.Name = "lblSaveAs"; + this.lblSaveAs.Size = new System.Drawing.Size(53, 25); + this.lblSaveAs.TabIndex = 2; + this.lblSaveAs.Text = "lblSaveas"; + this.lblSaveAs.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // // webBrowser1 // this.webBrowser1.AllowWebBrowserDrop = false; @@ -407,6 +385,18 @@ private void InitializeComponent() this.webBrowser1.Size = new System.Drawing.Size(1529, 670); this.webBrowser1.TabIndex = 0; // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(3, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(53, 25); + this.label2.TabIndex = 1; + this.label2.Text = "Save As.."; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // // FormLocations // this.FormLocations.Controls.Add(this.rtLocations); @@ -445,29 +435,31 @@ private void InitializeComponent() this.tableLayoutPanel1.ColumnCount = 1; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.Controls.Add(this.pnlFunctoids, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.btnGenerateXsltFromCanvas, 0, 1); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowCount = 3; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayoutPanel1.Size = new System.Drawing.Size(1537, 723); this.tableLayoutPanel1.TabIndex = 1; // // pnlFunctoids // + this.pnlFunctoids.Controls.Add(this.button2); + this.pnlFunctoids.Controls.Add(this.btnGenerateXsltFromCanvas); this.pnlFunctoids.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlFunctoids.Location = new System.Drawing.Point(3, 3); this.pnlFunctoids.Name = "pnlFunctoids"; - this.pnlFunctoids.Size = new System.Drawing.Size(1531, 682); + this.pnlFunctoids.Size = new System.Drawing.Size(1531, 662); this.pnlFunctoids.TabIndex = 0; this.pnlFunctoids.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragDrop); this.pnlFunctoids.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragEnter); // // btnGenerateXsltFromCanvas // - this.btnGenerateXsltFromCanvas.Location = new System.Drawing.Point(3, 691); + this.btnGenerateXsltFromCanvas.Location = new System.Drawing.Point(106, 630); this.btnGenerateXsltFromCanvas.Name = "btnGenerateXsltFromCanvas"; this.btnGenerateXsltFromCanvas.Size = new System.Drawing.Size(97, 29); this.btnGenerateXsltFromCanvas.TabIndex = 1; @@ -478,58 +470,50 @@ private void InitializeComponent() // trvTarget // this.trvTarget.Dock = System.Windows.Forms.DockStyle.Fill; - this.trvTarget.LineColor = System.Drawing.Color.Empty; this.trvTarget.Location = new System.Drawing.Point(0, 0); this.trvTarget.Name = "trvTarget"; this.trvTarget.Size = new System.Drawing.Size(441, 519); this.trvTarget.TabIndex = 1; // - // tableLayoutPanel2 - // - this.tableLayoutPanel2.ColumnCount = 2; - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1467F)); - this.tableLayoutPanel2.Controls.Add(this.lblSaveAs, 1, 0); - this.tableLayoutPanel2.Controls.Add(this.webBrowser1, 0, 1); - this.tableLayoutPanel2.Controls.Add(this.label2, 0, 0); - this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel2.Location = new System.Drawing.Point(2, 2); - this.tableLayoutPanel2.Name = "tableLayoutPanel2"; - this.tableLayoutPanel2.RowCount = 3; - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(1533, 719); - this.tableLayoutPanel2.TabIndex = 1; - // // saveFileDialog1 // this.saveFileDialog1.DefaultExt = "Save As.."; // - // label2 + // rbHtml // - this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(3, 0); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(53, 25); - this.label2.TabIndex = 1; - this.label2.Text = "Save As.."; - this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.rbHtml.AutoSize = true; + this.rbHtml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToHTML; + this.rbHtml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToHTML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.rbHtml.Location = new System.Drawing.Point(68, 24); + this.rbHtml.Margin = new System.Windows.Forms.Padding(2); + this.rbHtml.Name = "rbHtml"; + this.rbHtml.Size = new System.Drawing.Size(74, 24); + this.rbHtml.TabIndex = 1; + this.rbHtml.Text = "HTML"; + this.rbHtml.UseVisualStyleBackColor = true; // - // lblSaveAs + // rbXml // - this.lblSaveAs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.lblSaveAs.AutoSize = true; - this.lblSaveAs.Location = new System.Drawing.Point(69, 0); - this.lblSaveAs.Name = "lblSaveAs"; - this.lblSaveAs.Size = new System.Drawing.Size(53, 25); - this.lblSaveAs.TabIndex = 2; - this.lblSaveAs.Text = "lblSaveas"; - this.lblSaveAs.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.rbXml.AutoSize = true; + this.rbXml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToXML; + this.rbXml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToXML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.rbXml.Location = new System.Drawing.Point(4, 24); + this.rbXml.Margin = new System.Windows.Forms.Padding(2); + this.rbXml.Name = "rbXml"; + this.rbXml.Size = new System.Drawing.Size(63, 24); + this.rbXml.TabIndex = 0; + this.rbXml.TabStop = true; + this.rbXml.Text = "XML"; + this.rbXml.UseVisualStyleBackColor = true; + // + // button2 + // + this.button2.Location = new System.Drawing.Point(3, 630); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(97, 29); + this.button2.TabIndex = 2; + this.button2.Text = "Transform"; + this.button2.UseVisualStyleBackColor = true; // // X12UtilsFRM // @@ -553,11 +537,12 @@ private void InitializeComponent() this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.browser.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); this.FormLocations.ResumeLayout(false); this.tbpMap.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); - this.tableLayoutPanel2.ResumeLayout(false); - this.tableLayoutPanel2.PerformLayout(); + this.pnlFunctoids.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -593,16 +578,15 @@ private void InitializeComponent() private System.Windows.Forms.Button btnMap; private System.Windows.Forms.TabPage tbpMap; private System.Windows.Forms.TreeView trvTarget; - private System.Windows.Forms.CheckBox chkBrowse; private System.Windows.Forms.Panel pnlFunctoids; private System.Windows.Forms.ListBox lbxTargetSchema; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.Button btnGenerateXsltFromCanvas; - private System.Windows.Forms.CheckBox chkTargetSchema; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.SaveFileDialog saveFileDialog1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label lblSaveAs; + private System.Windows.Forms.Button button2; } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 7fb67428..fb5d0946 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -35,11 +35,9 @@ public enum enmTabPages formLocations, map } - public partial class X12UtilsFRM : Form { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - private SkiaMapper _mapper; private List toolboxCategories = new List(); private Panel pnlToolboxContainer = null; @@ -48,13 +46,10 @@ public partial class X12UtilsFRM : Form private Button btnToolboxToggle = null; private bool _isToolboxExpanded = true; private const int ToolboxWidth = 245; - private Button btnToolboxVerticalToggle = null; private bool _isToolboxExpandedVertical = true; private int _originalFloatingHeight = 400; // Default expanded height memory - // Draggable capsule tracking properties - private bool _isDraggingToolbox = false; private Point _toolboxDragStartMousePos; private Point _toolboxDragStartPanelPos; @@ -65,13 +60,11 @@ public partial class X12UtilsFRM : Form private Point _originalPanelLocation; private Size _originalPanelSize; private AnchorStyles _originalPanelAnchor; - List interchanges = null; ToolTip tt = null; private string locationsFile = ""; private static readonly string TestImageDirectory = @"..\..\..\tests\X12.Hipaa.Tests.Unit\Claims\TestData\Images\"; static readonly string pdfOutDirectory = @"C:\Temp\Pdfs"; - public X12UtilsFRM() { InitializeComponent(); @@ -100,16 +93,18 @@ public X12UtilsFRM() _mapper.DragEnter += pnlFunctoids_DragEnter; _mapper.DragOver += pnlFunctoids_DragEnter; _mapper.DragDrop += pnlFunctoids_DragDrop; - } + + + + + } private static void Log(String s, [CallerMemberName] string cn = "", [CallerLineNumber] int ln = 0, [CallerFilePath] string fp = "") { Trace.WriteLine($"{DateTime.Now.ToString()}-{cn}@{fp.Substring(fp.LastIndexOf('\\') + 1)}:{ln}:{s}"); Trace.Flush(); } - #region Toolbox Implementation - private void InitializeToolbox() { _originalFloatingHeight = pnlFunctoids.Height - 40; @@ -136,6 +131,7 @@ private void InitializeToolbox() pnlToolboxWrapper.Controls.Add(pnlHeaderBar); // 2. The Vertical Toggle Button placed directly onto the right side of the HeaderBar + #region vertical toggle button btnToolboxVerticalToggle = new Button { Text = "▲", @@ -152,9 +148,9 @@ private void InitializeToolbox() btnToolboxVerticalToggle.FlatAppearance.BorderSize = 0; btnToolboxVerticalToggle.Click += ToggleToolboxVertical_Click; pnlHeaderBar.Controls.Add(btnToolboxVerticalToggle); - - // Handle title text and icon drawing manually via GDI+ to Skia bridging - pnlHeaderBar.Paint += (sender, e) => + #endregion vertical toggle button + + pnlHeaderBar.Paint += (sender, e) => // Handle title text and icon drawing manually via GDI+ to Skia bridging { var info = new SKImageInfo(pnlHeaderBar.Width, pnlHeaderBar.Height); using (var surface = SKSurface.Create(info)) @@ -174,7 +170,7 @@ private void InitializeToolbox() using (var textPaint = new SKPaint { Color = iconColor, IsAntialias = true }) using (var textFont = new SKFont(SKTypeface.FromFamilyName("Segoe UI", SKFontStyle.Bold), 12)) { - canvas.DrawText("Functoids", 28, (pnlHeaderBar.Height / 2f) + 4.5f, textFont, textPaint); + canvas.DrawText("Functoids & Tools", 28, (pnlHeaderBar.Height / 2f) + 4.5f, textFont, textPaint); } canvas.Flush(); @@ -185,8 +181,50 @@ private void InitializeToolbox() } } }; + Panel pnlCanvasToolsBottomBar = new Panel + { + Dock = DockStyle.Bottom, + Height = 45, + BackColor = Color.FromArgb(225, 230, 245), + Padding = new Padding(10, 6, 10, 6), + BorderStyle = BorderStyle.None + }; + pnlCanvasToolsBottomBar.Paint += (s, e) => { + using (var pen = new Pen(Color.FromArgb(190, 200, 220), 1)) + { + e.Graphics.DrawLine(pen, 0, 0, pnlCanvasToolsBottomBar.Width, 0); + } + }; + int buttonWidth = (ToolboxWidth - 10) / 2; + Button btnTransform = new Button + { + Text = "Transform", + Size = new Size(buttonWidth, 32), + Location = new Point(10, 6), + FlatStyle = FlatStyle.Popup, + BackColor = Color.FromArgb(210, 220, 240), + Font = new Font("Segoe UI", 9, FontStyle.Regular), + Cursor = Cursors.Hand + }; + //btnTransform.Click += Transform_Click; + btnTransform.Click += btnGenerateXsltFromCanvas_Click; + Button btnSave = new Button + { + Text = "Save", + Size = new Size(buttonWidth, 32), + Location = new Point(15 + buttonWidth, 6), + FlatStyle = FlatStyle.Popup, + BackColor = Color.FromArgb(210, 220, 240), + Font = new Font("Segoe UI", 9, FontStyle.Regular), + Cursor = Cursors.Hand + }; + btnSave.Click += btnSaveCanvas_Click; + + pnlCanvasToolsBottomBar.Controls.Add(btnTransform); + pnlCanvasToolsBottomBar.Controls.Add(btnSave); + pnlToolboxWrapper.Controls.Add(pnlCanvasToolsBottomBar); - // 3. Create the main categories scroll container view + // 4. Create the main categories scroll container view (Fills remaining space) pnlToolboxCategoriesContainer = new FlowLayoutPanel { Dock = DockStyle.Fill, @@ -194,10 +232,17 @@ private void InitializeToolbox() FlowDirection = FlowDirection.TopDown, WrapContents = false, AutoScroll = true, - Padding = new Padding(10, 10, 10, 10) + Margin= new Padding(0,5,0,0), + Padding = new Padding(10, 18, 18, 10) }; pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); - pnlToolboxCategoriesContainer.BringToFront(); + + // Ensure all components maintain correct Z-order layering inside the wrapper frame + // To prevent layout overlap during minimization, the Fill container must live at the + // bottom of the Z-order stack so Top/Bottom docked components overlay cleanly on top of it. + pnlToolboxCategoriesContainer.SendToBack(); + pnlCanvasToolsBottomBar.BringToFront(); + pnlHeaderBar.BringToFront(); // Tie movement drag actions onto the header bar background layer AttachToolboxDragEvents(pnlHeaderBar); @@ -223,6 +268,14 @@ private void ToggleToolboxVertical_Click(object sender, EventArgs e) _isToolboxExpandedVertical = !_isToolboxExpandedVertical; pnlFunctoids.SuspendLayout(); + // Extract the header and bottom bar components safely from the wrapper + Control pnlHeader = pnlToolboxWrapper.Controls.Cast().FirstOrDefault(c => c.Dock == DockStyle.Top); + Control pnlBottomBar = pnlToolboxWrapper.Controls.Cast().FirstOrDefault(c => c.Dock == DockStyle.Bottom); + + int headerHeight = pnlHeader?.Height ?? 25; + int bottomBarHeight = pnlBottomBar?.Height ?? 45; + int topMarginOffset = pnlBottomBar?.Margin.Top ?? 8; + if (_isToolboxExpandedVertical) { // Restore height back out to our expanded memory size state @@ -233,17 +286,24 @@ private void ToggleToolboxVertical_Click(object sender, EventArgs e) else { // Save the current height dynamically before crushing it down (in case the user resized the form) - if (pnlToolboxWrapper.Height > 60) + // Keep threshold slightly above the dynamic collapsed height calculation + int minimumCollapsedHeight = headerHeight + bottomBarHeight + topMarginOffset; + + if (pnlToolboxWrapper.Height > minimumCollapsedHeight + 20) { _originalFloatingHeight = pnlToolboxWrapper.Height; } - // Collapse down vertically to perfectly clear room for lines below it + // Drop the central scrolling categories out of layout calculation completely pnlToolboxCategoriesContainer.Visible = false; - pnlToolboxWrapper.Height = 52; // Height of the button strip elements combined + + // Collapse down precisely matching the visible elements + the structural margin spring + pnlToolboxWrapper.Height = minimumCollapsedHeight; btnToolboxVerticalToggle.Text = "▼"; } + // Force the wrapper container block to evaluate layout rules and enforce spacing margins + pnlToolboxWrapper.PerformLayout(); pnlFunctoids.ResumeLayout(true); _mapper.Invalidate(); } @@ -289,30 +349,23 @@ private void AttachToolboxDragEvents(Control dragHandle) pnlToolboxWrapper.BringToFront(); } }; - dragHandle.MouseMove += (sender, e) => { if (_isDraggingToolbox) { int deltaX = Cursor.Position.X - _toolboxDragStartMousePos.X; int deltaY = Cursor.Position.Y - _toolboxDragStartMousePos.Y; - - // Compute the new target position int newX = _toolboxDragStartPanelPos.X + deltaX; int newY = _toolboxDragStartPanelPos.Y + deltaY; - - // Optional: Clamp the toolbox so it can't be dragged completely off screen edges - if (pnlFunctoids != null) + if (pnlFunctoids != null)// Optional: Clamp the toolbox so it can't be dragged completely off screen edges { newX = Math.Max(0, Math.Min(newX, pnlFunctoids.Width - pnlToolboxWrapper.Width)); newY = Math.Max(0, Math.Min(newY, pnlFunctoids.Height - 30)); } - pnlToolboxWrapper.Location = new Point(newX, newY); _mapper.Invalidate(); // Refresh lines to redraw cleanly around it } }; - dragHandle.MouseUp += (sender, e) => { if (e.Button == MouseButtons.Left) @@ -324,10 +377,8 @@ private void AttachToolboxDragEvents(Control dragHandle) private void RenderToolboxLayout() { if (pnlToolboxCategoriesContainer == null) return; - pnlToolboxCategoriesContainer.SuspendLayout(); pnlToolboxCategoriesContainer.Controls.Clear(); - foreach (var category in toolboxCategories) { category.Width = 205; @@ -335,17 +386,10 @@ private void RenderToolboxLayout() category.Margin = new Padding(6, 0, 0, 6); pnlToolboxCategoriesContainer.Controls.Add(category); } - pnlToolboxCategoriesContainer.ResumeLayout(true); } - - - #endregion - #region Drag and Drop Handling Logic - - private void ToggleWorkspaceDetachment() { // If the workspace isn't detached yet, pop it out into its own separate OS window @@ -397,7 +441,6 @@ private void ToggleWorkspaceDetachment() ReDockWorkspaceToMainForm(); } } - private void ReDockWorkspaceToMainForm() { if (_detachedWorkspaceWindow != null) @@ -431,7 +474,6 @@ private void MakeControlDraggable(Control masterControl) AttachDragEvents(child, masterControl); } } - private void AttachDragEvents(Control eventTriggerControl, Control actualMovingTarget) { eventTriggerControl.MouseDown += (sender, e) => @@ -477,11 +519,8 @@ private void AttachDragEvents(Control eventTriggerControl, Control actualMovingT } }; } - #endregion - #region Embedded Schema Virtual Setup - private void InitializeEmbeddedSchemaLayout(string sourceXmlPath, string targetXmlPath) { // Clear connections and bind data directly into the background Skia registries @@ -506,7 +545,6 @@ private void InitializeEmbeddedSchemaLayout(string sourceXmlPath, string targetX InitializeToolbox(); _mapper.Invalidate(); } - private void BuildCustomSchemaTree(XmlNode node, int depth, bool isTargetSchema) { if (node == null) return; @@ -541,28 +579,24 @@ private void BuildCustomSchemaTree(XmlNode node, int depth, bool isTargetSchema) } } } - #endregion - #region Form Controls & Life Cycle - protected override void OnLoad(EventArgs e) { base.OnLoad(e); + RichTextBoxTarget.ReInitializeAllTextboxes(this); Logger.Info("RichTextBox target initialized successfully."); } - protected override void OnShown(EventArgs e) { base.OnShown(e); RichTextBoxTarget.ReInitializeAllTextboxes(this); Logger.Info("RichTextBox logging attached (UI-safe)."); } - private void Form1_Load(object sender, EventArgs e) { - rbXml.Checked = Properties.Settings.Default.TransformFormat == "XML"; + tt = new ToolTip(); tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder}"); @@ -573,21 +607,18 @@ private void Form1_Load(object sender, EventArgs e) lbxInfileList.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); lbxTargetSchema.Items.AddRange(Properties.Settings.Default.fileList.Split(',')); - lbxInfileList.SelectedIndex = 5; - lbxTargetSchema.SelectedIndex = 5; + lbxInfileList.SelectedIndex = Properties.Settings.Default.SelectedInfile; + lbxTargetSchema.SelectedIndex = Properties.Settings.Default.SelectedTargetSchema; + //lbxTargetSchema.SelectedIndex = 5; btnParse.Enabled = false; } - private void X12UtilsFRM_FormClosing(object sender, FormClosingEventArgs e) { Properties.Settings.Default.Save(); } - #endregion - #region File Processing Actions - private void btnMap_Click(object sender, EventArgs e) { string inputFileName = lbxInfileList.Text; @@ -612,10 +643,9 @@ private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args) { Logger.Info($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); } - private string checkedOption(GroupBox grp) { - var checkedControl = grp.Controls.Cast().FirstOrDefault(c =>((dynamic) c).Checked == true); + var checkedControl = grp.Controls.Cast().FirstOrDefault(c => ((dynamic)c).Checked == true); Logger.Info($"Found control type: {checkedControl.Name}"); return checkedControl.Text; } @@ -628,7 +658,8 @@ private void btnParse_Click(object sender, EventArgs e) { switch (_checkedOption) { - case "HTML": x = X12Tohtml(rtxInterchangeFile.Text); break; + //case "HTML": x = X12Tohtml(rtxInterchangeFile.Text); break; + case "HTML": rtxInterchangeFile.Text = ContentFromFile(lbxInfileList.Text); x = X12Tohtml(rtxInterchangeFile.Text); break; case "XML": rtxInterchangeFile.Text = ContentFromFile(lbxInfileList.Text); X12.Parsing.X12Parser parser = new X12.Parsing.X12Parser(new x12Test.specFinder(), true); @@ -646,13 +677,11 @@ private void btnParse_Click(object sender, EventArgs e) DisplayHtml(x); tabControl1.SelectedIndex = (int)enmTabPages.browser; } - public string X12Tohtml(string x12) { var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); return htmlService.Transform(x12); } - public string X12ToXml(string x12) { if (string.IsNullOrEmpty(x12)) return string.Empty; @@ -665,7 +694,6 @@ public string X12ToXml(string x12) return sr.ReadToEnd(); } } - private void DisplayHtml(string html) { webBrowser1.Navigate("about:blank"); @@ -680,7 +708,6 @@ private void DisplayHtml(string html) webBrowser1.DocumentText = html; webBrowser1.AllowNavigation = true; } - private void btnAddFiles_Click(object sender, EventArgs e) { lbxInfileList.Items.Clear(); @@ -714,10 +741,7 @@ private void btnFindSpec_Click(object sender, EventArgs e) MessageBox.Show($"Spec Not Found for 856"); } } - - #endregion - #region Functional Canvas Drag-Drop Core Engine private Control ResolveActualTargetNode(Control control, Point clientPt) { @@ -746,7 +770,6 @@ private Control ResolveActualTargetNode(Control control, Point clientPt) return control; } - private void pnlFunctoids_DragDrop(object sender, DragEventArgs e) { // 1. Calculate drop coordinates relative to the central pnlFunctoids working area @@ -888,20 +911,27 @@ private Control CreateFunctoid(string text, Point location) return functoidNode; } - #endregion - #region Code Compilation Utilities (Xslt Outbound Maps) + #endregion + private void btnSaveCanvas_Click(object sender, EventArgs e) + { + using (SaveFileDialog sfd = new SaveFileDialog()) + { + sfd.Filter = "Mapping Layout Files (*.map.json)|*.map.json"; + sfd.Title = "Save Canvas Workflow State"; + if (sfd.ShowDialog() == DialogResult.OK) + { + var generator = new XsltMapGenerator(_mapper); - - - #endregion - - // Cleaned up legacy residual functions (trvSource overrides, Hippo wrappers, etc.) - private void rbXml_CheckedChanged(object sender, EventArgs e) { } - private void lbxInputFileList(object sender, EventArgs e) { } + // Saves the visual structural nodes out as JSON mapping rules + generator.SaveCanvasLayout(sfd.FileName, lbxInfileList.Text, "TargetSchema.xsd"); + MessageBox.Show("Canvas layout snapshot preserved successfully!", "State Saved"); + } + } + } private void btnHippaParse_Click(object sender, EventArgs e) { } private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { @@ -919,11 +949,11 @@ private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) Log("Switched to Browser tab."); // e.g., Ensure a document is loaded or focus the webBrowser1 control lblSaveAs.Text = lbxInfileList.Text; - using (SaveFileDialog saveFileDialog = new SaveFileDialog()) - { - saveFileDialog.InitialDirectory = Path.GetDirectoryName(lbxInfileList.Text); - webBrowser1.ShowSaveAsDialog(); - } + //using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + //{ + // saveFileDialog.InitialDirectory = Path.GetDirectoryName(lbxInfileList.Text); + // webBrowser1.ShowSaveAsDialog(); + //} webBrowser1.Focus(); break; @@ -938,14 +968,7 @@ private void lblInterchangeCount_TextChanged(object sender, EventArgs e) int fcount = int.Parse(((Label)sender).Text); btnParse.Enabled = fcount == 1 ? true : false; } - private void rbHtml_CheckedChanged(object sender, EventArgs e) - { - RadioButton r = (RadioButton)sender; - Properties.Settings.Default.TransformFormat = r.Checked ? r.Text : Properties.Settings.Default.TransformFormat; - Log($"TransformFormat:{Properties.Settings.Default.TransformFormat}"); - Properties.Settings.Default.Save(); - } - + public void LinkXsltToSourceXmlFile(string sourceXmlPath, string xsltFilePath) { if (string.IsNullOrEmpty(sourceXmlPath) || !File.Exists(sourceXmlPath)) @@ -1031,34 +1054,28 @@ public string ContentFromFile(string filename/*fullPath*/) } private void lbxfileList_SelectedIndexChanged(object sender, EventArgs e) { + string name = ((ListBox)sender).Name; + switch (name) + { + case "lbxInfileList": + Properties.Settings.Default.SelectedInfile = ((ListBox)sender).SelectedIndex; + break; + case "lbxTargetSchema": + Properties.Settings.Default.SelectedTargetSchema = ((ListBox)sender).SelectedIndex; + break; + } string fileName = ((ListBox)sender).Text; if (String.IsNullOrEmpty(fileName)) return; tt.SetToolTip(lbxInfileList, fileName + " is Selected now.."); lblInterchangeCount.Text = "0"; lblInterchangeCount.Text = "1"; - - - if (chkBrowse.Checked) - { - switch (Path.GetExtension(fileName)) - { - case ".txt": - DisplayHtml(X12ToXml(ContentFromFile(fileName))); - break; - case ".xml": - DisplayHtml(ContentFromFile(fileName)); - tabControl1.SelectedIndex = (int)enmTabPages.browser; - break; - default: - break; - } - return; - } + Properties.Settings.Default.Save(); } - private void label4_Click(object sender, EventArgs e) { } + + } } \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index 0c27fce4..e7854748 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -53,6 +53,9 @@ ..\packages\Fonet.1.0\lib\net20\Fonet.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.8\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + ..\packages\NLog.6.0.2\lib\net46\NLog.dll @@ -81,24 +84,37 @@ C:\Users\tony\.nuget\packages\syncfusion.diagram.base\33.2.6\lib\net8.0-windows7.0\Design\WinForms\Syncfusion.Diagram.Base.Protocol.dll
- - ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + ..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll ..\packages\System.Configuration.ConfigurationManager.10.0.8\lib\net462\System.Configuration.ConfigurationManager.dll - - ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + ..\packages\System.IO.Pipelines.10.0.8\lib\net462\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll - - ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Text.Encodings.Web.10.0.8\lib\net462\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.10.0.8\lib\net462\System.Text.Json.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll + @@ -117,6 +133,7 @@ Form + UserControl @@ -231,6 +248,8 @@ + + \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 3dcbd0f4..391633f5 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -123,6 +123,9 @@ 133, 17 + + 133, 17 + 230, 17 diff --git a/X12UtilsFRM/XsltMapGenerator.cs b/X12UtilsFRM/XsltMapGenerator.cs index 3729b0bf..6ce3d079 100644 --- a/X12UtilsFRM/XsltMapGenerator.cs +++ b/X12UtilsFRM/XsltMapGenerator.cs @@ -1,8 +1,12 @@ -using System; +using NLog.Targets; +using System; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Xml; -using System.Linq; -using System.Collections.Generic; +using X12UtilsFRM; +using System.Text.Json; +using System.IO; namespace PdfX.App.Services { @@ -14,11 +18,6 @@ public XsltMapGenerator(dynamic mapper) { _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); } - - /// - /// CONSOLIDATED LOGIC: Moved directly inside the generator class. - /// Recursively constructs the absolute XPath for a given XML node or attribute. - /// private string BuildAbsoluteXPath(XmlNode node) { if (node == null || node.NodeType == XmlNodeType.Document) return ""; @@ -28,29 +27,17 @@ private string BuildAbsoluteXPath(XmlNode node) string parentPath = BuildAbsoluteXPath(node.ParentNode); return string.IsNullOrEmpty(parentPath) ? node.Name : parentPath + "/" + node.Name; } - - /// - /// Builds the complete XSLT map layout based entirely on internal logic. - /// - /// Name of the input source data file context. - /// Name of this mapping XSLT file to associate. - public string GenerateXsltFromCanvas( - string sourceFileName = "unknown_source_payload.xml", - string xsltFileName = "BizTalkTransformMap.xslt") + public string GenerateXsltFromCanvas(string sourceFileName = "unknown_source_payload.xml", string xsltFileName = "BizTalkTransformMap.xslt") { if (_mapper.Connections == null || _mapper.Connections.Count == 0) { return string.Empty; } - if (!string.IsNullOrEmpty(sourceFileName) && (sourceFileName.Contains("\\") || sourceFileName.Contains("/"))) sourceFileName = System.IO.Path.GetFileName(sourceFileName); - if (!string.IsNullOrEmpty(xsltFileName) && (xsltFileName.Contains("\\") || xsltFileName.Contains("/"))) xsltFileName = System.IO.Path.GetFileName(xsltFileName); - StringBuilder xslt = new StringBuilder(); - // 1. Core Header Definitions xslt.AppendLine(""); xslt.AppendLine(""); xslt.AppendLine(" "); xslt.AppendLine(); - // 2. Global Metadata Parameters xslt.AppendLine(" "); xslt.AppendLine($" "); xslt.AppendLine($" "); xslt.AppendLine(); - // 3. Root Template Match Entry Point with Processing Instruction xslt.AppendLine(" "); xslt.AppendLine(" "); @@ -78,40 +63,30 @@ public string GenerateXsltFromCanvas( xslt.AppendLine(" "); xslt.AppendLine(" "); xslt.AppendLine(); - var flatSchemaRegistry = (IEnumerable)_mapper.FlatSchemaRegistry; var flatTargetSchemaRegistry = (IEnumerable)_mapper.FlatTargetSchemaRegistry; var connections = (IEnumerable)_mapper.Connections; - string sourceRootName = flatSchemaRegistry.FirstOrDefault()?.XmlSourceNode.Name ?? "SOURCE_ROOT"; string targetRootName = flatTargetSchemaRegistry.FirstOrDefault()?.XmlSourceNode.Name ?? "ROOT"; - xslt.AppendLine($" "); xslt.AppendLine($" <{targetRootName}>"); xslt.AppendLine(" "); xslt.AppendLine(); - int variableCounter = 1; Dictionary uniqueScriptMethodsRegistry = new Dictionary(); - var targetBoundConnections = connections.Where(c => c.Target is XmlNode || c.Target.GetType().Name == "SchemaNodeItem").ToList(); - foreach (var conn in targetBoundConnections) { XmlNode targetXmlNode = conn.Target is XmlNode xmlTgt ? xmlTgt : conn.Target.XmlSourceNode; if (targetXmlNode == null) continue; - xslt.AppendLine($" <{targetXmlNode.Name}>"); - - // CASE A: Direct Link (Now calling internal BuildAbsoluteXPath method) if (conn.Source is XmlNode || conn.Source.GetType().Name == "SchemaNodeItem") { XmlNode srcXmlNode = conn.Source is XmlNode xmlSrc ? xmlSrc : conn.Source.XmlSourceNode; string structuralXPath = BuildAbsoluteXPath(srcXmlNode).Replace(sourceRootName + "/", ""); xslt.AppendLine($" "); } - // CASE B: Series-Connected Functoid Chain else if (conn.Source.GetType().Name == "BizTalkFunctoidNode") { string varName = $"var:v{variableCounter}"; @@ -122,13 +97,10 @@ public string GenerateXsltFromCanvas( uniqueScriptMethodsRegistry, connections ); - xslt.AppendLine($" "); xslt.AppendLine($" "); - variableCounter++; } - xslt.AppendLine($" "); } @@ -239,5 +211,47 @@ private string ResolveFunctoidExpression( return $"userCSharp:{functionName}({string.Join(", ", optimizedArguments)})"; } + + public void SaveCanvasLayout(string outputJsonFilePath, string sourcePath, string targetPath) + { + var state = new CanvasSaveState + { + SourceSchemaFile = sourcePath, + TargetSchemaFile = targetPath + }; + + var connections = (IEnumerable)_mapper.Connections; + + // Extract arbitrary Functoids dropped on the layout grid + // Modify based on how your _mapper registers canvas items + foreach (var conn in connections) + { + if (conn.Source.GetType().Name == "BizTalkFunctoidNode") + { + if (!state.Functoids.Any(f => f.Id == conn.Source.Id.ToString())) + { + state.Functoids.Add(new CanvasFunctoidDto + { + Id = conn.Source.Id.ToString(), + FunctoidName = conn.Source.FunctoidName, + X = (float)conn.Source.X, + Y = (float)conn.Source.Y + }); + } + } + + // Map out the visual lines (Wires) + state.Wires.Add(new CanvasConnectionDto + { + SourceType = conn.Source is XmlNode ? "SchemaNode" : "Functoid", + SourceIdOrXPath = conn.Source is XmlNode xmlSrc ? BuildAbsoluteXPath(xmlSrc) : conn.Source.Id.ToString(), + TargetType = conn.Target is XmlNode ? "SchemaNode" : "Functoid", + TargetIdOrXPath = conn.Target is XmlNode xmlTgt ? BuildAbsoluteXPath(xmlTgt) : conn.Target.Id.ToString() + }); + } + + string jsonString = JsonSerializer.Serialize(state, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllText(outputJsonFilePath, jsonString); + } } } \ No newline at end of file diff --git a/X12UtilsFRM/packages.config b/X12UtilsFRM/packages.config index 61c386e5..1de2d228 100644 --- a/X12UtilsFRM/packages.config +++ b/X12UtilsFRM/packages.config @@ -1,6 +1,7 @@  + @@ -10,9 +11,14 @@ - + - - - + + + + + + + + \ No newline at end of file From b89fac4ba2bb9f9736cc113093ab587e420b8756 Mon Sep 17 00:00:00 2001 From: apeiris Date: Wed, 27 May 2026 13:07:55 -0400 Subject: [PATCH 19/22] wip --- X12UtilsFRM/SkiaMapper.cs | 12 ++ X12UtilsFRM/SkiaShared.cs | 1 + X12UtilsFRM/X12UtilsFRM.Designer.cs | 97 ++++++++----- X12UtilsFRM/X12UtilsFRM.cs | 206 +++++++++++++++++++++++++--- X12UtilsFRM/X12UtilsFRM.resx | 9 +- X12UtilsFRM/XsltMapGenerator.cs | 77 +++++++++-- 6 files changed, 331 insertions(+), 71 deletions(-) diff --git a/X12UtilsFRM/SkiaMapper.cs b/X12UtilsFRM/SkiaMapper.cs index c5c3ac87..417fc66d 100644 --- a/X12UtilsFRM/SkiaMapper.cs +++ b/X12UtilsFRM/SkiaMapper.cs @@ -625,6 +625,18 @@ public static void DrawToolboxIcon(SKCanvas canvas, SKPoint position, float size ); } } + public void ClearAllConnections() + { + if (this.Connections != null) + { + this.Connections.Clear(); + } + + + + this.Invalidate(); // Forces the Skia rendering engine to repaint the blank canvas immediately + Logger.Info("Mapping canvas links successfully purged."); + } } public class MappingConnection diff --git a/X12UtilsFRM/SkiaShared.cs b/X12UtilsFRM/SkiaShared.cs index 91c03338..5b58cbc2 100644 --- a/X12UtilsFRM/SkiaShared.cs +++ b/X12UtilsFRM/SkiaShared.cs @@ -20,6 +20,7 @@ public class CanvasFunctoidDto public string FunctoidName { get; set; } public float X { get; set; } public float Y { get; set; } + public string CustomScript { get; set; } } public class CanvasConnectionDto diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index a3ca44b7..9f2afea9 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -33,6 +33,7 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.lblSourceFolder = new System.Windows.Forms.Label(); this.lbxTargetSchema = new System.Windows.Forms.ListBox(); this.btnMap = new System.Windows.Forms.Button(); this.btnFindSpec = new System.Windows.Forms.Button(); @@ -44,6 +45,8 @@ private void InitializeComponent() this.lblSelectedFile = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rbHtml = new System.Windows.Forms.RadioButton(); + this.rbXml = new System.Windows.Forms.RadioButton(); this.btnAddFiles = new System.Windows.Forms.Button(); this.lbxInfileList = new System.Windows.Forms.ListBox(); this.rtLog = new System.Windows.Forms.RichTextBox(); @@ -58,13 +61,13 @@ private void InitializeComponent() this.tbpMap = new System.Windows.Forms.TabPage(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.pnlFunctoids = new System.Windows.Forms.Panel(); + this.button2 = new System.Windows.Forms.Button(); this.btnGenerateXsltFromCanvas = new System.Windows.Forms.Button(); this.trvTarget = new System.Windows.Forms.TreeView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); - this.rbHtml = new System.Windows.Forms.RadioButton(); - this.rbXml = new System.Windows.Forms.RadioButton(); - this.button2 = new System.Windows.Forms.Button(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -127,6 +130,7 @@ private void InitializeComponent() // // splitContainer1.Panel1 // + this.splitContainer1.Panel1.Controls.Add(this.lblSourceFolder); this.splitContainer1.Panel1.Controls.Add(this.lbxTargetSchema); this.splitContainer1.Panel1.Controls.Add(this.btnMap); this.splitContainer1.Panel1.Controls.Add(this.btnFindSpec); @@ -150,6 +154,15 @@ private void InitializeComponent() this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // + // lblSourceFolder + // + this.lblSourceFolder.AutoSize = true; + this.lblSourceFolder.Location = new System.Drawing.Point(5, 5); + this.lblSourceFolder.Name = "lblSourceFolder"; + this.lblSourceFolder.Size = new System.Drawing.Size(105, 13); + this.lblSourceFolder.TabIndex = 15; + this.lblSourceFolder.Text = "Default source folder"; + // // lbxTargetSchema // this.lbxTargetSchema.FormattingEnabled = true; @@ -285,10 +298,37 @@ private void InitializeComponent() this.groupBox1.TabStop = false; this.groupBox1.Text = "Transform.."; // + // rbHtml + // + this.rbHtml.AutoSize = true; + this.rbHtml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToHTML; + this.rbHtml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToHTML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.rbHtml.Location = new System.Drawing.Point(68, 24); + this.rbHtml.Margin = new System.Windows.Forms.Padding(2); + this.rbHtml.Name = "rbHtml"; + this.rbHtml.Size = new System.Drawing.Size(74, 24); + this.rbHtml.TabIndex = 1; + this.rbHtml.Text = "HTML"; + this.rbHtml.UseVisualStyleBackColor = true; + // + // rbXml + // + this.rbXml.AutoSize = true; + this.rbXml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToXML; + this.rbXml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToXML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.rbXml.Location = new System.Drawing.Point(4, 24); + this.rbXml.Margin = new System.Windows.Forms.Padding(2); + this.rbXml.Name = "rbXml"; + this.rbXml.Size = new System.Drawing.Size(63, 24); + this.rbXml.TabIndex = 0; + this.rbXml.TabStop = true; + this.rbXml.Text = "XML"; + this.rbXml.UseVisualStyleBackColor = true; + // // btnAddFiles // this.btnAddFiles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnAddFiles.Location = new System.Drawing.Point(4, 30); + this.btnAddFiles.Location = new System.Drawing.Point(5, 38); this.btnAddFiles.Margin = new System.Windows.Forms.Padding(2); this.btnAddFiles.Name = "btnAddFiles"; this.btnAddFiles.Size = new System.Drawing.Size(122, 25); @@ -457,6 +497,15 @@ private void InitializeComponent() this.pnlFunctoids.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragDrop); this.pnlFunctoids.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragEnter); // + // button2 + // + this.button2.Location = new System.Drawing.Point(3, 630); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(97, 29); + this.button2.TabIndex = 2; + this.button2.Text = "Transform"; + this.button2.UseVisualStyleBackColor = true; + // // btnGenerateXsltFromCanvas // this.btnGenerateXsltFromCanvas.Location = new System.Drawing.Point(106, 630); @@ -470,6 +519,7 @@ private void InitializeComponent() // trvTarget // this.trvTarget.Dock = System.Windows.Forms.DockStyle.Fill; + this.trvTarget.LineColor = System.Drawing.Color.Empty; this.trvTarget.Location = new System.Drawing.Point(0, 0); this.trvTarget.Name = "trvTarget"; this.trvTarget.Size = new System.Drawing.Size(441, 519); @@ -479,41 +529,9 @@ private void InitializeComponent() // this.saveFileDialog1.DefaultExt = "Save As.."; // - // rbHtml - // - this.rbHtml.AutoSize = true; - this.rbHtml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToHTML; - this.rbHtml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToHTML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.rbHtml.Location = new System.Drawing.Point(68, 24); - this.rbHtml.Margin = new System.Windows.Forms.Padding(2); - this.rbHtml.Name = "rbHtml"; - this.rbHtml.Size = new System.Drawing.Size(74, 24); - this.rbHtml.TabIndex = 1; - this.rbHtml.Text = "HTML"; - this.rbHtml.UseVisualStyleBackColor = true; - // - // rbXml + // openFileDialog1 // - this.rbXml.AutoSize = true; - this.rbXml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToXML; - this.rbXml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToXML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.rbXml.Location = new System.Drawing.Point(4, 24); - this.rbXml.Margin = new System.Windows.Forms.Padding(2); - this.rbXml.Name = "rbXml"; - this.rbXml.Size = new System.Drawing.Size(63, 24); - this.rbXml.TabIndex = 0; - this.rbXml.TabStop = true; - this.rbXml.Text = "XML"; - this.rbXml.UseVisualStyleBackColor = true; - // - // button2 - // - this.button2.Location = new System.Drawing.Point(3, 630); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(97, 29); - this.button2.TabIndex = 2; - this.button2.Text = "Transform"; - this.button2.UseVisualStyleBackColor = true; + this.openFileDialog1.FileName = "openFileDialog1"; // // X12UtilsFRM // @@ -587,6 +605,9 @@ private void InitializeComponent() private System.Windows.Forms.Label label2; private System.Windows.Forms.Label lblSaveAs; private System.Windows.Forms.Button button2; + private System.Windows.Forms.Label lblSourceFolder; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index fb5d0946..66f2c282 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -93,9 +93,9 @@ public X12UtilsFRM() _mapper.DragEnter += pnlFunctoids_DragEnter; _mapper.DragOver += pnlFunctoids_DragEnter; _mapper.DragDrop += pnlFunctoids_DragDrop; - - + + } @@ -149,7 +149,7 @@ private void InitializeToolbox() btnToolboxVerticalToggle.Click += ToggleToolboxVertical_Click; pnlHeaderBar.Controls.Add(btnToolboxVerticalToggle); #endregion vertical toggle button - + pnlHeaderBar.Paint += (sender, e) => // Handle title text and icon drawing manually via GDI+ to Skia bridging { var info = new SKImageInfo(pnlHeaderBar.Width, pnlHeaderBar.Height); @@ -181,34 +181,55 @@ private void InitializeToolbox() } } }; + + Panel pnlCanvasToolsBottomBar = new Panel { Dock = DockStyle.Bottom, - Height = 45, + Height = 100, BackColor = Color.FromArgb(225, 230, 245), Padding = new Padding(10, 6, 10, 6), BorderStyle = BorderStyle.None }; - pnlCanvasToolsBottomBar.Paint += (s, e) => { + pnlCanvasToolsBottomBar.Paint += (s, e) => + { using (var pen = new Pen(Color.FromArgb(190, 200, 220), 1)) { e.Graphics.DrawLine(pen, 0, 0, pnlCanvasToolsBottomBar.Width, 0); } }; + int bButtonRows = 2; // bottom button rows int buttonWidth = (ToolboxWidth - 10) / 2; + int buttonHeight = 35; + + + Button btnClearCanvas = new Button + { + Text = "Clear Canvas", + Size = new Size(buttonWidth, buttonHeight), + Location = new Point(10, 6), + FlatStyle = FlatStyle.Popup, + BackColor = Color.FromArgb(210, 220, 240), + Font = new Font("Segoe UI", 9, FontStyle.Regular), + Cursor = Cursors.Hand + }; + + btnClearCanvas.Click += btnClearCanvas_Click; + + Button btnTransform = new Button { Text = "Transform", Size = new Size(buttonWidth, 32), - Location = new Point(10, 6), + Location = new Point(10, 6 + (buttonHeight * 2)), FlatStyle = FlatStyle.Popup, BackColor = Color.FromArgb(210, 220, 240), Font = new Font("Segoe UI", 9, FontStyle.Regular), Cursor = Cursors.Hand }; - //btnTransform.Click += Transform_Click; btnTransform.Click += btnGenerateXsltFromCanvas_Click; - Button btnSave = new Button + //---------------------SAVE------------------------------- + Button btnSave = new Button { Text = "Save", Size = new Size(buttonWidth, 32), @@ -218,10 +239,26 @@ private void InitializeToolbox() Font = new Font("Segoe UI", 9, FontStyle.Regular), Cursor = Cursors.Hand }; - btnSave.Click += btnSaveCanvas_Click; + btnSave.Click += btnSaveCanvas_Click; + //---------------------LOAD Canvas------------------------------- + Button btnLoadCanvas = new Button + { + Text = "Load Canvas", + Size = new Size(buttonWidth, 32), + Location = new Point(15 + buttonWidth, 6 + buttonHeight), + FlatStyle = FlatStyle.Popup, + BackColor = Color.FromArgb(210, 220, 240), + Font = new Font("Segoe UI", 9, FontStyle.Regular), + Cursor = Cursors.Hand + }; + btnLoadCanvas.Click += btnLoadCanvas_Click; + + + pnlCanvasToolsBottomBar.Controls.Add(btnClearCanvas); pnlCanvasToolsBottomBar.Controls.Add(btnTransform); pnlCanvasToolsBottomBar.Controls.Add(btnSave); + pnlCanvasToolsBottomBar.Controls.Add(btnLoadCanvas); pnlToolboxWrapper.Controls.Add(pnlCanvasToolsBottomBar); // 4. Create the main categories scroll container view (Fills remaining space) @@ -232,7 +269,7 @@ private void InitializeToolbox() FlowDirection = FlowDirection.TopDown, WrapContents = false, AutoScroll = true, - Margin= new Padding(0,5,0,0), + Margin = new Padding(0, 5, 0, 0), Padding = new Padding(10, 18, 18, 10) }; pnlToolboxWrapper.Controls.Add(pnlToolboxCategoriesContainer); @@ -307,6 +344,141 @@ private void ToggleToolboxVertical_Click(object sender, EventArgs e) pnlFunctoids.ResumeLayout(true); _mapper.Invalidate(); } + + private void btnClearCanvas_Click(object sender, EventArgs e) + { + DialogResult result = MessageBox.Show( + "Are you sure you want to clear the entire canvas? This will delete all functoids and connection wires.", + "Clear Canvas", + MessageBoxButtons.YesNo, + MessageBoxIcon.Warning + ); + + if (result == DialogResult.Yes) + { + // 2. Erase the connection data collection lines + _mapper.ClearAllConnections(); + + // 3. Scan the UI collection and purge temporary Functoid controls safely + // Loop backwards to safely delete controls while modifying the collection + for (int i = pnlFunctoids.Controls.Count - 1; i >= 0; i--) + { + Control ctrl = pnlFunctoids.Controls[i]; + + // Check if it's a dynamic functoid capsule (and not the underlying SkiaMapper canvas itself) + if (ctrl is BizTalkFunctoidNode) + { + pnlFunctoids.Controls.RemoveAt(i); + ctrl.Dispose(); // Free system layout memory resources instantly + } + } + + Logger.Info("Master canvas layout workspace resetting completed."); + } + + + } + + private dynamic FindNodeByXPath(IEnumerable schemaRegistry, string xpath) + { + var generator = new XsltMapGenerator(_mapper); + foreach (var nodeItem in schemaRegistry) + { + XmlNode xmlNode = nodeItem is XmlNode node ? node : nodeItem.XmlSourceNode; + if (xmlNode != null) + { + // Internal path matching wrapper + string computedPath = generator.GetNodePathForLookup(xmlNode); + if (computedPath == xpath) + { + return nodeItem; + } + } + } + return null; + } + + private void btnLoadCanvas_Click(object sender, EventArgs e) + { + using (OpenFileDialog ofd = new OpenFileDialog()) + { + ofd.Filter = "Mapping Layout Files (*.map.json)|*.map.json"; + + if (ofd.ShowDialog() == DialogResult.OK) + { + string jsonRaw = File.ReadAllText(ofd.FileName); + var savedState = System.Text.Json.JsonSerializer.Deserialize(jsonRaw); + + // 1. Clear active connections and existing manual functoids from canvas + _mapper.Connections.Clear(); + + // Clean up old visual functoid controls if your mapper holds a separate list + // _mapper.Functoids?.Clear(); + + // Track newly generated functoids mapped from their JSON layout coordinate string "X_Y" + var runtimeFunctoidRegistry = new Dictionary(); + + // 2. Rehydrate and spawn Functoid nodes onto the canvas interface + foreach (var f in savedState.Functoids) + { + Control newFunctoid = CreateFunctoid(f.FunctoidName, new System.Drawing.Point((int)f.X, (int)f.Y)); + + // CRITICAL FIX: Mount the control physically onto the WinForms Canvas Surface Container! + pnlFunctoids.Controls.Add(newFunctoid); + newFunctoid.BringToFront(); + + // Map the original file ID token to this live runtime instance pointer + runtimeFunctoidRegistry[f.Id] = newFunctoid; + } + + // 3. Reconnect Wires + foreach (var wire in savedState.Wires) + { + dynamic sourcePointer = null; + dynamic targetPointer = null; + + // Resolve Source Pointer + if (wire.SourceType == "SchemaNode") + { + // Find matching node inside left schema tree via XPath helper + sourcePointer = FindNodeByXPath(_mapper.FlatSchemaRegistry, wire.SourceIdOrXPath); + } + else if (wire.SourceType == "Functoid") + { + runtimeFunctoidRegistry.TryGetValue(wire.SourceIdOrXPath, out sourcePointer); + } + + // Resolve Target Pointer + if (wire.TargetType == "SchemaNode") + { + // Find matching node inside right schema tree via XPath helper + targetPointer = FindNodeByXPath(_mapper.FlatTargetSchemaRegistry, wire.TargetIdOrXPath); + } + else if (wire.TargetType == "Functoid") + { + runtimeFunctoidRegistry.TryGetValue(wire.TargetIdOrXPath, out targetPointer); + } + + // 4. Append wire connection link if both ends were successfully resolved + if (sourcePointer != null && targetPointer != null) + { + // Create connection structure match matching your canvas model definition + // ❌ ERROR LINE + // _mapper.Connections.Add(new ConnectionItem(sourcePointer, targetPointer)); + _mapper.Connections.Add(new MappingConnection { Source = sourcePointer, Target = targetPointer }); + } + } + + // If your _mapper object handles the canvas lifecycle UI itself: + _mapper.Invalidate(); + // 5. Explicitly force the Skia Graphics Canvas control to refresh and repaint the connections + // skiaControl.Invalidate(); + + MessageBox.Show("Canvas wire layouts successfully loaded and re-drawn!", "State Restored"); + } + } + } + private void ToggleToolbox_Click(object sender, EventArgs e) { _isToolboxExpanded = !_isToolboxExpanded; @@ -584,7 +756,7 @@ private void BuildCustomSchemaTree(XmlNode node, int depth, bool isTargetSchema) protected override void OnLoad(EventArgs e) { base.OnLoad(e); - + RichTextBoxTarget.ReInitializeAllTextboxes(this); Logger.Info("RichTextBox target initialized successfully."); } @@ -596,7 +768,7 @@ protected override void OnShown(EventArgs e) } private void Form1_Load(object sender, EventArgs e) { - + tt = new ToolTip(); tt.SetToolTip(btnAddFiles, $"Import X12 Inbound files from {Properties.Settings.Default.X12Folder}"); @@ -611,6 +783,8 @@ private void Form1_Load(object sender, EventArgs e) lbxTargetSchema.SelectedIndex = Properties.Settings.Default.SelectedTargetSchema; //lbxTargetSchema.SelectedIndex = 5; + lblSourceFolder.Text = $"Source Folder: {Properties.Settings.Default.X12Folder}"; + btnParse.Enabled = false; } private void X12UtilsFRM_FormClosing(object sender, FormClosingEventArgs e) @@ -968,7 +1142,7 @@ private void lblInterchangeCount_TextChanged(object sender, EventArgs e) int fcount = int.Parse(((Label)sender).Text); btnParse.Enabled = fcount == 1 ? true : false; } - + public void LinkXsltToSourceXmlFile(string sourceXmlPath, string xsltFilePath) { if (string.IsNullOrEmpty(sourceXmlPath) || !File.Exists(sourceXmlPath)) @@ -1054,7 +1228,7 @@ public string ContentFromFile(string filename/*fullPath*/) } private void lbxfileList_SelectedIndexChanged(object sender, EventArgs e) { - string name = ((ListBox)sender).Name; + string name = ((ListBox)sender).Name; switch (name) { case "lbxInfileList": @@ -1069,13 +1243,13 @@ private void lbxfileList_SelectedIndexChanged(object sender, EventArgs e) tt.SetToolTip(lbxInfileList, fileName + " is Selected now.."); lblInterchangeCount.Text = "0"; lblInterchangeCount.Text = "1"; - Properties.Settings.Default.Save(); + Properties.Settings.Default.Save(); } private void label4_Click(object sender, EventArgs e) { } - + } } \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.resx b/X12UtilsFRM/X12UtilsFRM.resx index 391633f5..5abc6b1c 100644 --- a/X12UtilsFRM/X12UtilsFRM.resx +++ b/X12UtilsFRM/X12UtilsFRM.resx @@ -123,10 +123,13 @@ 133, 17 - - 133, 17 - 230, 17 + + 365, 17 + + + 532, 17 + \ No newline at end of file diff --git a/X12UtilsFRM/XsltMapGenerator.cs b/X12UtilsFRM/XsltMapGenerator.cs index 6ce3d079..acb33e30 100644 --- a/X12UtilsFRM/XsltMapGenerator.cs +++ b/X12UtilsFRM/XsltMapGenerator.cs @@ -125,6 +125,12 @@ public string GenerateXsltFromCanvas(string sourceFileName = "unknown_source_pay return xslt.ToString(); } + public string GetNodePathForLookup(XmlNode node) + { + return BuildAbsoluteXPath(node); + } + + private string ResolveFunctoidExpression( dynamic functoidNode, string sourceRootName, @@ -222,36 +228,79 @@ public void SaveCanvasLayout(string outputJsonFilePath, string sourcePath, strin var connections = (IEnumerable)_mapper.Connections; - // Extract arbitrary Functoids dropped on the layout grid - // Modify based on how your _mapper registers canvas items foreach (var conn in connections) { - if (conn.Source.GetType().Name == "BizTalkFunctoidNode") + // --- 1. RESOLVE SOURCE IDENTIFIER --- + string sourceIdOrXPath; + string sourceType; + + // Safely check if it's an XmlNode OR your custom SchemaNodeItem wrapper + if (conn.Source is XmlNode || conn.Source.GetType().Name == "SchemaNodeItem") { - if (!state.Functoids.Any(f => f.Id == conn.Source.Id.ToString())) + sourceType = "SchemaNode"; + XmlNode xmlSrc = conn.Source is XmlNode xmlNode ? xmlNode : conn.Source.XmlSourceNode; + sourceIdOrXPath = BuildAbsoluteXPath(xmlSrc); + } + else // It's a BizTalkFunctoidNode + { + sourceType = "Functoid"; + string functoidId = conn.Source.GetHashCode().ToString(); + sourceIdOrXPath = functoidId; + + if (!state.Functoids.Any(f => f.Id == functoidId)) { state.Functoids.Add(new CanvasFunctoidDto { - Id = conn.Source.Id.ToString(), + Id = functoidId, FunctoidName = conn.Source.FunctoidName, - X = (float)conn.Source.X, - Y = (float)conn.Source.Y + X = (float)conn.Source.Location.X, // Using Location.X since raw .X property doesn't exist + Y = (float)conn.Source.Location.Y, // Using Location.Y since raw .Y property doesn't exist + CustomScript = conn.Source.CustomScript + }); + } + } + + // --- 2. RESOLVE TARGET IDENTIFIER --- + string targetIdOrXPath; + string targetType; + + if (conn.Target is XmlNode || conn.Target.GetType().Name == "SchemaNodeItem") + { + targetType = "SchemaNode"; + XmlNode xmlTgt = conn.Target is XmlNode xmlNode ? xmlNode : conn.Target.XmlSourceNode; + targetIdOrXPath = BuildAbsoluteXPath(xmlTgt); + } + else // It's a BizTalkFunctoidNode target + { + targetType = "Functoid"; + string functoidId = conn.Target.GetHashCode().ToString(); + targetIdOrXPath = functoidId; + + if (!state.Functoids.Any(f => f.Id == functoidId)) + { + state.Functoids.Add(new CanvasFunctoidDto + { + Id = functoidId, + FunctoidName = conn.Target.FunctoidName, + X = (float)conn.Target.Location.X, + Y = (float)conn.Target.Location.Y }); } } - // Map out the visual lines (Wires) + // --- 3. ADD REGISTERED WIRE LINK --- state.Wires.Add(new CanvasConnectionDto { - SourceType = conn.Source is XmlNode ? "SchemaNode" : "Functoid", - SourceIdOrXPath = conn.Source is XmlNode xmlSrc ? BuildAbsoluteXPath(xmlSrc) : conn.Source.Id.ToString(), - TargetType = conn.Target is XmlNode ? "SchemaNode" : "Functoid", - TargetIdOrXPath = conn.Target is XmlNode xmlTgt ? BuildAbsoluteXPath(xmlTgt) : conn.Target.Id.ToString() + SourceType = sourceType, + SourceIdOrXPath = sourceIdOrXPath, + TargetType = targetType, + TargetIdOrXPath = targetIdOrXPath }); } - string jsonString = JsonSerializer.Serialize(state, new JsonSerializerOptions { WriteIndented = true }); + var options = new JsonSerializerOptions { WriteIndented = true }; + string jsonString = JsonSerializer.Serialize(state, options); File.WriteAllText(outputJsonFilePath, jsonString); } } -} \ No newline at end of file +} From 6844e4e110365eb1d4cab172a62804d1880ee70e Mon Sep 17 00:00:00 2001 From: apeiris Date: Wed, 27 May 2026 21:16:23 -0400 Subject: [PATCH 20/22] wip --- X12UtilsFRM/App.config | 4 +- X12UtilsFRM/Properties/Settings.Designer.cs | 4 +- X12UtilsFRM/Properties/Settings.settings | 4 +- X12UtilsFRM/X12UtilsFRM.Designer.cs | 134 +++++++++++---- X12UtilsFRM/X12UtilsFRM.cs | 174 +++++++++++++++++++- X12UtilsFRM/X12UtilsFRM.csproj | 1 + X12UtilsFRM/XsltTransformer.cs | 41 +++++ 7 files changed, 320 insertions(+), 42 deletions(-) create mode 100644 X12UtilsFRM/XsltTransformer.cs diff --git a/X12UtilsFRM/App.config b/X12UtilsFRM/App.config index 99043489..ac0734eb 100644 --- a/X12UtilsFRM/App.config +++ b/X12UtilsFRM/App.config @@ -32,10 +32,10 @@ False - True + False - False + True False diff --git a/X12UtilsFRM/Properties/Settings.Designer.cs b/X12UtilsFRM/Properties/Settings.Designer.cs index 134cb396..ff470d03 100644 --- a/X12UtilsFRM/Properties/Settings.Designer.cs +++ b/X12UtilsFRM/Properties/Settings.Designer.cs @@ -109,7 +109,7 @@ public bool throwExceptions { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] + [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool ParseToXML { get { return ((bool)(this["ParseToXML"])); @@ -121,7 +121,7 @@ public bool ParseToXML { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] + [global::System.Configuration.DefaultSettingValueAttribute("True")] public bool ParseToHTML { get { return ((bool)(this["ParseToHTML"])); diff --git a/X12UtilsFRM/Properties/Settings.settings b/X12UtilsFRM/Properties/Settings.settings index 9a0ad1fe..2ee6ba04 100644 --- a/X12UtilsFRM/Properties/Settings.settings +++ b/X12UtilsFRM/Properties/Settings.settings @@ -24,10 +24,10 @@ False - True + False - False + True False diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 9f2afea9..0a7e6267 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -33,13 +33,16 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.grpFileExtensionFilter = new System.Windows.Forms.GroupBox(); + this.rbtfXslt = new System.Windows.Forms.RadioButton(); + this.rbtfTxt = new System.Windows.Forms.RadioButton(); + this.rbtfXml = new System.Windows.Forms.RadioButton(); this.lblSourceFolder = new System.Windows.Forms.Label(); this.lbxTargetSchema = new System.Windows.Forms.ListBox(); this.btnMap = new System.Windows.Forms.Button(); this.btnFindSpec = new System.Windows.Forms.Button(); this.btnHippaParse = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button(); - this.btnParse = new System.Windows.Forms.Button(); this.lblInterchangeCount = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.lblSelectedFile = new System.Windows.Forms.Label(); @@ -68,12 +71,15 @@ private void InitializeComponent() this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.btnParse = new System.Windows.Forms.Button(); + this.btnApplyXslt = new System.Windows.Forms.Button(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); + this.grpFileExtensionFilter.SuspendLayout(); this.groupBox1.SuspendLayout(); this.browser.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); @@ -130,6 +136,8 @@ private void InitializeComponent() // // splitContainer1.Panel1 // + this.splitContainer1.Panel1.Controls.Add(this.btnApplyXslt); + this.splitContainer1.Panel1.Controls.Add(this.grpFileExtensionFilter); this.splitContainer1.Panel1.Controls.Add(this.lblSourceFolder); this.splitContainer1.Panel1.Controls.Add(this.lbxTargetSchema); this.splitContainer1.Panel1.Controls.Add(this.btnMap); @@ -154,6 +162,60 @@ private void InitializeComponent() this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // + // grpFileExtensionFilter + // + this.grpFileExtensionFilter.Controls.Add(this.rbtfXslt); + this.grpFileExtensionFilter.Controls.Add(this.rbtfTxt); + this.grpFileExtensionFilter.Controls.Add(this.rbtfXml); + this.grpFileExtensionFilter.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.grpFileExtensionFilter.Location = new System.Drawing.Point(8, 277); + this.grpFileExtensionFilter.Margin = new System.Windows.Forms.Padding(2); + this.grpFileExtensionFilter.Name = "grpFileExtensionFilter"; + this.grpFileExtensionFilter.Padding = new System.Windows.Forms.Padding(2); + this.grpFileExtensionFilter.Size = new System.Drawing.Size(356, 53); + this.grpFileExtensionFilter.TabIndex = 16; + this.grpFileExtensionFilter.TabStop = false; + this.grpFileExtensionFilter.Text = "Filter"; + // + // rbtfXslt + // + this.rbtfXslt.AutoSize = true; + this.rbtfXslt.Location = new System.Drawing.Point(126, 23); + this.rbtfXslt.Margin = new System.Windows.Forms.Padding(2); + this.rbtfXslt.Name = "rbtfXslt"; + this.rbtfXslt.Size = new System.Drawing.Size(54, 24); + this.rbtfXslt.TabIndex = 5; + this.rbtfXslt.Text = "xslt"; + this.rbtfXslt.UseVisualStyleBackColor = true; + this.rbtfXslt.CheckedChanged += new System.EventHandler(this.extensionFilter_CheckedChanged); + // + // rbtfTxt + // + this.rbtfTxt.AutoSize = true; + this.rbtfTxt.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToHTML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.rbtfTxt.Location = new System.Drawing.Point(72, 23); + this.rbtfTxt.Margin = new System.Windows.Forms.Padding(2); + this.rbtfTxt.Name = "rbtfTxt"; + this.rbtfTxt.Size = new System.Drawing.Size(47, 24); + this.rbtfTxt.TabIndex = 4; + this.rbtfTxt.Text = "txt"; + this.rbtfTxt.UseVisualStyleBackColor = true; + this.rbtfTxt.CheckedChanged += new System.EventHandler(this.extensionFilter_CheckedChanged); + // + // rbtfXml + // + this.rbtfXml.AutoSize = true; + this.rbtfXml.Checked = true; + this.rbtfXml.Location = new System.Drawing.Point(17, 24); + this.rbtfXml.Margin = new System.Windows.Forms.Padding(2); + this.rbtfXml.Name = "rbtfXml"; + this.rbtfXml.Size = new System.Drawing.Size(53, 24); + this.rbtfXml.TabIndex = 3; + this.rbtfXml.TabStop = true; + this.rbtfXml.Text = "xml"; + this.rbtfXml.UseVisualStyleBackColor = true; + this.rbtfXml.CheckedChanged += new System.EventHandler(this.extensionFilter_CheckedChanged); + // // lblSourceFolder // this.lblSourceFolder.AutoSize = true; @@ -162,14 +224,15 @@ private void InitializeComponent() this.lblSourceFolder.Size = new System.Drawing.Size(105, 13); this.lblSourceFolder.TabIndex = 15; this.lblSourceFolder.Text = "Default source folder"; + this.lblSourceFolder.Click += new System.EventHandler(this.lblSourceFolder_Click); // // lbxTargetSchema // this.lbxTargetSchema.FormattingEnabled = true; - this.lbxTargetSchema.Location = new System.Drawing.Point(2, 283); + this.lbxTargetSchema.Location = new System.Drawing.Point(4, 331); this.lbxTargetSchema.Margin = new System.Windows.Forms.Padding(2); this.lbxTargetSchema.Name = "lbxTargetSchema"; - this.lbxTargetSchema.Size = new System.Drawing.Size(356, 186); + this.lbxTargetSchema.Size = new System.Drawing.Size(356, 160); this.lbxTargetSchema.TabIndex = 13; this.lbxTargetSchema.SelectedIndexChanged += new System.EventHandler(this.lbxfileList_SelectedIndexChanged); // @@ -224,20 +287,6 @@ private void InitializeComponent() this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); this.button1.UseVisualStyleBackColor = true; // - // btnParse - // - this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnParse.Location = new System.Drawing.Point(203, 518); - this.btnParse.Margin = new System.Windows.Forms.Padding(2); - this.btnParse.Name = "btnParse"; - this.btnParse.Size = new System.Drawing.Size(122, 25); - this.btnParse.TabIndex = 7; - this.btnParse.Text = "<< Parse"; - this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnParse.UseVisualStyleBackColor = true; - this.btnParse.Click += new System.EventHandler(this.btnParse_Click); - // // lblInterchangeCount // this.lblInterchangeCount.AutoSize = true; @@ -301,10 +350,7 @@ private void InitializeComponent() // rbHtml // this.rbHtml.AutoSize = true; - this.rbHtml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToHTML; - this.rbHtml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToHTML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.rbHtml.Location = new System.Drawing.Point(68, 24); - this.rbHtml.Margin = new System.Windows.Forms.Padding(2); + this.rbHtml.Location = new System.Drawing.Point(72, 23); this.rbHtml.Name = "rbHtml"; this.rbHtml.Size = new System.Drawing.Size(74, 24); this.rbHtml.TabIndex = 1; @@ -314,10 +360,8 @@ private void InitializeComponent() // rbXml // this.rbXml.AutoSize = true; - this.rbXml.Checked = global::X12UtilsFRM.Properties.Settings.Default.ParseToXML; - this.rbXml.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::X12UtilsFRM.Properties.Settings.Default, "ParseToXML", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.rbXml.Location = new System.Drawing.Point(4, 24); - this.rbXml.Margin = new System.Windows.Forms.Padding(2); + this.rbXml.Checked = true; + this.rbXml.Location = new System.Drawing.Point(5, 23); this.rbXml.Name = "rbXml"; this.rbXml.Size = new System.Drawing.Size(63, 24); this.rbXml.TabIndex = 0; @@ -533,6 +577,33 @@ private void InitializeComponent() // this.openFileDialog1.FileName = "openFileDialog1"; // + // btnParse + // + this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnParse.Location = new System.Drawing.Point(211, 508); + this.btnParse.Margin = new System.Windows.Forms.Padding(2); + this.btnParse.Name = "btnParse"; + this.btnParse.Size = new System.Drawing.Size(122, 34); + this.btnParse.TabIndex = 7; + this.btnParse.Text = "<< Parse"; + this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnParse.UseVisualStyleBackColor = true; + this.btnParse.Click += new System.EventHandler(this.btnParse_Click); + // + // btnApplyXslt + // + this.btnApplyXslt.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnApplyXslt.Location = new System.Drawing.Point(211, 552); + this.btnApplyXslt.Margin = new System.Windows.Forms.Padding(2); + this.btnApplyXslt.Name = "btnApplyXslt"; + this.btnApplyXslt.Size = new System.Drawing.Size(133, 34); + this.btnApplyXslt.TabIndex = 17; + this.btnApplyXslt.Text = "Apply Xslt"; + this.btnApplyXslt.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnApplyXslt.UseVisualStyleBackColor = true; + this.btnApplyXslt.Click += new System.EventHandler(this.btnApplyXslt_Click); + // // X12UtilsFRM // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -552,6 +623,8 @@ private void InitializeComponent() this.splitContainer1.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); + this.grpFileExtensionFilter.ResumeLayout(false); + this.grpFileExtensionFilter.PerformLayout(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.browser.ResumeLayout(false); @@ -575,8 +648,6 @@ private void InitializeComponent() private System.Windows.Forms.TabPage browser; private System.Windows.Forms.ListBox lbxInfileList; private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.RadioButton rbHtml; - private System.Windows.Forms.RadioButton rbXml; private System.Windows.Forms.Button btnAddFiles; private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.Label lblInterchangeCount; @@ -584,7 +655,6 @@ private void InitializeComponent() private System.Windows.Forms.Label lblSelectedFile; private System.Windows.Forms.Label label1; private System.Windows.Forms.RichTextBox rtxInterchangeFile; - private System.Windows.Forms.Button btnParse; private System.Windows.Forms.WebBrowser webBrowser1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button btnFindSpec; @@ -608,6 +678,14 @@ private void InitializeComponent() private System.Windows.Forms.Label lblSourceFolder; private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.GroupBox grpFileExtensionFilter; + private System.Windows.Forms.RadioButton rbtfXslt; + private System.Windows.Forms.RadioButton rbtfTxt; + private System.Windows.Forms.RadioButton rbtfXml; + private System.Windows.Forms.RadioButton rbHtml; + private System.Windows.Forms.RadioButton rbXml; + private System.Windows.Forms.Button btnApplyXslt; + private System.Windows.Forms.Button btnParse; } } diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 66f2c282..217ac744 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -94,7 +94,7 @@ public X12UtilsFRM() _mapper.DragOver += pnlFunctoids_DragEnter; _mapper.DragDrop += pnlFunctoids_DragDrop; - + SetupListboxContextMenus(); @@ -766,6 +766,21 @@ protected override void OnShown(EventArgs e) RichTextBoxTarget.ReInitializeAllTextboxes(this); Logger.Info("RichTextBox logging attached (UI-safe)."); } + + private void PopulateFileList(string folderPath) + { + if (Directory.Exists(folderPath)) + { + lbxInfileList.Items.Clear(); + lbxInfileList.Items.AddRange(Directory.GetFiles(folderPath, "*.txt")); + lbxInfileList.Items.AddRange(Directory.GetFiles(folderPath, "*.xml")); + lbxInfileList.Items.AddRange(Directory.GetFiles(folderPath, "*.xslt")); + } + else + { + MessageBox.Show($"The specified folder path does not exist: {folderPath}", "Folder Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } private void Form1_Load(object sender, EventArgs e) { @@ -783,7 +798,7 @@ private void Form1_Load(object sender, EventArgs e) lbxTargetSchema.SelectedIndex = Properties.Settings.Default.SelectedTargetSchema; //lbxTargetSchema.SelectedIndex = 5; - lblSourceFolder.Text = $"Source Folder: {Properties.Settings.Default.X12Folder}"; + lblSourceFolder.Text = $"Source Folder: {Properties.Settings.Default.X12Folder} (..)"; btnParse.Enabled = false; } @@ -817,16 +832,22 @@ private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args) { Logger.Info($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); } - private string checkedOption(GroupBox grp) + private (string Text,bool IsChecked) checkedOption(GroupBox grp) { var checkedControl = grp.Controls.Cast().FirstOrDefault(c => ((dynamic)c).Checked == true); - Logger.Info($"Found control type: {checkedControl.Name}"); - return checkedControl.Text; + if (checkedControl != null) + { + Logger.Info($"Found control type: {checkedControl.Name}"); + return (checkedControl.Text, true); + } + else return (null, false); + + } private void btnParse_Click(object sender, EventArgs e) { string x = ""; - string _checkedOption = checkedOption(groupBox1); + var ( _checkedOption, isChecked) = checkedOption(groupBox1); try { @@ -848,9 +869,10 @@ private void btnParse_Click(object sender, EventArgs e) MessageBox.Show(ex.Message); return; } - DisplayHtml(x); + DisplayHtml(_checkedOption); tabControl1.SelectedIndex = (int)enmTabPages.browser; } + public string X12Tohtml(string x12) { var htmlService = new X12HtmlTransformationService(new X12EdiParsingService(Properties.Settings.Default.SurppressParsingComments, new x12Test.specFinder())); @@ -1089,6 +1111,8 @@ private Control CreateFunctoid(string text, Point location) #region Code Compilation Utilities (Xslt Outbound Maps) #endregion + + private void btnSaveCanvas_Click(object sender, EventArgs e) { using (SaveFileDialog sfd = new SaveFileDialog()) @@ -1245,11 +1269,145 @@ private void lbxfileList_SelectedIndexChanged(object sender, EventArgs e) lblInterchangeCount.Text = "1"; Properties.Settings.Default.Save(); } - private void label4_Click(object sender, EventArgs e) + + + private void lblSourceFolder_Click(object sender, EventArgs e) + { + using (FolderBrowserDialog fb = new FolderBrowserDialog()) + { + fb.Description = "Select the X12 Source Folder"; + + + // Assign the initial directory from your application properties + // Adjust the exact settings path if your namespace differs (e.g., Properties.Settings.Default...) + if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.X12Folder) && + System.IO.Directory.Exists(Properties.Settings.Default.X12Folder)) + { + fb.SelectedPath= Properties.Settings.Default.X12Folder; + } + + // Show the dialog and check if the user clicked OK + if (fb.ShowDialog() == DialogResult.OK) + { + // Update the setting with the new path + Properties.Settings.Default.X12Folder = fb.SelectedPath; + + // Save the settings persistantly + Properties.Settings.Default.Save(); + + // Optional: Update the label or a textbox text to reflect the new selection + + lblSourceFolder.Text = $"Source Folder: {fb.SelectedPath} (..)"; + lbxfileList_SelectedIndexChanged(lbxInfileList, null); + PopulateFileList(Properties.Settings.Default.X12Folder); + + + } + } + } + + private void extensionFilter_CheckedChanged(object sender, EventArgs e) + { + var (text, isChecked) = checkedOption(grpFileExtensionFilter); + if(!isChecked) return; + switch (text.ToLower()) { + case "txt": + lbxTargetSchema.Items.Clear(); + lbxTargetSchema.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); + break; + case "xml": + lbxTargetSchema.Items.Clear(); + lbxTargetSchema.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); break; + case "xslt": + lbxTargetSchema.Items.Clear(); + lbxTargetSchema.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xslt")); + break; + } + + + } + + private void btnApplyXslt_Click(object sender, EventArgs e) { + + XsltTransformer.ApplyXslt(lbxInfileList.Text,lbxTargetSchema.Text,Path.Combine(Path.GetFileNameWithoutExtension(lbxInfileList.Text),"out.xml")); + } + private void MenuBrowse_Click(object sender, EventArgs e) + { + // Identify which ListBox was right-clicked + ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender; + ContextMenuStrip ownerMenu = (ContextMenuStrip)clickedItem.Owner; + ListBox parentControl = ownerMenu.SourceControl as ListBox; + string htmlContent = $@"{ContentFromFile(parentControl.Text)}"; + DisplayHtml(htmlContent); + tabControl1.SelectedIndex = (int)enmTabPages.browser; } + private void MenuDelete_Click(object sender, EventArgs e) + { + // Identify which ListBox was right-clicked + ToolStripMenuItem menuItem = (ToolStripMenuItem)sender; + ContextMenuStrip owner = (ContextMenuStrip)menuItem.Owner; + ListBox targetListBox = (ListBox)owner.SourceControl; + // Check if an item is selected to be deleted + if (targetListBox.SelectedItem != null) + { + string removedItem = targetListBox.SelectedItem.ToString(); + + // Remove from UI + targetListBox.Items.Remove(targetListBox.SelectedItem); + + Logger.Info($"Removed '{removedItem}' from {targetListBox.Name}"); + } + else + { + MessageBox.Show("Please select an item first to delete.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + + private void SetupListboxContextMenus() + { + // Create the ContextMenuStrip + ContextMenuStrip listboxMenu = new ContextMenuStrip(); + + // Create the Browse item + ToolStripMenuItem menuBrowse = new ToolStripMenuItem("Browse..."); + menuBrowse.Click += MenuBrowse_Click; + + // Create the Delete item + ToolStripMenuItem menuDelete = new ToolStripMenuItem("Delete"); + menuDelete.Click += MenuDelete_Click; + + // Add items to the context menu + listboxMenu.Items.Add(menuBrowse); + listboxMenu.Items.Add(new ToolStripSeparator()); // Optional visual separator line + listboxMenu.Items.Add(menuDelete); + + // Assign the same context menu to both ListBoxes + lbxInfileList.ContextMenuStrip = listboxMenu; + lbxTargetSchema.ContextMenuStrip = listboxMenu; + + // Optional: Select the ListBox item automatically on a right-click + lbxInfileList.MouseDown += ListBox_MouseDown; + lbxTargetSchema.MouseDown += ListBox_MouseDown; + } + + private void ListBox_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + ListBox listBox = (ListBox)sender; + // Find the index of the item corresponding to the coordinates of the mouse click + int index = listBox.IndexFromPoint(e.Location); + + if (index != ListBox.NoMatches) + { + listBox.SelectedIndex = index; // Programmatically select it + } + } + } } } \ No newline at end of file diff --git a/X12UtilsFRM/X12UtilsFRM.csproj b/X12UtilsFRM/X12UtilsFRM.csproj index e7854748..e2ffac21 100644 --- a/X12UtilsFRM/X12UtilsFRM.csproj +++ b/X12UtilsFRM/X12UtilsFRM.csproj @@ -153,6 +153,7 @@ + ResXFileCodeGenerator Resources.Designer.cs diff --git a/X12UtilsFRM/XsltTransformer.cs b/X12UtilsFRM/XsltTransformer.cs new file mode 100644 index 00000000..258d2cfb --- /dev/null +++ b/X12UtilsFRM/XsltTransformer.cs @@ -0,0 +1,41 @@ +using NLog; +using System; +using System.Xml; +using System.Xml.Xsl; + +public class XsltTransformer +{ + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + public static void ApplyXslt(string xmlFilePath, string xsltFilePath, string outputFilePath) + { + try + { + // 1. Enable script execution inside the XSLT (critical for BizTalk maps) + XsltSettings settings = new XsltSettings(enableDocumentFunction: true, enableScript: true); + + // 2. Load the XSLT stylesheet + XslCompiledTransform xslt = new XslCompiledTransform(); + xslt.Load(xsltFilePath, settings, new XmlUrlResolver()); + + // 3. Optional: Set up standard writer settings for clean, indented output + XmlWriterSettings writerSettings = new XmlWriterSettings + { + Indent = true, + IndentChars = " ", + NewLineOnAttributes = false + }; + + // 4. Execute the transformation and save to disk + using (XmlWriter writer = XmlWriter.Create(outputFilePath, writerSettings)) + { + xslt.Transform(xmlFilePath, writer); + } + + Logger.Info($"Transformation successful! Output saved to: {outputFilePath}"); + } + catch (Exception ex) + { + Logger.Error($"Error running transformation: {ex.Message}\n {ex.InnerException}"); + } + } +} \ No newline at end of file From a2bfcc9241b734768db9284e8f68fa0d5de7489a Mon Sep 17 00:00:00 2001 From: apeiris Date: Thu, 28 May 2026 09:13:19 -0400 Subject: [PATCH 21/22] wip --- X12UtilsFRM/X12UtilsFRM.Designer.cs | 85 ++++++++++------------------- X12UtilsFRM/X12UtilsFRM.cs | 82 ++++++++++++++-------------- X12UtilsFRM/XsltMapGenerator.cs | 76 ++++++++++++++++++++------ 3 files changed, 129 insertions(+), 114 deletions(-) diff --git a/X12UtilsFRM/X12UtilsFRM.Designer.cs b/X12UtilsFRM/X12UtilsFRM.Designer.cs index 0a7e6267..40b3484e 100644 --- a/X12UtilsFRM/X12UtilsFRM.Designer.cs +++ b/X12UtilsFRM/X12UtilsFRM.Designer.cs @@ -33,6 +33,7 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.parse = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.btnApplyXslt = new System.Windows.Forms.Button(); this.grpFileExtensionFilter = new System.Windows.Forms.GroupBox(); this.rbtfXslt = new System.Windows.Forms.RadioButton(); this.rbtfTxt = new System.Windows.Forms.RadioButton(); @@ -43,6 +44,7 @@ private void InitializeComponent() this.btnFindSpec = new System.Windows.Forms.Button(); this.btnHippaParse = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button(); + this.btnParse = new System.Windows.Forms.Button(); this.lblInterchangeCount = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.lblSelectedFile = new System.Windows.Forms.Label(); @@ -64,15 +66,11 @@ private void InitializeComponent() this.tbpMap = new System.Windows.Forms.TabPage(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.pnlFunctoids = new System.Windows.Forms.Panel(); - this.button2 = new System.Windows.Forms.Button(); - this.btnGenerateXsltFromCanvas = new System.Windows.Forms.Button(); this.trvTarget = new System.Windows.Forms.TreeView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); - this.btnParse = new System.Windows.Forms.Button(); - this.btnApplyXslt = new System.Windows.Forms.Button(); this.tabControl1.SuspendLayout(); this.parse.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -86,7 +84,6 @@ private void InitializeComponent() this.FormLocations.SuspendLayout(); this.tbpMap.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); - this.pnlFunctoids.SuspendLayout(); this.SuspendLayout(); // // statusStrip1 @@ -162,6 +159,19 @@ private void InitializeComponent() this.splitContainer1.SplitterWidth = 3; this.splitContainer1.TabIndex = 0; // + // btnApplyXslt + // + this.btnApplyXslt.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnApplyXslt.Location = new System.Drawing.Point(211, 552); + this.btnApplyXslt.Margin = new System.Windows.Forms.Padding(2); + this.btnApplyXslt.Name = "btnApplyXslt"; + this.btnApplyXslt.Size = new System.Drawing.Size(133, 34); + this.btnApplyXslt.TabIndex = 17; + this.btnApplyXslt.Text = "Apply Xslt"; + this.btnApplyXslt.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnApplyXslt.UseVisualStyleBackColor = true; + this.btnApplyXslt.Click += new System.EventHandler(this.btnApplyXslt_Click); + // // grpFileExtensionFilter // this.grpFileExtensionFilter.Controls.Add(this.rbtfXslt); @@ -287,6 +297,20 @@ private void InitializeComponent() this.toolTip1.SetToolTip(this.button1, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); this.button1.UseVisualStyleBackColor = true; // + // btnParse + // + this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnParse.Location = new System.Drawing.Point(211, 508); + this.btnParse.Margin = new System.Windows.Forms.Padding(2); + this.btnParse.Name = "btnParse"; + this.btnParse.Size = new System.Drawing.Size(122, 34); + this.btnParse.TabIndex = 7; + this.btnParse.Text = "<< Parse"; + this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); + this.btnParse.UseVisualStyleBackColor = true; + this.btnParse.Click += new System.EventHandler(this.btnParse_Click); + // // lblInterchangeCount // this.lblInterchangeCount.AutoSize = true; @@ -531,8 +555,6 @@ private void InitializeComponent() // // pnlFunctoids // - this.pnlFunctoids.Controls.Add(this.button2); - this.pnlFunctoids.Controls.Add(this.btnGenerateXsltFromCanvas); this.pnlFunctoids.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlFunctoids.Location = new System.Drawing.Point(3, 3); this.pnlFunctoids.Name = "pnlFunctoids"; @@ -541,25 +563,6 @@ private void InitializeComponent() this.pnlFunctoids.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragDrop); this.pnlFunctoids.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlFunctoids_DragEnter); // - // button2 - // - this.button2.Location = new System.Drawing.Point(3, 630); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(97, 29); - this.button2.TabIndex = 2; - this.button2.Text = "Transform"; - this.button2.UseVisualStyleBackColor = true; - // - // btnGenerateXsltFromCanvas - // - this.btnGenerateXsltFromCanvas.Location = new System.Drawing.Point(106, 630); - this.btnGenerateXsltFromCanvas.Name = "btnGenerateXsltFromCanvas"; - this.btnGenerateXsltFromCanvas.Size = new System.Drawing.Size(97, 29); - this.btnGenerateXsltFromCanvas.TabIndex = 1; - this.btnGenerateXsltFromCanvas.Text = "Transform"; - this.btnGenerateXsltFromCanvas.UseVisualStyleBackColor = true; - this.btnGenerateXsltFromCanvas.Click += new System.EventHandler(this.btnGenerateXsltFromCanvas_Click); - // // trvTarget // this.trvTarget.Dock = System.Windows.Forms.DockStyle.Fill; @@ -577,33 +580,6 @@ private void InitializeComponent() // this.openFileDialog1.FileName = "openFileDialog1"; // - // btnParse - // - this.btnParse.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnParse.Location = new System.Drawing.Point(211, 508); - this.btnParse.Margin = new System.Windows.Forms.Padding(2); - this.btnParse.Name = "btnParse"; - this.btnParse.Size = new System.Drawing.Size(122, 34); - this.btnParse.TabIndex = 7; - this.btnParse.Text = "<< Parse"; - this.btnParse.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.toolTip1.SetToolTip(this.btnParse, "Adds Inbound X12 EDI files saved into $\"{Properties.Settings.Default.X12Flist}\" "); - this.btnParse.UseVisualStyleBackColor = true; - this.btnParse.Click += new System.EventHandler(this.btnParse_Click); - // - // btnApplyXslt - // - this.btnApplyXslt.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnApplyXslt.Location = new System.Drawing.Point(211, 552); - this.btnApplyXslt.Margin = new System.Windows.Forms.Padding(2); - this.btnApplyXslt.Name = "btnApplyXslt"; - this.btnApplyXslt.Size = new System.Drawing.Size(133, 34); - this.btnApplyXslt.TabIndex = 17; - this.btnApplyXslt.Text = "Apply Xslt"; - this.btnApplyXslt.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnApplyXslt.UseVisualStyleBackColor = true; - this.btnApplyXslt.Click += new System.EventHandler(this.btnApplyXslt_Click); - // // X12UtilsFRM // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -633,7 +609,6 @@ private void InitializeComponent() this.FormLocations.ResumeLayout(false); this.tbpMap.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); - this.pnlFunctoids.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -669,12 +644,10 @@ private void InitializeComponent() private System.Windows.Forms.Panel pnlFunctoids; private System.Windows.Forms.ListBox lbxTargetSchema; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.Button btnGenerateXsltFromCanvas; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.SaveFileDialog saveFileDialog1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label lblSaveAs; - private System.Windows.Forms.Button button2; private System.Windows.Forms.Label lblSourceFolder; private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; private System.Windows.Forms.OpenFileDialog openFileDialog1; diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index 217ac744..a30a71ee 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -181,7 +181,10 @@ private void InitializeToolbox() } } }; - + // bottom tool bar with action buttons + int bButtonRows = 2; // bottom button rows + int buttonWidth = (ToolboxWidth - 10) / 2; + int buttonHeight = 30; Panel pnlCanvasToolsBottomBar = new Panel { @@ -198,13 +201,8 @@ private void InitializeToolbox() e.Graphics.DrawLine(pen, 0, 0, pnlCanvasToolsBottomBar.Width, 0); } }; - int bButtonRows = 2; // bottom button rows - int buttonWidth = (ToolboxWidth - 10) / 2; - int buttonHeight = 35; - - Button btnClearCanvas = new Button - { + Button btnClearCanvas = new Button { Text = "Clear Canvas", Size = new Size(buttonWidth, buttonHeight), Location = new Point(10, 6), @@ -213,39 +211,35 @@ private void InitializeToolbox() Font = new Font("Segoe UI", 9, FontStyle.Regular), Cursor = Cursors.Hand }; - btnClearCanvas.Click += btnClearCanvas_Click; - - Button btnTransform = new Button - { - Text = "Transform", - Size = new Size(buttonWidth, 32), - Location = new Point(10, 6 + (buttonHeight * 2)), + Button btnSave = new Button { + Text = "Save", + Size = new Size(buttonWidth, buttonHeight), + Location = new Point(15 + buttonWidth, 6), FlatStyle = FlatStyle.Popup, BackColor = Color.FromArgb(210, 220, 240), Font = new Font("Segoe UI", 9, FontStyle.Regular), Cursor = Cursors.Hand }; - btnTransform.Click += btnGenerateXsltFromCanvas_Click; - //---------------------SAVE------------------------------- - Button btnSave = new Button - { - Text = "Save", + btnSave.Click += btnSaveCanvas_Click; + + + Button btnTransform = new Button { + Text = "Transform", Size = new Size(buttonWidth, 32), - Location = new Point(15 + buttonWidth, 6), + Location = new Point(10, 10 + (buttonHeight)), FlatStyle = FlatStyle.Popup, BackColor = Color.FromArgb(210, 220, 240), Font = new Font("Segoe UI", 9, FontStyle.Regular), Cursor = Cursors.Hand }; - btnSave.Click += btnSaveCanvas_Click; - //---------------------LOAD Canvas------------------------------- - Button btnLoadCanvas = new Button - { + btnTransform.Click += btnGenerateXsltFromCanvas_Click; + + Button btnLoadCanvas = new Button { Text = "Load Canvas", - Size = new Size(buttonWidth, 32), - Location = new Point(15 + buttonWidth, 6 + buttonHeight), + Size = new Size(buttonWidth, buttonHeight), + Location = new Point(15 + buttonWidth, 10 + buttonHeight), FlatStyle = FlatStyle.Popup, BackColor = Color.FromArgb(210, 220, 240), Font = new Font("Segoe UI", 9, FontStyle.Regular), @@ -253,6 +247,10 @@ private void InitializeToolbox() }; btnLoadCanvas.Click += btnLoadCanvas_Click; + + + + pnlCanvasToolsBottomBar.Controls.Add(btnClearCanvas); @@ -832,7 +830,7 @@ private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args) { Logger.Info($"IC#={args.InterchangeControlNumber}-FG={args.FunctionalGroupControlNumber}-Segment={args.Segment}{args.Message}"); } - private (string Text,bool IsChecked) checkedOption(GroupBox grp) + private (string Text, bool IsChecked) checkedOption(GroupBox grp) { var checkedControl = grp.Controls.Cast().FirstOrDefault(c => ((dynamic)c).Checked == true); if (checkedControl != null) @@ -842,12 +840,12 @@ private void parser_ParserWarning(object sender, X12ParserWarningEventArgs args) } else return (null, false); - + } private void btnParse_Click(object sender, EventArgs e) { string x = ""; - var ( _checkedOption, isChecked) = checkedOption(groupBox1); + var (_checkedOption, isChecked) = checkedOption(groupBox1); try { @@ -1226,7 +1224,7 @@ private void btnGenerateXsltFromCanvas_Click(object sender, EventArgs e) var generator = new XsltMapGenerator(_mapper); string directory = Path.GetDirectoryName(lbxInfileList.Text); string filenameWithoutExt = Path.GetFileNameWithoutExtension(lbxInfileList.Text); - string targetSchemaFileName = Path.Combine(directory, "Transforms", filenameWithoutExt + ".xslt"); + string targetSchemaFileName = Path.Combine(directory, filenameWithoutExt + ".xslt"); string transformDirectory = Path.GetDirectoryName(targetSchemaFileName); if (!Directory.Exists(transformDirectory)) { @@ -1269,21 +1267,21 @@ private void lbxfileList_SelectedIndexChanged(object sender, EventArgs e) lblInterchangeCount.Text = "1"; Properties.Settings.Default.Save(); } - + private void lblSourceFolder_Click(object sender, EventArgs e) { using (FolderBrowserDialog fb = new FolderBrowserDialog()) { fb.Description = "Select the X12 Source Folder"; - + // Assign the initial directory from your application properties // Adjust the exact settings path if your namespace differs (e.g., Properties.Settings.Default...) if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.X12Folder) && System.IO.Directory.Exists(Properties.Settings.Default.X12Folder)) { - fb.SelectedPath= Properties.Settings.Default.X12Folder; + fb.SelectedPath = Properties.Settings.Default.X12Folder; } // Show the dialog and check if the user clicked OK @@ -1309,28 +1307,30 @@ private void lblSourceFolder_Click(object sender, EventArgs e) private void extensionFilter_CheckedChanged(object sender, EventArgs e) { var (text, isChecked) = checkedOption(grpFileExtensionFilter); - if(!isChecked) return; - switch (text.ToLower()) { + if (!isChecked) return; + switch (text.ToLower()) + { case "txt": lbxTargetSchema.Items.Clear(); lbxTargetSchema.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.txt")); break; - case "xml": + case "xml": lbxTargetSchema.Items.Clear(); lbxTargetSchema.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xml")); break; case "xslt": lbxTargetSchema.Items.Clear(); lbxTargetSchema.Items.AddRange(Directory.GetFiles(Properties.Settings.Default.X12Folder, "*.xslt")); - break; + break; } - + } private void btnApplyXslt_Click(object sender, EventArgs e) { - - XsltTransformer.ApplyXslt(lbxInfileList.Text,lbxTargetSchema.Text,Path.Combine(Path.GetFileNameWithoutExtension(lbxInfileList.Text),"out.xml")); + string infile = lbxInfileList.Text; + string outXml = Path.Combine(Path.GetDirectoryName(infile),$"{Path.GetFileNameWithoutExtension(infile)}_out.xml" ); + XsltTransformer.ApplyXslt(infile, lbxTargetSchema.Text,outXml ); } private void MenuBrowse_Click(object sender, EventArgs e) @@ -1366,7 +1366,7 @@ private void MenuDelete_Click(object sender, EventArgs e) MessageBox.Show("Please select an item first to delete.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } - + private void SetupListboxContextMenus() { diff --git a/X12UtilsFRM/XsltMapGenerator.cs b/X12UtilsFRM/XsltMapGenerator.cs index acb33e30..2ee4665e 100644 --- a/X12UtilsFRM/XsltMapGenerator.cs +++ b/X12UtilsFRM/XsltMapGenerator.cs @@ -33,26 +33,62 @@ public string GenerateXsltFromCanvas(string sourceFileName = "unknown_source_pay { return string.Empty; } + if (!string.IsNullOrEmpty(sourceFileName) && (sourceFileName.Contains("\\") || sourceFileName.Contains("/"))) sourceFileName = System.IO.Path.GetFileName(sourceFileName); + if (!string.IsNullOrEmpty(xsltFileName) && (xsltFileName.Contains("\\") || xsltFileName.Contains("/"))) xsltFileName = System.IO.Path.GetFileName(xsltFileName); + + var flatSchemaRegistry = (IEnumerable)_mapper.FlatSchemaRegistry; + var flatTargetSchemaRegistry = (IEnumerable)_mapper.FlatTargetSchemaRegistry; + var connections = (IEnumerable)_mapper.Connections; + + // Extract the actual root XmlNodes to inspect their namespaces + XmlNode sourceRootNode = flatSchemaRegistry.FirstOrDefault()?.XmlSourceNode; + XmlNode targetRootNode = flatTargetSchemaRegistry.FirstOrDefault()?.XmlSourceNode; + + string sourceRootName = sourceRootNode?.Name ?? "SOURCE_ROOT"; + string targetRootName = targetRootNode?.Name ?? "ROOT"; + + // --- DYNAMIC NAMESPACE DISCOVERY --- + string sourceNamespaceDecl = ""; + string targetNamespaceDecl = ""; + + if (sourceRootNode != null && !string.IsNullOrEmpty(sourceRootNode.Prefix) && !string.IsNullOrEmpty(sourceRootNode.NamespaceURI)) + { + sourceNamespaceDecl = $"xmlns:{sourceRootNode.Prefix}=\"{sourceRootNode.NamespaceURI}\""; + } + if (targetRootNode != null && !string.IsNullOrEmpty(targetRootNode.Prefix) && !string.IsNullOrEmpty(targetRootNode.NamespaceURI)) + { + targetNamespaceDecl = $"xmlns:{targetRootNode.Prefix}=\"{targetRootNode.NamespaceURI}\""; + } + StringBuilder xslt = new StringBuilder(); - // 1. Core Header Definitions + + // 1. Core Header Definitions (with dynamically injected namespaces) xslt.AppendLine(""); xslt.AppendLine(""); xslt.AppendLine(" "); xslt.AppendLine(); + // 2. Global Metadata Parameters xslt.AppendLine(" "); xslt.AppendLine($" "); xslt.AppendLine($" "); xslt.AppendLine(); + // 3. Root Template Match Entry Point with Processing Instruction xslt.AppendLine(" "); xslt.AppendLine(" "); @@ -63,23 +99,22 @@ public string GenerateXsltFromCanvas(string sourceFileName = "unknown_source_pay xslt.AppendLine(" "); xslt.AppendLine(" "); xslt.AppendLine(); - var flatSchemaRegistry = (IEnumerable)_mapper.FlatSchemaRegistry; - var flatTargetSchemaRegistry = (IEnumerable)_mapper.FlatTargetSchemaRegistry; - var connections = (IEnumerable)_mapper.Connections; - string sourceRootName = flatSchemaRegistry.FirstOrDefault()?.XmlSourceNode.Name ?? "SOURCE_ROOT"; - string targetRootName = flatTargetSchemaRegistry.FirstOrDefault()?.XmlSourceNode.Name ?? "ROOT"; + xslt.AppendLine($" "); xslt.AppendLine($" <{targetRootName}>"); xslt.AppendLine(" "); xslt.AppendLine(); + int variableCounter = 1; Dictionary uniqueScriptMethodsRegistry = new Dictionary(); var targetBoundConnections = connections.Where(c => c.Target is XmlNode || c.Target.GetType().Name == "SchemaNodeItem").ToList(); + foreach (var conn in targetBoundConnections) { XmlNode targetXmlNode = conn.Target is XmlNode xmlTgt ? xmlTgt : conn.Target.XmlSourceNode; if (targetXmlNode == null) continue; + xslt.AppendLine($" <{targetXmlNode.Name}>"); if (conn.Source is XmlNode || conn.Source.GetType().Name == "SchemaNodeItem") { @@ -132,10 +167,10 @@ public string GetNodePathForLookup(XmlNode node) private string ResolveFunctoidExpression( - dynamic functoidNode, - string sourceRootName, - Dictionary scriptRegistry, - IEnumerable connections) + dynamic functoidNode, + string sourceRootName, + Dictionary scriptRegistry, + IEnumerable connections) { var inputLinks = connections.Where(c => object.ReferenceEquals(c.Target, functoidNode)).ToList(); List optimizedArguments = new List(); @@ -149,7 +184,6 @@ private string ResolveFunctoidExpression( XmlNode inputXmlNode = inputConn.Source is XmlNode xmlIn ? xmlIn : inputConn.Source.XmlSourceNode; if (inputXmlNode != null) { - // Now calling internal BuildAbsoluteXPath method directly string inputPath = BuildAbsoluteXPath(inputXmlNode).Replace(sourceRootName + "/", ""); optimizedArguments.Add($"string({inputPath})"); formalParameters.Add($"string p_arg{argIdx}"); @@ -171,26 +205,35 @@ private string ResolveFunctoidExpression( int argumentCount = optimizedArguments.Count; string functionName = $"Fct_{toolName}_{argumentCount}"; + string paramsJoined = string.Join(", ", formalParameters); if (!scriptRegistry.ContainsKey(functionName)) { StringBuilder methodBody = new StringBuilder(); - string paramsJoined = string.Join(", ", formalParameters); switch (toolName) { case "Concatenate": - methodBody.AppendLine($" public string {functionName}(params string[] segments)"); + // GENERATES: public string Fct_Concatenate_2(string p_arg1, string p_arg2) + methodBody.AppendLine($" public string {functionName}({paramsJoined})"); methodBody.AppendLine(" {"); - methodBody.AppendLine(" return string.Concat(segments);"); + + // Get the variable names: p_arg1, p_arg2, etc. + var catVars = formalParameters.Select(p => p.Split(' ')[1]); + methodBody.AppendLine($" return string.Concat({string.Join(", ", catVars)});"); methodBody.AppendLine(" }"); break; case "Add": - methodBody.AppendLine($" public string {functionName}(params string[] numbers)"); + // GENERATES: public string Fct_Add_2(string p_arg1, string p_arg2) + methodBody.AppendLine($" public string {functionName}({paramsJoined})"); methodBody.AppendLine(" {"); methodBody.AppendLine(" double total = 0;"); - methodBody.AppendLine(" foreach(var num in numbers) { if (double.TryParse(num, out double val)) total += val; }"); + foreach (var param in formalParameters) + { + string varName = param.Split(' ')[1]; + methodBody.AppendLine($" if (double.TryParse({varName}, out double val_{varName})) total += val_{varName};"); + } methodBody.AppendLine(" return total.ToString();"); methodBody.AppendLine(" }"); break; @@ -217,7 +260,6 @@ private string ResolveFunctoidExpression( return $"userCSharp:{functionName}({string.Join(", ", optimizedArguments)})"; } - public void SaveCanvasLayout(string outputJsonFilePath, string sourcePath, string targetPath) { var state = new CanvasSaveState From 4ae73782cfcab849edfadadaed67cd0df43865b0 Mon Sep 17 00:00:00 2001 From: apeiris Date: Thu, 28 May 2026 20:38:30 -0400 Subject: [PATCH 22/22] ShowFormWith (Form) added --- X12UtilsFRM/ControlExtensions.cs | 28 ++++++++++++++++ X12UtilsFRM/X12UtilsFRM.cs | 55 ++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 X12UtilsFRM/ControlExtensions.cs diff --git a/X12UtilsFRM/ControlExtensions.cs b/X12UtilsFRM/ControlExtensions.cs new file mode 100644 index 00000000..5344813d --- /dev/null +++ b/X12UtilsFRM/ControlExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +public static class ControlExtensions +{ + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); + + private const int WM_SETREDRAW = 0x000B; + + public static void BeginUpdate(this Control control) + { + if (control != null && !control.IsDisposed && control.IsHandleCreated) + { + SendMessage(control.Handle, WM_SETREDRAW, 0, IntPtr.Zero); + } + } + + public static void EndUpdate(this Control control) + { + if (control != null && !control.IsDisposed && control.IsHandleCreated) + { + SendMessage(control.Handle, WM_SETREDRAW, 1, IntPtr.Zero); + control.Invalidate(true); // Forces a full redraw of the control and its children + } + } +} diff --git a/X12UtilsFRM/X12UtilsFRM.cs b/X12UtilsFRM/X12UtilsFRM.cs index a30a71ee..cc863844 100644 --- a/X12UtilsFRM/X12UtilsFRM.cs +++ b/X12UtilsFRM/X12UtilsFRM.cs @@ -1234,6 +1234,8 @@ private void btnGenerateXsltFromCanvas_Click(object sender, EventArgs e) File.WriteAllText(targetSchemaFileName, compiledXslt); LinkXsltToSourceXmlFile(lbxInfileList.Text, targetSchemaFileName); + ShowFormWith(compiledXslt); + MessageBox.Show($"XSLT Map generated successfully at:\n{targetSchemaFileName}", "Success"); } catch (Exception ex) @@ -1241,6 +1243,53 @@ private void btnGenerateXsltFromCanvas_Click(object sender, EventArgs e) MessageBox.Show($"Failed to generate XSLT map layout:\n{ex.Message}", "Generation Error"); } } + + private void ShowFormWith(string stringToShow) + { + using (Form previewForm = new Form { Text = "Compiled Script XSLT Output", Width = 700, Height = 550, StartPosition = FormStartPosition.CenterParent }) + { + // 1. Create the Close Button + Button btnClose = new Button + { + Text = "Close", + DialogResult = DialogResult.Cancel, // Automatically closes the dialog when clicked + Width = 100, + Height = 30, + Location = new Point(560, 10) // Positions it on the right side of the bottom panel + }; + + // Ensure pressing the Enter or Esc key also closes the form naturally + previewForm.CancelButton = btnClose; + previewForm.AcceptButton = btnClose; + + // 2. Create a bottom panel to hold the button neatly + Panel buttonPanel = new Panel + { + Dock = DockStyle.Bottom, + Height = 50 + }; + buttonPanel.Controls.Add(btnClose); + + // 3. Create the Text Box (Change DockStyle.Fill behavior to respect the bottom panel) + TextBox txtPreview = new TextBox + { + Multiline = true, + ScrollBars = ScrollBars.Both, + Dock = DockStyle.Fill, + Font = new Font("Consolas", 10f), + WordWrap = false, + Text = stringToShow, + ReadOnly = true + }; + + // 4. Add controls to the form (order matters slightly for layout nesting) + previewForm.Controls.Add(txtPreview); + previewForm.Controls.Add(buttonPanel); // Docked to bottom, so TextBox fills the remaining space + + previewForm.ShowDialog(this); + } + } + public string ContentFromFile(string filename/*fullPath*/) { using (Stream ediFile = new FileStream(filename, FileMode.Open, FileAccess.Read)) @@ -1340,8 +1389,10 @@ private void MenuBrowse_Click(object sender, EventArgs e) ContextMenuStrip ownerMenu = (ContextMenuStrip)clickedItem.Owner; ListBox parentControl = ownerMenu.SourceControl as ListBox; string htmlContent = $@"{ContentFromFile(parentControl.Text)}"; - DisplayHtml(htmlContent); - tabControl1.SelectedIndex = (int)enmTabPages.browser; + // DisplayHtml(htmlContent); + + ShowFormWith(ContentFromFile(parentControl.Text)); + //tabControl1.SelectedIndex = (int)enmTabPages.browser; } private void MenuDelete_Click(object sender, EventArgs e)