From ce9e9e182efd7beb263c852de604109d6b60602d Mon Sep 17 00:00:00 2001 From: John Date: Thu, 29 Jul 2021 18:28:12 +0000 Subject: [PATCH] C2021-026 Parent/Child applicability in RO Editor --- .../Exe/RefObj/CmpRpt/CmpRpt.cs | 8 +- .../Exe/RefObj/ROEditor/RODefFrm.cs | 344 ++++++++++++++---- .../Exe/RefObj/ROEditor/RODefFrm.resx | 142 ++++---- .../Exe/RefObj/ROEditor/ROEditor.cs | 86 ++++- .../Exe/RefObj/ROEditor/ROEditor.resx | 22 +- .../Exe/RefObj/ROEditor/RO_FST.cs | 4 +- .../LibSource/RODBInterface/RODBInterface.cs | 122 ++++++- .../LibSource/RODBInterface/SqlRODB.cs | 3 + .../LibSource/RODBInterface/VlnXml.cs | 211 ++++++++--- .../LibSource/ROField/ROField.cs | 36 +- .../LibSource/ctlXMLEditLib/ctlXMLEdit.cs | 266 ++++++++++++-- .../Config/ROFSTLookup.cs | 44 ++- PROMS/Volian.Controls.Library/DisplayRO.cs | 41 ++- .../Volian.Controls.Library/DisplayReports.cs | 10 + .../Volian.Controls.Library/StepTabRibbon.cs | 16 + PROMS/Volian.Controls.Library/vlnTreeView.cs | 11 +- 16 files changed, 1103 insertions(+), 263 deletions(-) diff --git a/PROMS/ReferencedObjects/Exe/RefObj/CmpRpt/CmpRpt.cs b/PROMS/ReferencedObjects/Exe/RefObj/CmpRpt/CmpRpt.cs index 3c4a40ea..821ddbca 100644 --- a/PROMS/ReferencedObjects/Exe/RefObj/CmpRpt/CmpRpt.cs +++ b/PROMS/ReferencedObjects/Exe/RefObj/CmpRpt/CmpRpt.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: CmpRpt.cs $ $Revision: 3 $ @@ -264,7 +264,7 @@ namespace CmpRpt for (int i = cnt - 1; i >= 0; i--) headers.Add(reversehdrs[i]); myrodb.MyDBID = tbl; - rptele.Show(myrodb, headers, showStat); + rptele.Show(myrodb, headers, showStat, PCChildren); // this will write data to print.tmp file in the RO folder Application.DoEvents(); headers.Clear(); reversehdrs.Clear(); @@ -296,6 +296,7 @@ namespace CmpRpt } } } + public static string[] PCChildren; //C2021-026 list of Parent/Child Children private static string BuildROList(string[] args) { // when ro's in sql was added, an /sql parameter was introduced to allow the definition of the connection string. So @@ -317,6 +318,9 @@ namespace CmpRpt { SqlConnectionStr = parm2.Substring(5); } + // C2021-026 get the list of P/C Children if it was passed in + else if (parm2.ToUpper().StartsWith("/PC=")) + PCChildren = parm2.Substring(4).Split(','); //C2021-026 list of Parent/Child Children else roIdArg = parm2; } diff --git a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.cs b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.cs index 68cd7a17..f03ecda0 100644 --- a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.cs +++ b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021- Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: RODefFrm.cs $ $Revision: 18 $ @@ -105,6 +105,7 @@ using System.Text; using ROFields; using RODBInterface; using VlnStatus; +using System.Collections.Generic; namespace ROEditor @@ -125,6 +126,7 @@ namespace ROEditor private System.Windows.Forms.Label lblInUse; private System.Windows.Forms.Label lblAvail; private System.Windows.Forms.ListBox lboxInUse; + private System.Windows.Forms.CheckedListBox lboxInUseCB; // C2021-026 added a checked list box for Parent/Child capabilites private System.Windows.Forms.ListBox lboxAvail; private System.Windows.Forms.Button btnAdd; private System.Windows.Forms.Button btnEdit; @@ -139,15 +141,24 @@ namespace ROEditor private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnCancel; ArrayList InUseList; + ArrayList InUseApplcList; // C2021-026 hold the list of fields that have child values private VlnXmlElement elem; - private uint editlevel; // flag for group definition or ro definition + private uint editlevel; // flag for group definition or ro definition private string strFieldsInUse; private string origFieldsInUse; + private string origApplicFields; private string origRetVal; private string origMenuItem; - StringBuilder parseerror; + StringBuilder parseerror; private int hi, lo; + private Label lb_chkApplc; private int dbtype; + // C2021-026 returns true is Parent/Child info was passed into the RO Editor + public bool PCApplicabilityEnabled + { + get { return ROEditor.Form1.ApplicabilityEnabled(); } + } + // pass in Group Element public RODefFrm(VlnXmlElement pelem, RODB rodb, string fields, string grptxt, int idbtype) { @@ -164,7 +175,20 @@ namespace ROEditor // InitializeComponent(); - if(editlevel==(uint)RecordType.GroupSchema)this.Text = "Subgroup Definition"; + // C2021-024 toggle which check boxes are visable based on if Parent/Child is available + if (PCApplicabilityEnabled) + { + lboxInUseCB.Visible = true; + lboxInUse.Visible = false; + lb_chkApplc.Visible = true; + } + else + { + lboxInUseCB.Visible = false; + lboxInUse.Visible = true; + lb_chkApplc.Visible = false; + } + if (editlevel==(uint)RecordType.GroupSchema)this.Text = "Subgroup Definition"; FillInData(grptxt); } @@ -195,31 +219,62 @@ namespace ROEditor this.lboxAvail.Items.Add(rof.GetFieldname); } } + // C2021-024 see if the give RO field is checked to have child values + private bool ContainedInUseApplicList(ROField rof) + { + bool isInList = false; + foreach (ROField arof in InUseApplcList) + { + if (arof.GetRecID == rof.GetRecID) + { + isInList = true; + break; + } + } + return isInList; + } + private bool _initializing = false; - private void SetUpListBoxes() { + _initializing = true; ROField rof; // Get list of available fields (all fields in this type, i.e. rectype = 'Schema' // or 'GroupSchema') and get list of inuse from the schema definition. ArrayList tmp = myrodb.RODB_GetFields(elem, editlevel); // put the items in the AvailList box. if (AvailList == null) AvailList = new ArrayList(); - for (int i=0; i< tmp.Count; i++) AvailList.Add(tmp[i]); // don't modify the list returned from RODB_GetFields since it is part of dictionary - InUseList = myrodb.RODB_GetFieldsInUse(elem, AvailList, strFieldsInUse, ref origFieldsInUse, false); + for (int i = 0; i < tmp.Count; i++) AvailList.Add(tmp[i]); // don't modify the list returned from RODB_GetFields since it is part of dictionary + InUseList = myrodb.RODB_GetFieldsInUse(elem, AvailList, strFieldsInUse, ref origFieldsInUse, true); + // C2021-024 get the list of fields that are have P/C values turned on (fields that are checked) + InUseApplcList = myrodb.RODB_GetApplicabilityEnabledFields(elem, InUseList, ref origApplicFields, PCApplicabilityEnabled); FillInAvailable(); // set up the listbox for inuse items. - if (InUseList != null) + if (InUseList != null) { // add items to the InUseList box. - for (int i=0; i< InUseList.Count; i++) + for (int i = 0; i < InUseList.Count; i++) { - rof = (ROField) InUseList[i]; + rof = (ROField)InUseList[i]; if (rof.GetFieldname != null) //DO YET: why null? - this.lboxInUse.Items.Add(rof.GetFieldname); + { + // C2021-026 populate the relative In Use list base on if Parent/Child is enabled + if (PCApplicabilityEnabled) + { + this.lboxInUseCB.Items.Add(rof.GetFieldname); + if (rof.FieldTypeCanDoApplicability()) + { + if (ContainedInUseApplicList(rof)) + this.lboxInUseCB.SetItemCheckState(lboxInUseCB.Items.IndexOf(rof.GetFieldname), CheckState.Checked); + } + } + else + this.lboxInUse.Items.Add(rof.GetFieldname); + } } } + _initializing = false; } @@ -281,8 +336,12 @@ namespace ROEditor this.lblGroupText.Text = grptxt; DoValueTextBoxes(); SetUpListBoxes(); - - lboxInUse.GotFocus += new EventHandler(this.lboxInUse_GotFocus); + + if (PCApplicabilityEnabled) // C2021-026 Check Box list focus event + lboxInUseCB.GotFocus += new EventHandler(this.lboxInUseCB_GotFocus); + else + lboxInUse.GotFocus += new EventHandler(this.lboxInUse_GotFocus); + lboxAvail.GotFocus += new EventHandler(this.lboxAvail_GotFocus); // save copies of local data, so if there is a change, we know we must save them. @@ -309,9 +368,19 @@ namespace ROEditor this.btnAdd.Enabled = false; this.btnEdit.Enabled = true; } + protected void lboxInUseCB_GotFocus(object sender, EventArgs e) + { + lboxAvail.ClearSelected(); + this.btnRemove.Enabled = true; + this.btnAdd.Enabled = false; + this.btnEdit.Enabled = true; + } protected void lboxAvail_GotFocus (object sender, EventArgs e) { - lboxInUse.ClearSelected(); + if (PCApplicabilityEnabled) + lboxInUseCB.ClearSelected(); + else + lboxInUse.ClearSelected(); this.btnAdd.Enabled = true; this.btnRemove.Enabled = false; this.btnEdit.Enabled = true; @@ -320,48 +389,101 @@ namespace ROEditor { //get item in lboxInUse (in use list) and remove it from there // and add it to the lboxAvail list. - if (lboxInUse.SelectedIndex >=0 ) + if (PCApplicabilityEnabled) // C2021-026 use the Check Box list { - // get the selected item and its string. Remove it from the listbox, - // add it to the available array list & listbox & then remove it from - // the inuse array list. - int indx = lboxInUse.SelectedIndex; - lboxInUse.Items.RemoveAt(indx); + if (lboxInUseCB.SelectedIndex >= 0) + { + // get the selected item and its string. Remove it from the listbox, + // add it to the available array list & listbox & then remove it from + // the inuse array list. + int indx = lboxInUseCB.SelectedIndex; + lboxInUseCB.Items.RemoveAt(indx); - // copy if over to availlist - ROField rof = (ROField) InUseList[indx]; - ROField copyrof = new ROField(rof.GetFieldname,rof.GetRecID,rof.GetMasterRecID, rof.GetFieldType); - AvailList.Add(copyrof); + // copy if over to availlist + ROField rof = (ROField)InUseList[indx]; + ROField copyrof = new ROField(rof.GetFieldname, rof.GetRecID, rof.GetMasterRecID, rof.GetFieldType); + AvailList.Add(copyrof); - lboxAvail.Items.Add(copyrof.GetFieldname); - InUseList.RemoveAt(indx); - lboxAvail.Refresh(); - lboxInUse.Refresh(); + lboxAvail.Items.Add(copyrof.GetFieldname); + InUseList.RemoveAt(indx); + if (InUseApplcList.Contains(rof)) // C2021-026 remove from the field applicability list + InUseApplcList.Remove(rof); + lboxAvail.Refresh(); + lboxInUseCB.Refresh(); + } + } + else + { + if (lboxInUse.SelectedIndex >= 0) + { + // get the selected item and its string. Remove it from the listbox, + // add it to the available array list & listbox & then remove it from + // the inuse array list. + int indx = lboxInUse.SelectedIndex; + lboxInUse.Items.RemoveAt(indx); + + // copy if over to availlist + ROField rof = (ROField)InUseList[indx]; + ROField copyrof = new ROField(rof.GetFieldname, rof.GetRecID, rof.GetMasterRecID, rof.GetFieldType); + AvailList.Add(copyrof); + + lboxAvail.Items.Add(copyrof.GetFieldname); + InUseList.RemoveAt(indx); + if (InUseApplcList.Contains(rof)) // C2021-026 remove from the field applicability list + InUseApplcList.Remove(rof); + lboxAvail.Refresh(); + lboxInUse.Refresh(); + } } } private void btnAdd_Click(object sender, System.EventArgs e) { //get item in lboxInUse (in use list) and remove it from there // and add it to the lboxAvail list. - if (lboxAvail.SelectedIndex >=0 ) + if (PCApplicabilityEnabled) // C2021-026 using the Check Box List { - // get the selected item and its string. Remove it from the listbox, - // add it to the inuse array list & listbox & then remove it from - // the avail(able) array list. - int indx = lboxAvail.SelectedIndex; - lboxAvail.Items.RemoveAt(indx); - - // copy if over to availlist - ROField rof = (ROField) AvailList[indx]; - ROField copyrof = new ROField(rof.GetFieldname,rof.GetRecID,rof.GetMasterRecID,rof.GetFieldType); - InUseList.Add(copyrof); + if (lboxAvail.SelectedIndex >= 0) + { + // get the selected item and its string. Remove it from the listbox, + // add it to the inuse array list & listbox & then remove it from + // the avail(able) array list. + int indx = lboxAvail.SelectedIndex; + lboxAvail.Items.RemoveAt(indx); - lboxInUse.Items.Add(copyrof.GetFieldname); - AvailList.RemoveAt(indx); - lboxAvail.Refresh(); - lboxInUse.Refresh(); - btnOK.Enabled=true; + // copy if over to availlist + ROField rof = (ROField)AvailList[indx]; + ROField copyrof = new ROField(rof.GetFieldname, rof.GetRecID, rof.GetMasterRecID, rof.GetFieldType); + InUseList.Add(copyrof); + lboxInUseCB.Items.Add(copyrof.GetFieldname); + AvailList.RemoveAt(indx); + lboxAvail.Refresh(); + lboxInUseCB.Refresh(); + btnOK.Enabled = true; + } + } + else + { + if (lboxAvail.SelectedIndex >= 0) + { + // get the selected item and its string. Remove it from the listbox, + // add it to the inuse array list & listbox & then remove it from + // the avail(able) array list. + int indx = lboxAvail.SelectedIndex; + lboxAvail.Items.RemoveAt(indx); + + // copy if over to availlist + ROField rof = (ROField)AvailList[indx]; + ROField copyrof = new ROField(rof.GetFieldname, rof.GetRecID, rof.GetMasterRecID, rof.GetFieldType); + InUseList.Add(copyrof); + + lboxInUse.Items.Add(copyrof.GetFieldname); + AvailList.RemoveAt(indx); + lboxAvail.Refresh(); + lboxInUse.Refresh(); + btnOK.Enabled = true; + + } } } @@ -849,6 +971,17 @@ namespace ROEditor if (i+1 < InUseList.Count) inuserecs = inuserecs + " "; } } + // C2021-026 save the fields with applicability set + string applicfieldrecs = null; + for (int i = 0; i < InUseApplcList.Count; i++) + { + rof = (ROField)InUseApplcList[i]; + if (rof.GetFieldname != null) + { + applicfieldrecs = applicfieldrecs + rof.GetRecID; + if (i + 1 < InUseApplcList.Count) applicfieldrecs = applicfieldrecs + " "; + } + } // save the database record, saving modified data as appropriate -- if a mod // occurred at this level, add it to the attribute list too. @@ -877,6 +1010,12 @@ namespace ROEditor elem.SetAttribute("FieldsInUse", inuserecs); mod = true; } + //C2021-026 save the list of field recids that use applicability + if (applicfieldrecs != origApplicFields) + { + elem.SetAttribute("ApplicabilityEnabled", applicfieldrecs); + mod = true; + } } if (editlevel == (uint) RecordType.GroupSchema) @@ -941,7 +1080,8 @@ namespace ROEditor // Get the field which is active & it's type. Pass the field through to the field // editor. int indx; - indx = lboxInUse.SelectedIndex; + // C2021-026 get the selected index base on wich InUse list is being used + indx = (PCApplicabilityEnabled)? lboxInUseCB.SelectedIndex : lboxInUse.SelectedIndex; if (indx >= 0) rof = (ROField) InUseList[indx]; else @@ -975,13 +1115,29 @@ namespace ROEditor // Update Lists & Text boxes to represent any modified text. if (isInSelList) { - lboxInUse.Items.Clear(); + if (PCApplicabilityEnabled) + lboxInUseCB.Items.Clear(); + else + lboxInUse.Items.Clear(); // add items to the InUseList box. for (int i=0; i< InUseList.Count; i++) { rof = (ROField) InUseList[i]; if (rof.GetFieldname != null) - this.lboxInUse.Items.Add(rof.GetFieldname); + { + // C2021-026 if doing Parent/Child enabled RO Editor, put the In Use fields in the Check Box List instead of the normal list + if (PCApplicabilityEnabled) + { + this.lboxInUseCB.Items.Add(rof.GetFieldname); + if (rof.FieldTypeCanDoApplicability()) + { + if (ContainedInUseApplicList(rof)) + this.lboxInUseCB.SetItemCheckState(lboxInUseCB.Items.IndexOf(rof.GetFieldname), CheckState.Checked); + } + } + else + this.lboxInUse.Items.Add(rof.GetFieldname); + } } } else @@ -1009,6 +1165,32 @@ namespace ROEditor lboxAvail.Items.Add(rof.GetFieldname); } } + // C2021-026 Check/un-check field for Parent/Child values + private void lboxInUseCB_ItemCheck(object sender, ItemCheckEventArgs e) + { + if (_initializing) return; + ROField rof = (ROField)InUseList[e.Index]; + bool isInAplicList = ContainedInUseApplicList(rof); + if (!rof.FieldTypeCanDoApplicability()) + { + MessageBox.Show("Cannot Enable Applicability on this RO Field type.", "Enable Applicabilty", MessageBoxButtons.OK, MessageBoxIcon.Information); + e.NewValue = CheckState.Unchecked; + } + else if (e.NewValue == CheckState.Checked) //we are going to check it - add tothe applic list + { + if (!isInAplicList) // make sure it's not already in the list (this should never happen) + InUseApplcList.Add(rof); + } + else if (isInAplicList) // we are un-checking it. Remove it from the applic list + { + for (int i = 0; i < InUseApplcList.Count; i++) + if ((InUseApplcList[i] as ROField).GetRecID == rof.GetRecID) + { + InUseApplcList.RemoveAt(i); + break; + } + } + } #region Windows Form Designer generated code /// @@ -1024,12 +1206,14 @@ namespace ROEditor this.tbMenuVal = new System.Windows.Forms.TextBox(); this.lblGroupText = new System.Windows.Forms.Label(); this.gbFields = new System.Windows.Forms.GroupBox(); + this.lb_chkApplc = new System.Windows.Forms.Label(); this.btnNew = new System.Windows.Forms.Button(); this.btnRemove = new System.Windows.Forms.Button(); this.btnEdit = new System.Windows.Forms.Button(); this.btnAdd = new System.Windows.Forms.Button(); this.lboxAvail = new System.Windows.Forms.ListBox(); this.lboxInUse = new System.Windows.Forms.ListBox(); + this.lboxInUseCB = new System.Windows.Forms.CheckedListBox(); // C2021-026 list with check boxes to enable P/C on field this.lblAvail = new System.Windows.Forms.Label(); this.lblInUse = new System.Windows.Forms.Label(); this.btnOK = new System.Windows.Forms.Button(); @@ -1090,22 +1274,32 @@ namespace ROEditor // // gbFields // - this.gbFields.Controls.AddRange(new System.Windows.Forms.Control[] { - this.btnNew, - this.btnRemove, - this.btnEdit, - this.btnAdd, - this.lboxAvail, - this.lboxInUse, - this.lblAvail, - this.lblInUse}); + this.gbFields.Controls.Add(this.lb_chkApplc); + this.gbFields.Controls.Add(this.btnNew); + this.gbFields.Controls.Add(this.btnRemove); + this.gbFields.Controls.Add(this.btnEdit); + this.gbFields.Controls.Add(this.btnAdd); + this.gbFields.Controls.Add(this.lboxAvail); + this.gbFields.Controls.Add(this.lboxInUse); + this.gbFields.Controls.Add(this.lboxInUseCB); + this.gbFields.Controls.Add(this.lblAvail); + this.gbFields.Controls.Add(this.lblInUse); this.gbFields.Location = new System.Drawing.Point(8, 112); this.gbFields.Name = "gbFields"; - this.gbFields.Size = new System.Drawing.Size(704, 224); + this.gbFields.Size = new System.Drawing.Size(704, 247); this.gbFields.TabIndex = 8; this.gbFields.TabStop = false; this.gbFields.Text = "Fields"; // + // lb_chkApplc + // + this.lb_chkApplc.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lb_chkApplc.Location = new System.Drawing.Point(69, 24); + this.lb_chkApplc.Name = "lb_chkApplc"; + this.lb_chkApplc.Size = new System.Drawing.Size(227, 16); + this.lb_chkApplc.TabIndex = 8; + this.lb_chkApplc.Text = "(Check Parent/Child Applicability Fields)"; + // // btnNew // this.btnNew.Location = new System.Drawing.Point(608, 48); @@ -1150,17 +1344,25 @@ namespace ROEditor this.lboxAvail.ItemHeight = 14; this.lboxAvail.Location = new System.Drawing.Point(376, 48); this.lboxAvail.Name = "lboxAvail"; - this.lboxAvail.Size = new System.Drawing.Size(216, 144); + this.lboxAvail.Size = new System.Drawing.Size(216, 172); this.lboxAvail.TabIndex = 3; // // lboxInUse // this.lboxInUse.ItemHeight = 14; - this.lboxInUse.Location = new System.Drawing.Point(24, 48); + this.lboxInUse.Location = new System.Drawing.Point(27, 48); this.lboxInUse.Name = "lboxInUse"; - this.lboxInUse.Size = new System.Drawing.Size(216, 144); + this.lboxInUse.Size = new System.Drawing.Size(216, 172); this.lboxInUse.TabIndex = 2; // + // lboxInUseCB + // + this.lboxInUseCB.Location = new System.Drawing.Point(27, 48); + this.lboxInUseCB.Name = "lboxInUseCB"; + this.lboxInUseCB.Size = new System.Drawing.Size(216, 174); + this.lboxInUseCB.TabIndex = 2; + this.lboxInUseCB.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.lboxInUseCB_ItemCheck); + // // lblAvail // this.lblAvail.Location = new System.Drawing.Point(384, 24); @@ -1200,21 +1402,21 @@ namespace ROEditor // this.AutoScaleBaseSize = new System.Drawing.Size(6, 15); this.ClientSize = new System.Drawing.Size(792, 437); - this.Controls.AddRange(new System.Windows.Forms.Control[] { - this.btnCancel, - this.btnOK, - this.gbFields, - this.lblGroupText, - this.tbMenuVal, - this.tbRetVal, - this.lblMenuVal, - this.lblRetVal, - this.lblGroup}); - this.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.gbFields); + this.Controls.Add(this.lblGroupText); + this.Controls.Add(this.tbMenuVal); + this.Controls.Add(this.tbRetVal); + this.Controls.Add(this.lblMenuVal); + this.Controls.Add(this.lblRetVal); + this.Controls.Add(this.lblGroup); + this.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Name = "RODefFrm"; this.Text = "Referenced Object Definition"; this.gbFields.ResumeLayout(false); this.ResumeLayout(false); + this.PerformLayout(); } #endregion diff --git a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.resx b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.resx index c87ed6c9..d58980a3 100644 --- a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.resx +++ b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RODefFrm.resx @@ -1,75 +1,96 @@ + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + + + + + + + + + + + + + + + + + + - + + @@ -88,15 +109,12 @@ text/microsoft-resx - 1.3 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - RODefFrm - \ No newline at end of file diff --git a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.cs b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.cs index 6f2d916f..6498ee9a 100644 --- a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.cs +++ b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: ROEditor.cs $ $Revision: 54 $ @@ -350,6 +350,7 @@ namespace ROEditor private System.Windows.Forms.MenuItem menuEditSelAll; private TreeNode LastSelectedNode; private TextBox _CurrentTextBox; // currently selected TextBox field + public static string[] PCChildren; //C2021-026 list of Parent/Child Children public TextBox CurrentTextBox { @@ -887,9 +888,9 @@ namespace ROEditor } } - private void CreateCtlXmlEdit2(VlnXmlElement curelem, XmlSchema myschema, ArrayList reqfields) + private void CreateCtlXmlEdit2(VlnXmlElement curelem, XmlSchema myschema, ArrayList reqfields, ArrayList fieldsWithApplic) { - ctlXMLEdit2 = new ctlXMLEditLib.ctlXMLEdit(curelem,myschema,reqfields); + ctlXMLEdit2 = new ctlXMLEditLib.ctlXMLEdit(curelem,myschema,reqfields,fieldsWithApplic,PCChildren); // C2021-026 pass in P/C enabled information ctlXMLEdit2.AutoScroll = true; ctlXMLEdit2.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); ctlXMLEdit2.Name = "ctlXMLEdit2"; @@ -927,9 +928,29 @@ namespace ROEditor this.panel2.Controls.Add(ctlXMLEdit2); tbtnCancel.Enabled = true; } - + // C2021-026 Get a list of fields that are P/C enabled + private ArrayList GetApplcFieldListForElement(VlnXmlElement elem) + { + ArrayList rtnval = null; + ArrayList InUseApplcList = null; + ArrayList AvailList = null; + ArrayList InUseList = null; + string origFieldsInUse = ""; + string origApplicFields = ""; + ArrayList tmp = myrodb.RODB_GetFields((VlnXmlElement)elem.ParentNode, (uint)RecordType.Schema); + // put the items in the AvailList box. + if (AvailList == null) AvailList = new ArrayList(); + for (int i = 0; i < tmp.Count; i++) AvailList.Add(tmp[i]); // don't modify the list returned from RODB_GetFields since it is part of dictionary + InUseList = myrodb.RODB_GetFieldsInUse((VlnXmlElement)elem.ParentNode, AvailList, "FieldsInUse", ref origFieldsInUse, false); + InUseApplcList = myrodb.RODB_GetApplicabilityEnabledFields((VlnXmlElement)elem.ParentNode, InUseList, ref origApplicFields, ApplicabilityEnabled()); + rtnval = new ArrayList(); + foreach (ROField rof in InUseApplcList) + rtnval.Add(rof.GetFieldname); + return rtnval; + } private void EditRO(VlnXmlElement curelem) { + ArrayList fieldsWithApplic = null; newone=null; // can't edit fields for top or top group nodes (top node not editable, // and top group node data change at properties level). @@ -944,6 +965,10 @@ namespace ROEditor // a message. (B2004-017) if (curelem.Name != "vlnGroup") { + // C2021-026 Get the list of fields with P/C enabled + // use the curelm.parent and calls similar to what is in RODefFrm.cs + fieldsWithApplic = GetApplcFieldListForElement(curelem); + myschema = myrodb.RODB_GetSchema(curelem); if (myschema==null) { @@ -965,7 +990,7 @@ namespace ROEditor } ArrayList reqfields = curelem.GetRequiredFields(); - CreateCtlXmlEdit2(curelem,myschema,reqfields); + CreateCtlXmlEdit2(curelem,myschema, reqfields, fieldsWithApplic); // C2021-026 pass in P/C enabled fields this.panel2.Controls.Add(ctlXMLEdit2); tbtnSave.Enabled=false; // set initial states of buttons on edit tbtnRestore.Enabled=false; @@ -1406,7 +1431,7 @@ namespace ROEditor this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Location = new System.Drawing.Point(228, 28); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(588, 591); + this.panel1.Size = new System.Drawing.Size(710, 591); this.panel1.TabIndex = 5; // // panel2 @@ -1447,7 +1472,7 @@ namespace ROEditor this.tbar.Location = new System.Drawing.Point(0, 0); this.tbar.Name = "tbar"; this.tbar.ShowToolTips = true; - this.tbar.Size = new System.Drawing.Size(816, 28); + this.tbar.Size = new System.Drawing.Size(938, 28); this.tbar.TabIndex = 0; this.tbar.TextAlign = System.Windows.Forms.ToolBarTextAlign.Right; this.tbar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.tbar_OnClick); @@ -1519,7 +1544,7 @@ namespace ROEditor // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); - this.ClientSize = new System.Drawing.Size(816, 619); + this.ClientSize = new System.Drawing.Size(980, 619); this.Controls.Add(this.lblDuplicateRO); this.Controls.Add(this.panel1); this.Controls.Add(this.splitter1); @@ -1574,24 +1599,37 @@ namespace ROEditor // the the Access database. if (args.Length > 0) { - ConnectionPath = args[0]; + if (args[0].ToUpper().StartsWith("PC=")) + PCChildren = args[0].Substring(3).Split(','); //C2021-026 list of Parent/Child Children + else + ConnectionPath = args[0]; // Directory.SetCurrentDirectory(ConnectionPath); } - else // find ROPATH + if (ConnectionPath == null) // RO Path was not passed in, find ROPATH { ConnectionPath = FindTheRODirectory(); } if (args.Length > 1) { - if (args[1].ToUpper().Contains("DATA SOURCE")) SqlConnectionStr = args[1]; + if (args[1].ToUpper().StartsWith("PC=")) + PCChildren = args[1].Substring(3).Split(','); //C2021-026 list of Parent/Child Children + else if (args[1].ToUpper().Contains("DATA SOURCE")) SqlConnectionStr = args[1]; else specificro = args[1]; } if (args.Length > 2) { - if (args[2].ToUpper().Contains("DATA SOURCE")) SqlConnectionStr = args[2]; + if (args[2].ToUpper().StartsWith("PC=")) + PCChildren = args[2].Substring(3).Split(','); //C2021-026 list of Parent/Child Children + else if (args[2].ToUpper().Contains("DATA SOURCE")) SqlConnectionStr = args[2]; else specificro = args[2]; } - try + if (args.Length > 3) + if (args[3].ToUpper().StartsWith("PC=")) + PCChildren = args[3].Substring(3).Split(','); //C2021-026 list of Parent/Child Children + else if (args[3].ToUpper().Contains("DATA SOURCE")) SqlConnectionStr = args[3]; + else specificro = args[3]; + RODB.PCChildList = PCChildren; //C2021-026 pass the Parent/Child info to the RODB class + try { // Convert the RO data if needed if (!CheckForDataConversion(ConnectionPath)) @@ -1726,6 +1764,12 @@ namespace ROEditor } } + // C2021-026 was Parent/Child information passed into the RO Editor? + public static bool ApplicabilityEnabled() + { + return (PCChildren != null && PCChildren.Length > 0); + } + /* * Look for the RO directory via PROC.INI and by * looking for a \RO directory in the current VEplant @@ -2011,7 +2055,7 @@ namespace ROEditor int retval = roTreeView_ClearEditDisplay(false); if (retval == -1) return; roListView_ClearListDisplay(); - CreateCtlXmlEdit2(nelem,myschema,reqfields); + CreateCtlXmlEdit2(nelem,myschema,reqfields, null); tbtnSave.Enabled=false; // initial disable the save button ctlXMLEdit2.Focus(); tbtnZoom.Enabled = false; @@ -2024,6 +2068,7 @@ namespace ROEditor private void menuNewRefObj_Click(object sender, System.EventArgs e) { int retval = roTreeView_ClearEditDisplay(false); + ArrayList InUseApplcList=null; if (retval == -1) return; roListView_ClearListDisplay(); VlnXmlElement curelem = (VlnXmlElement) roTreeView.SelectedNode.Tag; @@ -2051,6 +2096,7 @@ namespace ROEditor { curelem.ParentNode.AppendChild((XmlNode) nelem); TreeNewparent = roTreeView.SelectedNode.Parent; + InUseApplcList = GetApplcFieldListForElement(curelem); //C2021-026 get list of fields with P/C enabled } else { @@ -2060,7 +2106,7 @@ namespace ROEditor newone = nelem; ArrayList reqfields = nelem.GetRequiredFields(); - CreateCtlXmlEdit2(nelem,myschema,reqfields); + CreateCtlXmlEdit2(nelem,myschema,reqfields, InUseApplcList); tbtnSave.Enabled=false; // initial disable the save button ctlXMLEdit2.Focus(); tbtnZoom.Enabled = false; @@ -2555,7 +2601,8 @@ namespace ROEditor if (rof.GetFieldname != null) { uint ftype = rof.GetFieldType; - if (ftype == 1 || ftype == 2 || ftype==4 || ftype==128) + if (ftype == (uint)ROFields.FieldTypes.SingleTxt || ftype == (uint)ROFields.FieldTypes.VariableTxt || + ftype == (uint)ROFields.FieldTypes.FrmtSingleTxt || ftype == (uint)ROFields.FieldTypes.Combination) roListView.Columns.Add(rof.GetFieldname, 100,HorizontalAlignment.Left); } } @@ -2594,7 +2641,8 @@ namespace ROEditor if (rof.GetFieldname != null) { uint ftype = rof.GetFieldType; - if (ftype == 1 || ftype == 2 || ftype == 4 || ftype == 128) + if (ftype == (uint)ROFields.FieldTypes.SingleTxt || ftype == (uint)ROFields.FieldTypes.VariableTxt || + ftype == (uint)ROFields.FieldTypes.FrmtSingleTxt || ftype == (uint)ROFields.FieldTypes.Combination) { string nm0 = rof.GetFieldname; nm = rof.MakeFieldName(nm0); @@ -2711,9 +2759,9 @@ namespace ROEditor byte xbyte, ybyte; xlen = xbuff.Length; ylen = ybuff.Length; - if (xbuff[0] == '<') + if (xbuff.Length > 0 && xbuff[0] == '<') rtnval = 0; - if (ybuff[0] == '<') + if (ybuff.Length > 0 && ybuff[0] == '<') rtnval = 0; while ((rtnval==0) && ((xcnt < xlen) || (ycnt < ylen))) { diff --git a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.resx b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.resx index 99e10a40..bb1d7760 100644 --- a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.resx +++ b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/ROEditor.resx @@ -112,20 +112,20 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + 124, 17 - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACE - CAAAAk1TRnQBSQFMAgEBAgEAARQBAAEUAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CAAAAk1TRnQBSQFMAgEBAgEAARwBAAEcAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -164,18 +164,18 @@ AYAPAAEBBwABAwYAAYABBwYAAcYBHwQACw== - + 17, 17 - + 256, 17 - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAe - CwAAAk1TRnQBSQFMAgEBBgEAARQBAAEUAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CwAAAk1TRnQBSQFMAgEBBgEAARwBAAEcAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -225,10 +225,10 @@ ASgDAAFAAwABIAMAAQEBAAEBBgABARYAA///AAIACw== - + 36 - + AAABAAEAICAQAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAAAIAAAAAAAAAAAAAEAAAABAA diff --git a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RO_FST.cs b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RO_FST.cs index b652b0f6..2a263265 100644 --- a/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RO_FST.cs +++ b/PROMS/ReferencedObjects/Exe/RefObj/ROEditor/RO_FST.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: RO_FST.cs $ $Revision: 15 $ @@ -823,7 +823,7 @@ namespace ROEditor // i =0; // } string cvttmp= CvtFldToUserFld(RtnValTmplate); - string RORtnVal = elem.GetReturnValue(ROdatabase,tablename,cvttmp,InUseList,ref RtnVal); + string RORtnVal = elem.GetReturnValue(ROdatabase,tablename,cvttmp,InUseList,ref RtnVal,ROEditor.Form1.PCChildren); // C2021-026 pass in P/C Children // Write the field type to the FST fhFST.Write(RtnVal); diff --git a/PROMS/ReferencedObjects/LibSource/RODBInterface/RODBInterface.cs b/PROMS/ReferencedObjects/LibSource/RODBInterface/RODBInterface.cs index 8165eaba..b5f85ad4 100644 --- a/PROMS/ReferencedObjects/LibSource/RODBInterface/RODBInterface.cs +++ b/PROMS/ReferencedObjects/LibSource/RODBInterface/RODBInterface.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: RODBInterface.cs $ $Revision: 48 $ @@ -264,6 +264,7 @@ using Org.Mentalis.Files; using System.Data.SqlClient; using System.Collections.Generic; + namespace RODBInterface { /// @@ -273,7 +274,6 @@ namespace RODBInterface { Master = 0, SubDatabase = 1, Schema = 2, Group = 3, GroupSchema = 4, RRO = 5, SchemaStart = 6, SchemaEnd = 7, ConvertedToSql = 8 } - /// /// The following class handles generation of sql strings to get/put requested parts of /// XML RO Tree. And performs the database access using the VLN_DB class. @@ -314,6 +314,13 @@ namespace RODBInterface get { return _OnlyConnectOnce; } set { _OnlyConnectOnce = value; } } + // C2021-026 used to access in the list of P/C Children + private static string[] _PCChildList = null; + public static string[] PCChildList + { + get { return _PCChildList; } + set { _PCChildList = value; } + } #endregion #region abstracts // need these for each method that must be defined for each database type public abstract string RODB_GetNextGroupTable(); @@ -354,7 +361,6 @@ namespace RODBInterface } #region GeneralDB - public void GetDbServerInfo(string ROdir) { @@ -504,6 +510,84 @@ namespace RODBInterface } return inuse; } + + //C2021-026 adding ability to have field values based on Parent/Child applicability + // This reads the database and returns a list of the field where applicability was enabled + public ArrayList RODB_GetApplicabilityEnabledFields(VlnXmlElement elem, ArrayList fieldsInUse, ref string origApplcFields, bool pcApplicabilityEnabled) + { + ArrayList newApplicList = new ArrayList(); + if (!pcApplicabilityEnabled) + { + origApplcFields = null; + return newApplicList; + } + VlnXmlElement startelem = elem; + string atribApplicFields = "ApplicabilityEnabled"; //xml attribute containing list of field recids + // if this element doesn't have any fields in use, walk up the tree until + // we find them. + string applicFields = ""; + if (startelem.HasAttribute(atribApplicFields) == false) + { + VlnXmlElement parent; + parent = (VlnXmlElement)startelem.ParentNode; + while (parent != null && applicFields == "") + { + applicFields = parent.GetAttribute(atribApplicFields); + if (parent.Name != "RO_Root") + parent = (VlnXmlElement)parent.ParentNode; + else + parent = null; + } + } + else + applicFields = startelem.GetAttribute(atribApplicFields); + + origApplcFields = applicFields; // make a copy to compare to later. + + // if there are no fields with applicability (may be inserting a top group) + // return an empty list. + if (applicFields == "") return newApplicList; + // Go through the FieldsInUse list and copy elements to newApplicList + int strpos = 0; + string recid; + recid = applicFields.Substring(strpos, 8); + MyRecID = recid; + while (recid != null) + { + // find it in avail list and add to newApplicList + for (int i = 0; i < fieldsInUse.Count; i++) + { + ROField rof = (ROField)fieldsInUse[i]; + string lrecid = rof.GetRecID; + if (lrecid == recid) + { + // add to newApplilcList if it is not already there list + ROField inuserof = new ROField(rof.GetFieldname, rof.GetRecID, rof.GetMasterRecID, rof.GetFieldType); + bool addit = true; + foreach (ROField arof in newApplicList) + { + if (arof.GetRecID == inuserof.GetRecID) + { + addit = false; //this field is already in the list + break; + } + } + if (addit) + newApplicList.Add((object)inuserof); + break; + } + } + strpos = strpos + 9; + if (strpos > applicFields.Length) + recid = null; + else + { + recid = applicFields.Substring(strpos, 8); + } + } + return newApplicList; + } + public string CvtUserFldToFld(string fldname) { if (fldname.Length < 2) @@ -649,6 +733,12 @@ namespace RODBInterface xmlTextWriter.WriteString(enode.GetAttribute("FieldsInUse")); xmlTextWriter.WriteEndAttribute(); } + if (enode.HasAttribute("ApplicabilityEnabled")) //C2021-026 save field applicability + { + xmlTextWriter.WriteStartAttribute("ApplicabilityEnabled", null); + xmlTextWriter.WriteString(enode.GetAttribute("ApplicabilityEnabled")); + xmlTextWriter.WriteEndAttribute(); + } if (enode.HasAttribute("GroupMenuItem")) { xmlTextWriter.WriteStartAttribute("GroupMenuItem", null); @@ -755,12 +845,31 @@ namespace RODBInterface success = RODB_NewSchemaPiece(lrecid, parent.GetAttribute("RecID"), myelem.GetAttribute("Table"), strbld.ToString(), editlevel); return success; } + // C2021-026 rename any P/C Child fields + public string DoReplaceParentChildField(string infstr, string oldName, string newName) + { + string rtnInfoStr = infstr; + if (PCChildList == null) return rtnInfoStr; + int pcChildIdx = 0; // children indexing starts at one so initialize with zero + foreach (string chld in PCChildList) + { + pcChildIdx++; + string csufx = string.Format("_PCCHILD{0}", pcChildIdx); // Create child field name + string oldFldNameChild = oldName.Insert(oldName.Length - 1, CvtUserFldToFld(csufx)); + string newFldNameChild = newName.Insert(newName.Length - 1, CvtUserFldToFld(csufx)); + rtnInfoStr = rtnInfoStr.Replace(oldFldNameChild, newFldNameChild); + } + return rtnInfoStr; + } + public string DoCmbFieldReplace(string repstring, string oname, string nname, string letter) { string cmboname, cmbnname; cmboname = oname.Insert(oname.Length - 1, letter); cmbnname = nname.Insert(nname.Length - 1, letter); - return (repstring.Replace(cmboname, cmbnname)); + string rtnstr = repstring.Replace(cmboname, cmbnname); + rtnstr = DoReplaceParentChildField(rtnstr, cmboname, cmbnname); // C2021-026 create child fields in combo group + return rtnstr; } // RODB_UpdateNamesInROs: goes through subtree (top node is 'fld') and if this @@ -2333,11 +2442,9 @@ namespace RODBInterface DBE.CommandDispose(); return success; } - public override bool RODB_ProcessRROFieldChange(VlnXmlElement child, string oldname, string newname, uint editlevel, VlnStatusMessage StatMsgWindow, bool combofield) { - bool success; string str; string info; @@ -2464,7 +2571,9 @@ namespace RODBInterface if (combofield == false) { tinfo1 = info.Replace(onameOpen, nnameOpen); + tinfo1 = DoReplaceParentChildField(tinfo1, onameOpen, nnameOpen); //C2021-0226 also update Parent/Child fields tinfo2 = tinfo1.Replace(onameClose, nnameClose); + tinfo2 = DoReplaceParentChildField(tinfo2, onameClose, nnameClose); //C2021-0226 also update Parent/Child fields XmlNodeList nodeList; nodeList = echild.SelectNodes(oldname); foreach (XmlNode nod in nodeList) @@ -2499,7 +2608,6 @@ namespace RODBInterface } } } - StatMsgWindow.StatusMessage = echild.GetAttribute("MenuTitle"); str = "UPDATE " + echild.GetAttribute("Table") + " SET Info = '" + tinfo2 + "'"; str = str + ", ModDateTime = '" + dt + "' WHERE RecID = '" + echild.GetAttribute("RecID") + "';"; diff --git a/PROMS/ReferencedObjects/LibSource/RODBInterface/SqlRODB.cs b/PROMS/ReferencedObjects/LibSource/RODBInterface/SqlRODB.cs index 0808bfe3..c7794a61 100644 --- a/PROMS/ReferencedObjects/LibSource/RODBInterface/SqlRODB.cs +++ b/PROMS/ReferencedObjects/LibSource/RODBInterface/SqlRODB.cs @@ -2133,7 +2133,9 @@ namespace RODBInterface if (combofield == false) { tinfo1 = info.Replace(onameOpen, nnameOpen); + tinfo1 = DoReplaceParentChildField(tinfo1, onameOpen, nnameOpen); //C2021-0226 also update Parent/Child fields tinfo2 = tinfo1.Replace(onameClose, nnameClose); + tinfo2 = DoReplaceParentChildField(tinfo2, onameClose, nnameClose); //C2021-0226 also update Parent/Child fields XmlNodeList nodeList; nodeList = echild.SelectNodes(oldname); foreach (XmlNode nod in nodeList) @@ -2565,6 +2567,7 @@ namespace RODBInterface return null; } } + // C2021-026 read in schema for the "ApplicabilityEnabled" attribute entireschema = schemastart + entireschema + schemaend; } XmlTextReader schemareader = new XmlTextReader(entireschema, XmlNodeType.Element, null); diff --git a/PROMS/ReferencedObjects/LibSource/RODBInterface/VlnXml.cs b/PROMS/ReferencedObjects/LibSource/RODBInterface/VlnXml.cs index be553d39..307b59b3 100644 --- a/PROMS/ReferencedObjects/LibSource/RODBInterface/VlnXml.cs +++ b/PROMS/ReferencedObjects/LibSource/RODBInterface/VlnXml.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: VlnXml.cs $ $Revision: 23 $ @@ -689,13 +689,78 @@ namespace RODBInterface return rtnval; } + private ArrayList GetApplcFieldListForElement(RODB roDatabase, VlnXmlElement elem, bool pcApplicability) + { + ArrayList rtnval = null; + ArrayList InUseApplcList = null; + ArrayList AvailList = null; + ArrayList InUseList = null; + string origFieldsInUse = ""; + string origApplicFields = ""; + ArrayList tmp = roDatabase.RODB_GetFields((VlnXmlElement)elem.ParentNode, (uint)RecordType.Schema); + // put the items in the AvailList box. + if (AvailList == null) AvailList = new ArrayList(); + for (int i = 0; i < tmp.Count; i++) AvailList.Add(tmp[i]); // don't modify the list returned from RODB_GetFields since it is part of dictionary + InUseList = roDatabase.RODB_GetFieldsInUse((VlnXmlElement)elem.ParentNode, AvailList, "FieldsInUse", ref origFieldsInUse, false); + InUseApplcList = roDatabase.RODB_GetApplicabilityEnabledFields((VlnXmlElement)elem.ParentNode, InUseList, ref origApplicFields, pcApplicability); + rtnval = new ArrayList(); + foreach (ROField rof in InUseApplcList) + rtnval.Add(rof.GetFieldname); + return rtnval; + } + private string GetPCReturnValues(RODB theDb, string[] pcChildern, VlnXmlElement elm, bool PCApplicability, string inusename, string defValue) + { + string applicValues = defValue; + ArrayList FieldsWithApplic = GetApplcFieldListForElement(theDb, elm, PCApplicability); + if (FieldsWithApplic.Contains(CvtFldToUserFld(inusename))) // C2021-026 returns True if field should show Parent/Child Applicability fields + { + XmlNode elmnode = (XmlNode)elm; + XmlNode nd = elmnode.SelectSingleNode(inusename); + string parentName = inusename; + string parentValue = ""; - public string GetReturnValue(RODB theDb, string TableName,string RtnValTemplate, ArrayList InUseList, ref ushort ValueType) + if (nd == null) + { + XmlNode radNode = elmnode.FirstChild; + string radNodeName = radNode.Name; + while (radNode != null && !radNodeName.StartsWith(inusename)) + { + radNode = radNode.NextSibling; + radNodeName = radNode.Name; + } + parentValue = radNode.InnerText; + parentName = radNodeName; + } + else + parentValue = nd.InnerText; + + //applicValues = ""; + applicValues = string.Format(" 0); + // Parse the template for the fields and generate a return string int left = RtnValTemplate.IndexOf("<"); // look for begining of field int right = -1; @@ -762,6 +827,8 @@ namespace RODBInterface } ValueType |= FldType; + if (PCApplicability) + text = GetPCReturnValues(theDb, pcChildern, elm, PCApplicability, inusename, text); // C2021-026 Get P/C Children return values strbld.Append(text); } else @@ -789,6 +856,7 @@ namespace RODBInterface return RtnValStr; } + public string GetComboFieldValueAndType(XmlNode CurNode, string Fld, ref ushort FldTyp, bool ForMenu) { string RtnVal = ""; @@ -929,52 +997,52 @@ namespace RODBInterface /// // ShowGroupDetail sends to print.tmp the data for a Group level. - private bool ShowGroupDetail(RODB myrodb) - { - ROField rof; - XmlNode nd; - VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument; - string nm; + //private bool ShowGroupDetail(RODB myrodb) + //{ + // ROField rof; + // XmlNode nd; + // VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument; + // string nm; - // First get the fields used for this Group. - string tmp=null; // needed for inuse call - ArrayList AvailList = myrodb.RODB_GetFields(this, 0); - ArrayList InUseList = myrodb.RODB_GetFieldsInUse(this, AvailList, "GroupFieldsInUse", ref tmp, false); + // // First get the fields used for this Group. + // string tmp=null; // needed for inuse call + // ArrayList AvailList = myrodb.RODB_GetFields(this, 0); + // ArrayList InUseList = myrodb.RODB_GetFieldsInUse(this, AvailList, "GroupFieldsInUse", ref tmp, false); - // For each field, print the header (field name) & then print data if it exists. - if (InUseList != null) - { - xmldoc.writeRROBegin(); - xmldoc.writeInt(7); - xmldoc.writeText(" "); + // // For each field, print the header (field name) & then print data if it exists. + // if (InUseList != null) + // { + // xmldoc.writeRROBegin(); + // xmldoc.writeInt(7); + // xmldoc.writeText(" "); - for (int i=0; i< InUseList.Count; i++) - { - rof = (ROField) InUseList[i]; - if (rof.GetFieldname != null) - { - string nm0 = rof.GetFieldname; - nm = rof.MakeFieldName(nm0); - xmldoc.pushHeader(nm0); - // see if it has data in the ro. - nd = this.SelectSingleNode(nm); - // if not found with just the string, search the tree. - if (nd==null)nd = this.SelectSingleNode("*/"+nm); - if (nd == null) // not found, write out a '0'. - xmldoc.writeInt(0); - else - { - VlnXmlElement end; - end = (VlnXmlElement) nd; - xmldoc.writeTextValue(end.InnerText); - } - xmldoc.popHeader(); - } - } - xmldoc.writeRROEnd(); - } - return true; - } + // for (int i=0; i< InUseList.Count; i++) + // { + // rof = (ROField) InUseList[i]; + // if (rof.GetFieldname != null) + // { + // string nm0 = rof.GetFieldname; + // nm = rof.MakeFieldName(nm0); + // xmldoc.pushHeader(nm0); + // // see if it has data in the ro. + // nd = this.SelectSingleNode(nm); + // // if not found with just the string, search the tree. + // if (nd==null)nd = this.SelectSingleNode("*/"+nm); + // if (nd == null) // not found, write out a '0'. + // xmldoc.writeInt(0); + // else + // { + // VlnXmlElement end; + // end = (VlnXmlElement) nd; + // xmldoc.writeTextValue(end.InnerText); + // } + // xmldoc.popHeader(); + // } + // } + // xmldoc.writeRROEnd(); + // } + // return true; + //} public XmlNode GetCurrentOfMultiFields(VlnXmlElement CurElement, string FldName) { @@ -997,6 +1065,19 @@ namespace RODBInterface return nd; } + private bool ContainedInArrayList(ROField rof, ArrayList aryList) + { + bool isInList = false; + foreach (ROField arof in aryList) + { + if (arof.GetRecID == rof.GetRecID) + { + isInList = true; + break; + } + } + return isInList; + } // ShowRRO writes data for the input RO. private bool ShowRRO(RODB myrodb, ArrayList headers) { @@ -1010,7 +1091,8 @@ namespace RODBInterface string tmp=null; // needed for inuse call ArrayList AvailList = myrodb.RODB_GetFields(this, 0); ArrayList InUseList = myrodb.RODB_GetFieldsInUse(this, AvailList, "FieldsInUse", ref tmp, false); - + ArrayList InUseApplcList = myrodb.RODB_GetApplicabilityEnabledFields(this, InUseList, ref tmp, HasApplicabilityEnabled); // C2021-026 get fields that have P/C Children + string defPCROval = ""; // put out the stored headers, i.e. the group titles up the tree. xmldoc.doHeader(headers); @@ -1094,13 +1176,33 @@ namespace RODBInterface if (doingplot) xmldoc.writePlot(end.InnerText); else + { xmldoc.writeTextValue(end.InnerText); - + defPCROval = end.InnerText; + } + } + } + // C2021_026 put out PC children values + if (ContainedInArrayList(rof,InUseApplcList)) + { + XmlNode pcn; + int pcChildIdx = 0; + foreach (string s in PCChildren) + { + pcChildIdx++; + string pcName = nd.Name + string.Format("_PCCHILD{0}", pcChildIdx); // create child field name + string pcField = rof.MakeFieldName(pcName); + xmldoc.pushHeader(" "+s); // put out the PC Child name (indented 5 spaces) for complete RO Report + // see if it has data in the ro. + pcn = this.SelectSingleNode(pcField); + if (pcn != null) + xmldoc.writeTextValue(pcn.InnerText); // use PC Child value + else + xmldoc.writeTextValue(defPCROval); // use default value } } xmldoc.popHeader(); } - } xmldoc.writeRROEnd(); } @@ -1184,12 +1286,21 @@ namespace RODBInterface headers.RemoveAt(headers.Count-1); return true; } + private static string[] PCChildren = null; //C2021-026 holds list of P/C children names + public bool HasApplicabilityEnabled + { + get + { + return (PCChildren != null && PCChildren.Length > 0); + } + } // put this element, and if a group all it's subelements out to the 'print.tmp' // file for complete reports. - public bool Show(RODB myrodb, ArrayList headers, VlnStatusMessage showStat) + public bool Show(RODB myrodb, ArrayList headers, VlnStatusMessage showStat, string [] pcChildren) { bool success; + PCChildren = pcChildren; // C2021-026 list of P/C children VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument; success = xmldoc.OpenTemp(); if (success==false) return false; diff --git a/PROMS/ReferencedObjects/LibSource/ROField/ROField.cs b/PROMS/ReferencedObjects/LibSource/ROField/ROField.cs index 7d577c9b..64fa3a86 100644 --- a/PROMS/ReferencedObjects/LibSource/ROField/ROField.cs +++ b/PROMS/ReferencedObjects/LibSource/ROField/ROField.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: ROField.cs $ $Revision: 11 $ @@ -63,12 +63,22 @@ using System.Text; namespace ROFields { +// Field Types: +// SingleTxt - Single Line Text +// VariableTxt - Variable Length Text (multiple lines) +// FrmtSingleTxt - Single Line Formatted text - used for Accessory ID fields +// XYPlot - used to enter the plot language commands +// Table - Used to enter a table (16-bit VE-PROMS text based style using dashes and pipe characters to define cells) +// Image - Used for images (ex. TIF,JPG,BMP file references) +// MultiTxt - ?? +// Combination - used for Setpoint return values - user can select type of return value (Single/Multi line text, Table, X/Y Plot) +// when entering the RO data +// MultiField - ?? public enum FieldTypes: uint { Nil=0, SingleTxt=1, VariableTxt=2, FrmtSingleTxt=4, XYPlot=8, Table=10, Image=32, MultiTxt=40, Combination=128, MultiFld=100 } - /// /// Summary description for ROField: This class contains RO Field information. Each ROField /// contains: @@ -92,7 +102,7 @@ namespace ROFields recID = rID; masterrecID = mrID; fldtype = fieldtype; - } + } public string GetFieldname { get {return fieldname;}} public string GetRecID { get {return recID;}} public string GetMasterRecID { get {return masterrecID;}} @@ -101,7 +111,23 @@ namespace ROFields public void SetRecID(string recid) {recID = recid;} public void SetMasterRecID(string mrecid) {masterrecID = mrecid;} public void SetFieldType(uint ftype) {fldtype = ftype;} - + + // C2021-026 return true if we allow child values for the current field type + public bool FieldTypeCanDoApplicability() + { + bool rtnval = false; + switch (fldtype) + { + case (uint)FieldTypes.SingleTxt: + case (uint)FieldTypes.VariableTxt: + case (uint)FieldTypes.Combination: + rtnval = true; + break; + } + return rtnval; + } + + // Given a schema string, determine which RO Field type it is. public uint ParseFieldType(string info) { @@ -191,7 +217,7 @@ namespace ROFields StringBuilder strbld = new StringBuilder(); strbld.Append("\n"); + strbld.Append("\" minOccurs=\"0\">\n"); if (ftype == (uint)FieldTypes.VariableTxt || ftype == (uint)FieldTypes.Table || ftype == (uint)FieldTypes.XYPlot) { strbld.Append("\n"); diff --git a/PROMS/ReferencedObjects/LibSource/ctlXMLEditLib/ctlXMLEdit.cs b/PROMS/ReferencedObjects/LibSource/ctlXMLEditLib/ctlXMLEdit.cs index 4e510cbe..73219830 100644 --- a/PROMS/ReferencedObjects/LibSource/ctlXMLEditLib/ctlXMLEdit.cs +++ b/PROMS/ReferencedObjects/LibSource/ctlXMLEditLib/ctlXMLEdit.cs @@ -1,5 +1,5 @@ /********************************************************************************************* - * Copyright 2002 - Volian Enterprises, Inc. All rights reserved. + * Copyright 2021 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: ctlXMLEdit.cs $ $Revision: 36 $ @@ -258,12 +258,17 @@ namespace ctlXMLEditLib int DPPL = (720/6); int DPPC = (720/12); int height, width; - + + /** C2021-026 the following are use for Parent Child RO fields **/ + public ArrayList FieldsWithApplic = null; + public string[] PCChildren; + private GroupBox pcGrpBox = null; + /** end C2021-026 **/ + // use this struct to define attributes for the text box fields, storing // the pattern, radio button association, required field flag, etc. struct TextBoxAttrTag { - bool required; //whether the field is required string req_msg; //message to print if required, but not set string pattern; //pattern for validation @@ -295,10 +300,12 @@ namespace ctlXMLEditLib public void SetImageDate(string imgdate) {this.imagedate = imgdate;} } - public ctlXMLEdit(VlnXmlElement myelem, XmlSchema myschema, ArrayList reqfields) + public ctlXMLEdit(VlnXmlElement myelem, XmlSchema myschema, ArrayList reqfields, ArrayList fldsWithApplic, string [] pckids) { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); + FieldsWithApplic = fldsWithApplic; + PCChildren = pckids; //C2021-026 list of Parent/Child children zmtooltip = new ToolTip(); myHT = new Hashtable(); tabindx=0; @@ -409,6 +416,38 @@ namespace ctlXMLEditLib } } } + + // C2021-026 If this is a Parent/Child field that has no value saved in the database + // then use the parent's value and display it as grey colored text. + private void GetDefaultParentValue(TextBox tb, XmlNode node, string chldName) + { + XmlNode parentNode = null; + // PCChildren contains a list strings reprenting the Children setup in the current Working Draft Parent/Child property + if (PCChildren == null) return; // C2021-026 no children to process + int pcChildIdx = 0; // C2021-026 corresponds with DocVersionConfig.SelectedSlave value: 0 = no child selected 1 = first child ... + foreach (string c in PCChildren) + { + pcChildIdx++; + string csufx = string.Format("_PCCHILD{0}", pcChildIdx); // C2021-026 create a child field name + if (chldName.EndsWith(csufx)) + { + int idx = chldName.LastIndexOf(csufx); + if (idx > 0) + { + string parent = chldName.Remove(idx); + parentNode = node.SelectSingleNode(parent); + // if not found with just the string, search the tree. + if (parentNode == null) parentNode = node.SelectSingleNode("*/" + parent); + if (parentNode != null) + { + tb.Text = parentNode.InnerText; // set the P/C Child text box to the parent's value + tb.ForeColor = SystemColors.GrayText; + break; + } + } + } + } + } // Given a parent XmlNode, walk through the child nodes & add the text for the // node to the associated text box. @@ -425,7 +464,9 @@ namespace ctlXMLEditLib nd = node.SelectSingleNode(str); // if not found with just the string, search the tree. if (nd==null)nd = node.SelectSingleNode("*/"+str); - if (nd != null) + if (nd == null) + GetDefaultParentValue(hwnd, node, str); // C2021-026 Parent/Child Field has no value so use parent's value + else { hwnd.Text = nd.InnerText; // set the field's text from XML @@ -504,8 +545,8 @@ namespace ctlXMLEditLib { // if MaxWidth is small, a scroll bar appears below the fields // so make this a bit larger, so a scroll bar doesn't appear - if (MaxWidth<30) return MaxWidth+60; - return MaxWidth+30; + if (MaxWidth < 30) return MaxWidth + 100; + return MaxWidth + 70; } public int GetMaxLength() { @@ -569,11 +610,46 @@ namespace ctlXMLEditLib editelem.InnerXml = savedInnerXml; } + //C2021-026 when saving the RO record, if a PC Child's textbox contains a value identical + // to the parent's value, then clear the child's textbox so that nothing is saved + // to the database. This allow us to know that a specific value was not set + // for this Parent/Child child + private void RemovePCChildTextIfSameAsParent(XmlNode node, TextBox tb, string chldName) + { + XmlNode parentNode = null; + // if this is a child node get the parent's value + // PCChildren contains a list strings reprenting the Children setup in the current Working Draft Parent/Child property + if (PCChildren == null) return; + int pcChildIdx = 0; + foreach (string c in PCChildren) + { + //string csufx = CvtUserFldToFld(c); + pcChildIdx++; + string csufx = string.Format("_PCCHILD{0}", pcChildIdx); + if (chldName.EndsWith(csufx)) + { + int idx = chldName.LastIndexOf(csufx); + if (idx > 0) + { + string parent = chldName.Remove(idx); + parentNode = node.SelectSingleNode(parent); + // if not found with just the string, search the tree. + if (parentNode == null) parentNode = node.SelectSingleNode("*/" + parent); + if (parentNode != null && parentNode.InnerText == tb.Text) + { + tb.Text = ""; + break; + } + } + } + } + } + // SaveData saves the data in the element which had been sent to the control. Return // true if success, false if fail. + // Note that the Parent and Child XML node variables below are not coding for Parent/Child Applicabily Fields public bool SaveData() { - if (mysavexml) { TextBox hwnd; @@ -586,7 +662,6 @@ namespace ctlXMLEditLib object o = myHT[str]; hwnd = (TextBox) o; imgdate = null; - // if this is a required field and there is no text, put out an error // message and get out of here. if (hwnd.Tag != null) @@ -602,7 +677,6 @@ namespace ctlXMLEditLib return (false); } imgdate = tag.GetImageDate; - } // find the element in the current element node. @@ -612,7 +686,7 @@ namespace ctlXMLEditLib XmlNode elmnode = (XmlNode) editelem; XmlNode nd = elmnode.SelectSingleNode(str); if (nd == null) nd = elmnode.SelectSingleNode("*/"+str); - + RemovePCChildTextIfSameAsParent(elmnode, hwnd, str); // C2021-026 will clear hwnd.Text if child value is same as parent value // handle, element exists - but text removed first (delete element) if ((hwnd.Text == null || hwnd.Text == "") && nd != null) { @@ -694,6 +768,7 @@ namespace ctlXMLEditLib } } mysavexml=false; // data has been saved, don't allow it again. + DisplayFieldContents((XmlNode) editelem); // to refresh display after saving Parent/Child fields to show default values return(true); } return (false); @@ -783,7 +858,8 @@ namespace ctlXMLEditLib { XmlSchemaDocumentation doc = (XmlSchemaDocumentation) item; XmlNode[] node = (XmlNode[]) doc.Markup; - + // Note: this has nothing to do with PROMS Annotations. This is more of a field type description + // used for Graphics (figures) RO fields to setup event handlers and buttons to display a Find File Dialog getannot = node[0].InnerText; if (getannot == "VLN_FINDFILE") { @@ -894,7 +970,6 @@ namespace ctlXMLEditLib else tmp = element.SchemaTypeName.Name; radio.Text = CvtFldToUserFld(tmp); - //radio.Width = (int) radio.Font.SizeInPoints * radio.Text.Length + 20; // add 20 for button radio.TabIndex = 0; ysize = (int) radio.Height; @@ -916,8 +991,20 @@ namespace ctlXMLEditLib tb.KeyDown += new KeyEventHandler(MyOnKeyDown); gbox.Contains(tb); // the following will set attributes on the text boxes such as maxlength, multiline, etc. - DisplayXmlSchemaSimpleType((XmlSchemaSimpleType)element.SchemaType, tb, radio,false,null); - rety = (ysize + 25 + tb.Height); + DisplayXmlSchemaSimpleType((XmlSchemaSimpleType)element.SchemaType, tb, radio,false,null); + int chldGrpHeight = 0; + if (FieldsWithApplic != null && FieldsWithApplic.Contains(gbox.Text) && radio.Text == "Fixed") // C2021-026 user turned appicability on for this field + { + int saveScreeny = screeny; + int saveScreenx = screenx; + screeny += tb.Height + 50; + screenx += 20; + pcGrpBox = null; // C2021-026 used to hide/show Parent/Child group when radio buttons are selected + DisplayAppicChildrenGroup(element, PCChildren, ref chldGrpHeight, gbox.Text); // C2021-026 make sub-group for Parent/Child child fields (if needed) + screeny = saveScreeny; + screenx = saveScreenx; + } + rety = (ysize + 25 + chldGrpHeight + tb.Height); retx = tb.Width; } @@ -956,25 +1043,84 @@ namespace ctlXMLEditLib // get the widths of all children of this group box & use this to set the size // of the groupbox. int gritms = groupbox.Controls.Count; - screeny=screeny+maxyfortext+10; + screeny = screeny + maxyfortext + 20; MaxWidth = (maxxfortext+40>MaxWidth)?maxxfortext+40:MaxWidth; groupbox.Size = new System.Drawing.Size(maxxfortext+40, maxyfortext+10); Controls.Add(groupbox); } private void DisplayXmlSchemaElement(XmlSchemaElement element) + { + string userfldName = CvtFldToUserFld(element.Name); + string childLabel = ""; + bool pcApplic = FieldsWithApplic != null && FieldsWithApplic.Contains(userfldName); // C2021-026 returns True if field should show Parent/Child Applicability fields + if (pcApplic) childLabel = CvtFldToUserFld(element.Name); + int dmy = 0; + DoDisplayXmlSchemaElement(element, childLabel, 0, ref dmy, Color.Transparent, 0); + if (pcApplic) + { + // C2021-026 this will create a grouping containing Parent/Child Applicability fields + DisplayAppicChildrenGroup(element, PCChildren, ref dmy, null); + screeny += 10; + } + } + // C2021-026 Creates a group box containing Parent/Child Applicability fields + // the group box is indented and shaded a blue color + private void DisplayAppicChildrenGroup(XmlSchemaElement element, string [] PCChildren, ref int chldgrphgt, string altGrpName) + { + int screenposx, screenposy; + int savescreenX = screenx; + screenx += 20; + GroupBox groupbox = new GroupBox(); + groupbox.BackColor = Color.AliceBlue; + groupbox.SuspendLayout(); + groupbox.Location = new System.Drawing.Point(screenx, screeny); + groupbox.Name = "PCgb_" + element.Name; + groupbox.TabStop = false; + + // remove the last character of the name for the title of the group box. + string tstr = (altGrpName == null)?CvtFldToUserFld(element.Name):altGrpName;//(elem.Name); + groupbox.Text = "Child Values"; + screenposx = screenx + 20; + screenposy = screeny + 20; + int screenySave = screeny; + screeny += 20; + int maxChldWidth = 0; + int pcChildIdx = 0; + foreach (string s in PCChildren) + { + string childLabel = s; + pcChildIdx++; + DoDisplayXmlSchemaElement(element, childLabel, 20, ref maxChldWidth,Color.AliceBlue, pcChildIdx); + } + // get the widths and number of all children of this group box & use this to set the size + // of the groupbox. + groupbox.Size = new System.Drawing.Size(Math.Max(55,maxChldWidth + 40), screeny - screenySave + 5);//maxxfortext + 40, maxyfortext + 10); + chldgrphgt = screeny - screenySave + 5; + Controls.Add(groupbox); + if (pcGrpBox == null) + pcGrpBox = groupbox; // only save if is in a Choice (radio button) group - used to hide/unhide the P/C Group box when radio buttons are selected + screenx = savescreenX; + } + private void DoDisplayXmlSchemaElement(XmlSchemaElement element, string applicLabel, int indent, ref int maxwidth, Color chlbckcolor, int pcChildIdx) { // always add a label. - Label mylabel; int sscreeny; - mylabel = new System.Windows.Forms.Label(); - mylabel.Location = new Point(screenx, screeny); - mylabel.Name = element.Name; - mylabel.Text = CvtFldToUserFld(element.Name); + string userfldName = CvtFldToUserFld(element.Name); + string pcChildFldName = element.Name; // C2021-026 PC Child field name + // C2021-026 the first PC Child has pcChildIdx of one + if (pcChildIdx > 0) + pcChildFldName += string.Format("_PCCHILD{0}", pcChildIdx); + Label mylabel; + mylabel = new System.Windows.Forms.Label(); + mylabel.BackColor = chlbckcolor; // PC Applic fields are shaded blue otherwise backcolor is transparent + mylabel.Location = new Point(screenx+indent, screeny); + mylabel.Name = (pcChildIdx == 0) ? CvtUserFldToFld(element.Name) : CvtUserFldToFld(pcChildFldName); + mylabel.Text = (applicLabel.Length > 0) ? applicLabel : CvtFldToUserFld(element.Name); // C2021-026 applicLabel is the P/C Child name mylabel.AutoSize = true; Controls.Add(mylabel); // add 3 onto screeny so that textbox is slightly below label. - screeny = screeny+mylabel.Height+3; + screeny = screeny + mylabel.Height + 3; sscreeny = screeny; // save 'y' location in case of annotation. if (element.SchemaType != null && element.SchemaType is XmlSchemaComplexType) { @@ -986,23 +1132,34 @@ namespace ctlXMLEditLib { TextBox mytextbox; mytextbox = new TextBox(); - mytextbox.Location = new Point(screenx, screeny); - myHT.Add(element.Name,mytextbox); + mytextbox.Location = new Point(screenx+indent, screeny); + string tFieldName = (pcChildIdx == 0) ? CvtUserFldToFld(element.Name) : CvtUserFldToFld(pcChildFldName); + myHT.Add(tFieldName, mytextbox); tabindx++; Controls.Add(mytextbox); - screeny+=mytextbox.Height; + screeny = screeny + 10; mytextbox.TextChanged += new System.EventHandler(this.textbox_change); mytextbox.Validating += new System.ComponentModel.CancelEventHandler(this.textbox_Validating); mytextbox.GotFocus += new System.EventHandler(this.textbox_zoombtn); mytextbox.KeyDown += new KeyEventHandler(MyOnKeyDown); + if (pcChildIdx > 0) + { + mytextbox.Enter += new System.EventHandler(this.txtBox_Enter); + mytextbox.Leave += new System.EventHandler(this.txtBox_Leave); + } string labelAnnot; bool imgchld = false; if (element.Name == "Image_Filename" || element.Name == "Image_Height" || element.Name == "Image_Width") imgchld = true; // Pass the textbox in to set attributes such as maxlength, multiline and pattern + // DisplayXmlSchemaSimpleType will set up + // - the textbox length which is needed to determin the Parent/Child group box width + // - add special buttons and events for Graphic (figure) RO type fields labelAnnot = DisplayXmlSchemaSimpleType((XmlSchemaSimpleType)element.SchemaType,mytextbox, null,imgchld,GraphicsText); if (labelAnnot != null) { + // this is part of a Graphics (figure) RO - either the height or width adjustment text box + // so put a lable next to the respective height/width text box Label annot; annot = new System.Windows.Forms.Label(); annot.Location = new Point(screenx+mytextbox.Width+10, sscreeny); @@ -1011,7 +1168,9 @@ namespace ctlXMLEditLib annot.AutoSize = true; Controls.Add(annot); } - screeny+=mytextbox.Height; + screeny += mytextbox.Height; + maxwidth = Math.Max(maxwidth, mylabel.Width); // is the label wider? + maxwidth = Math.Max(mytextbox.Width, maxwidth); // is the text box wider? } } @@ -1028,6 +1187,37 @@ namespace ctlXMLEditLib { if(dosaveflag)mysavexml = true; } + // C2021-026 Event handler for Parent/Child child textbox + // if the textbox text is same as parent, then or nothing is entered in the textbox + // then use the parent value and set the text color to gray + private void txtBox_Leave(object sender, EventArgs e) + { + TextBox tb = sender as TextBox; + string dfTxt = ""; + string parName = pcGrpBox.Name.Substring(5); + object o = myHT[parName]; + if (o != null) + dfTxt = (o as TextBox).Text; // set to use the parent's value (default) + if (dosaveflag) mysavexml = true; + if (tb.Text.Length == 0 || tb.Text == dfTxt) + { + tb.Text = dfTxt; + tb.ForeColor = SystemColors.GrayText; + } + } + + // C2021-026 Event handler for Parent/Child child textbox + // If the textbox is set to gray, then we are using the parent value + // so clear the textbox so that user can enter the value for that child + private void txtBox_Enter(object sender, EventArgs e) + { + TextBox tb = sender as TextBox; + if (tb.ForeColor == SystemColors.GrayText) // currently no value set - using parent's value + { + tb.Text = ""; + tb.ForeColor = SystemColors.WindowText; + } + } // radiocheckchg - called when a radio button is selected. This will set // visibility for associated text box. @@ -1050,6 +1240,30 @@ namespace ctlXMLEditLib assocbox = (TextBox) o; // make the text box visible if checked, otherwise, invisible assocbox.Visible = btnsel.Checked; + // C2021-026 show or hide the Parent/Child appicability group box + if (pcGrpBox != null) // note that we save only one applicability group box and only for the schema choice field type (radio buttons) + { + bool vsblState = (btnsel.Text == "Fixed"); // only show parent/child group if the Fixed radio button is selected + { + pcGrpBox.Visible = vsblState; // show or hide the P/C Children group box (the box shaded in blue) + // C2021-026 PCChildren contains a list strings reprenting the Children setup in the current Working Draft Parent/Child property + int pcChildIdx = 0; + foreach (string s in PCChildren) + { + pcChildIdx++; + string fldx = string.Format("_PCCHILD{0}", pcChildIdx); // create a field name for P/C Child fields + string tstr = pcGrpBox.Name.Substring(5) + fldx; // get the base part of the label and text box control name + foreach (Control c in Controls) + if (c.Name == tstr) + { + c.Visible = vsblState; // show or hide the lable inside the group box + object oo = myHT[c.Name]; + if (oo != null) + (oo as TextBox).Visible = vsblState; // show or hide the associated text box + } + } + } + } } // these two methods convert user input field names from/to xml tags. (xml tags diff --git a/PROMS/VEPROMS.CSLA.Library/Config/ROFSTLookup.cs b/PROMS/VEPROMS.CSLA.Library/Config/ROFSTLookup.cs index 22cb52c4..da116eb5 100644 --- a/PROMS/VEPROMS.CSLA.Library/Config/ROFSTLookup.cs +++ b/PROMS/VEPROMS.CSLA.Library/Config/ROFSTLookup.cs @@ -300,6 +300,40 @@ namespace VEPROMS.CSLA.Library } return val; } + // C2021-026 Get the child RO value if it exists, otherwise to the default (parent) RO value + public string GetParentChildROValue(rochild roc) + { + string roval = roc.value; + // get the child (slave) information and set the rtnchld.value to the corresponding RO Value + int selChldIdx = MyDocVersionInfo.DocVersionConfig.SelectedSlave; + string childName = MyDocVersionInfo.DocVersionConfig.Unit_Name; + string aplString = roval; + string ChldValue = ""; + // if the RO Value contains Parent/Child values, parse out default value and the child (slave or unit specific) value + while (roval.Contains("", startCVIdx); + aplString = roval.Substring(startCVIdx, EndCVidx + 6 - startCVIdx); + int endDefIdx = aplString.IndexOf(",UnitIdx=",startCVIdx); // look for more than just a comma incase value contains a comma + string defValue = aplString.Substring(16,endDefIdx-16); // save the default RO value + int idx = aplString.IndexOf("UnitIdx=" + selChldIdx.ToString()); // look for a specific child (slave/unit) value + if (selChldIdx > 0 && idx > -1 && idx < aplString.Length) + { + idx = aplString.IndexOf("Value=", idx) + 6; + int idxEndVal = aplString.IndexOf(",UnitIdx=", idx); // look for more than just a comma incase value contains a comma + if (idxEndVal == -1) idxEndVal = EndCVidx; // if last child value is up to " /APL>" + if (idxEndVal > idx) + ChldValue = aplString.Substring(idx, idxEndVal - idx); // selected Child RO value + else + ChldValue = defValue; // incomplete "") with the specifc value + } + return roval; + } // this only gets rochild values. Later we may want another // dictionary to get groups. public string GetRoValue(string ROID16) @@ -311,14 +345,14 @@ namespace VEPROMS.CSLA.Library { rochild rochld = (rochild)dicRos[ROID.ToUpper()]; if (rochld.value != null && rochld.value != string.Empty) - return FixUnitROs( rochld.value); + return FixUnitROs(GetParentChildROValue(rochld)); if (rochld.children != null) { foreach (rochild child in rochld.children) if (child.roid.ToUpper() == ROID16.ToUpper() || (child.roid.EndsWith("0041") && ROID16.EndsWith("0000"))) - return FixUnitROs(child.value ?? "?"); - // if there isn't a specific match for multi-return values, default to the first child. - return FixUnitROs(rochld.children[0].value ?? "?"); + return FixUnitROs(GetParentChildROValue(child) ?? "?"); + // if there isn't a specific match for multi-return values, default to the first child. + return FixUnitROs(GetParentChildROValue(rochld.children[0]) ?? "?"); } } //if (ROID == "FFFF00000001") return _ROFstInfo.ROFstAssociations[0].MyDocVersion.DocVersionConfig.Unit_Number; @@ -1140,7 +1174,7 @@ namespace VEPROMS.CSLA.Library { rochild? child = GetROChildByAccPageID(accPageID, spDefault, igDefault); if (child == null) return null; - return ((rochild)child).value; + return GetParentChildROValue((rochild)child); // C2021-026 get the P/C value if it exists, otherwise get the non-P/C value } public int? GetROTypeByAccPagID(string accPageID, string spDefault, string igDefault) { diff --git a/PROMS/Volian.Controls.Library/DisplayRO.cs b/PROMS/Volian.Controls.Library/DisplayRO.cs index c3ccf79e..a0591acf 100644 --- a/PROMS/Volian.Controls.Library/DisplayRO.cs +++ b/PROMS/Volian.Controls.Library/DisplayRO.cs @@ -251,7 +251,9 @@ namespace Volian.Controls.Library switch (chld.type) { case 1: // standard (regular) text RO type - tbROValue.Text = chld.value.Replace(@"\u160?", " "); + string roval = chld.value.Replace(@"\u160?", " "); + roval = GetPCDefaultValue(roval); // C2021-026 get the default RO value from P/C RO value information + tbROValue.Text = roval; btnPreviewRO.Enabled = false; if (chld.roid.StartsWith("FFFF")) btnGoToRO.Enabled = false; @@ -317,6 +319,23 @@ namespace Volian.Controls.Library } private E_ROValueType _CurrentROTypeFilter = E_ROValueType.All; + // C2021-026 Get the Parent (Default) RO value if the return value include P/C information + // otherwise return the RO value as is. + // This is used for the insert RO interface on the Step Properties pannel + private string GetPCDefaultValue(string roval) + { + string rntval = roval; + while (rntval.Contains("", startCVIdx); + string aplicValues = rntval.Substring(startCVIdx, EndCVidx + 6 - startCVIdx); + int endDefIdx = rntval.IndexOf(",", startCVIdx); + string defValue = rntval.Substring(startCVIdx + 16, endDefIdx - (startCVIdx + 16)); + rntval = rntval.Replace(aplicValues, defValue); + } + return rntval; + } private void LoadChildren(TreeNode tn) { object tag = tn.Tag; @@ -378,7 +397,9 @@ namespace Volian.Controls.Library //} else { - tmp = new TreeNode(chld[i].title.Replace(@"\u160?"," ")); + string ntitle = chld[i].title.Replace(@"\u160?", " "); + ntitle = GetPCDefaultValue(ntitle); // C2021-026 get the default RO value from P/C RO value information + tmp = new TreeNode(ntitle); tmp.Tag = chld[i]; if (chld[i].roid.Length == 16) tn.Nodes.Add(tmp); @@ -887,6 +908,14 @@ namespace Volian.Controls.Library string args = "\"" + _MyROFST.MyRODb.FolderPath + "\" " + roch.roid.ToLower(); // C2017-003: ro data in sql server, check for sql connection string if (_MyROFST.MyRODb.DBConnectionString != "cstring") args = args + " \"" + _MyROFST.MyRODb.DBConnectionString + "\""; + // C2021-026 pass in Parent/Child information (list of the children) + DocVersionConfig dvc = Mydvi.DocVersionConfig as DocVersionConfig; + if (dvc != null) + { + string str = dvc.Unit_Name; + if (str!="" && str!="0") + args += " \"PC=" + str + "\""; + } System.Diagnostics.Process.Start(roapp, args); } } @@ -929,6 +958,14 @@ namespace Volian.Controls.Library } // C2017-003: ro data in sql server, check for sql connection string if (_MyROFST.MyRODb.DBConnectionString != "cstring") args = args + " \"" + _MyROFST.MyRODb.DBConnectionString + "\""; + // C2021-026 pass in Parent/Child information (list of the children) + DocVersionConfig dvc = Mydvi.DocVersionConfig as DocVersionConfig; + if (dvc != null) + { + string str = dvc.Unit_Name; + if (str != "" && str !="0") + args += " \"PC=" + str + "\""; + } System.Diagnostics.Process.Start(roapp, args); } } diff --git a/PROMS/Volian.Controls.Library/DisplayReports.cs b/PROMS/Volian.Controls.Library/DisplayReports.cs index 11ddb9b4..2a3362ae 100644 --- a/PROMS/Volian.Controls.Library/DisplayReports.cs +++ b/PROMS/Volian.Controls.Library/DisplayReports.cs @@ -938,6 +938,16 @@ namespace Volian.Controls.Library string roloc = "\"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath + "\" \"/f=" + fname + "\""; // C2017-003: ro data in sql server, check for sql connection string if (MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString != "cstring") roloc = roloc + " \"/sql=" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString + "\""; + + // C2021-026 pass in Parent/Child information (list of the children) + DocVersionConfig dvc = MyDVI.DocVersionConfig as DocVersionConfig; + if (dvc != null) + { + string str = dvc.Unit_Name; + if (str != "" && str != "0") + roloc += " \"/PC=" + str + "\""; + } + System.Diagnostics.Process p = System.Diagnostics.Process.Start(cmpRptExePath, roloc); // need to wait, sometimes the Print.tmp file that is generated is not available p.WaitForExit(); // without arguments, this will wait indefinitely diff --git a/PROMS/Volian.Controls.Library/StepTabRibbon.cs b/PROMS/Volian.Controls.Library/StepTabRibbon.cs index e3ba9d34..1b7bec16 100644 --- a/PROMS/Volian.Controls.Library/StepTabRibbon.cs +++ b/PROMS/Volian.Controls.Library/StepTabRibbon.cs @@ -3112,6 +3112,14 @@ namespace Volian.Controls.Library } // C2017-003: ro data in sql server, check for sql connection string if (myRODB.DBConnectionString != "cstring") args = args + " \"" + myRODB.DBConnectionString + "\""; + // C2021-026 pass in Parent/Child information (list of the children) + DocVersionConfig dvc = Mydvi.DocVersionConfig as DocVersionConfig; + if (dvc != null) + { + string str = dvc.Unit_Name; + if (str!="" && str!="0") + args += " \"PC=" + str + "\""; + } System.Diagnostics.Process.Start(roapp, args); } } @@ -3268,6 +3276,14 @@ namespace Volian.Controls.Library } // C2017-003: ro data in sql server, check for sql connection string if (Mydvi.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString != "cstring") roloc = roloc + " \"" + Mydvi.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString + "\""; + // C2021-026 pass in Parent/Child information (list of the children) + DocVersionConfig dvc = Mydvi.DocVersionConfig as DocVersionConfig; + if (dvc != null) + { + string str = dvc.Unit_Name; + if (str!="" && str!="0") + roloc += " \"PC=" + str + "\""; + } System.Diagnostics.Process.Start(roapp, roloc); } diff --git a/PROMS/Volian.Controls.Library/vlnTreeView.cs b/PROMS/Volian.Controls.Library/vlnTreeView.cs index 30111f27..9ff8dd14 100644 --- a/PROMS/Volian.Controls.Library/vlnTreeView.cs +++ b/PROMS/Volian.Controls.Library/vlnTreeView.cs @@ -2088,7 +2088,16 @@ namespace Volian.Controls.Library return; } // C2017-003: ro data in sql server, check for sql connection string - if (MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString != "cstring") roloc = roloc + " \"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString + "\""; + if (MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString != "cstring") + roloc = roloc + " \"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString + "\""; + // C2021-026 pass in Parent/Child information (list of the children) + DocVersionConfig dvc = MyDVI.DocVersionConfig as DocVersionConfig; + if (dvc != null) + { + string str = dvc.Unit_Name; + if (str !="" && str != "0") + roloc += " \"PC=" + str + "\""; + } System.Diagnostics.Process.Start(roapp, roloc); }