/********************************************************************************************* * Copyright 2021- Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: RODefFrm.cs $ $Revision: 18 $ * $Author: Kathy $ $Date: 9/06/05 11:26a $ * * $History: RODefFrm.cs $ * * ***************** Version 18 ***************** * User: Kathy Date: 9/06/05 Time: 11:26a * Updated in $/EXE/RefObj/ROEditor * B2005-035 * * ***************** Version 17 ***************** * User: Jsj Date: 7/02/03 Time: 9:25a * Updated in $/EXE/RefObj/ROEditor * made messagebox calls modal by removing the parent window reference * * ***************** Version 16 ***************** * User: Kathy Date: 5/21/03 Time: 12:52p * Updated in $/EXE/RefObj/ROEditor * B2003-041: process if only one field for RO & not always saving ro * field name edit * * ***************** Version 15 ***************** * User: Kathy Date: 5/07/03 Time: 1:58p * Updated in $/EXE/RefObj/ROEditor * B2003-033 fixed * * ***************** Version 14 ***************** * User: Jsj Date: 4/14/03 Time: 3:03p * Updated in $/EXE/RefObj/ROEditor * changes due to RO FST file creation speed up * * ***************** Version 13 ***************** * User: Kathy Date: 12/10/02 Time: 2:26p * Updated in $/EXE/RefObj/ROEditor * fieldname special chars & bug fixes * * ***************** Version 12 ***************** * User: Kathy Date: 12/02/02 Time: 9:25a * Updated in $/EXE/RefObj/ROEditor * after edit fieldname, update menu & retval correctly * * ***************** Version 11 ***************** * User: Kathy Date: 12/02/02 Time: 8:30a * Updated in $/EXE/RefObj/ROEditor * fieldname replace chars * * ***************** Version 10 ***************** * User: Kathy Date: 12/02/02 Time: 6:19a * Updated in $/EXE/RefObj/ROEditor * status on long ops & update text box for fieldname change * * ***************** Version 9 ***************** * User: Kathy Date: 11/19/02 Time: 11:30a * Updated in $/EXE/RefObj/ROEditor * validate retval (handle {}) * * ***************** Version 8 ***************** * User: Kathy Date: 10/15/02 Time: 2:18p * Updated in $/EXE/RefObj/ROEditor * new group (table) * * ***************** Version 7 ***************** * User: Kathy Date: 10/10/02 Time: 10:02a * Updated in $/EXE/RefObj/ROEditor * try to m ake xml tree & tree control in sync * * ***************** Version 6 ***************** * User: Kathy Date: 9/25/02 Time: 2:31p * Updated in $/EXE/RefObj/ROEditor * multitxt->variable * * ***************** Version 5 ***************** * User: Kathy Date: 9/25/02 Time: 9:57a * Updated in $/EXE/RefObj/ROEditor * dev * * ***************** Version 4 ***************** * User: Kathy Date: 9/19/02 Time: 10:04a * Updated in $/EXE/RefObj/ROEditor * mods for subgroup apply below node. if mod menutitle template, update * menu titles from node down. * * ***************** Version 3 ***************** * User: Kathy Date: 9/11/02 Time: 1:15p * Updated in $/EXE/RefObj/ROEditor * vlnxml * * ***************** Version 2 ***************** * User: Kathy Date: 8/28/02 Time: 10:57a * Updated in $/EXE/RefObj/ROEditor *********************************************************************************************/ using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Xml; using System.Xml.Schema; using System.Text; using ROFields; using RODBInterface; using VlnStatus; using System.Collections.Generic; namespace ROEditor { /// /// Summary description for RODefinition. /// public class RODefFrm : System.Windows.Forms.Form { private System.Windows.Forms.Label lblGroup; private System.Windows.Forms.Label lblRetVal; private System.Windows.Forms.Label lblMenuVal; private System.Windows.Forms.TextBox tbRetVal; private System.Windows.Forms.TextBox tbMenuVal; private System.Windows.Forms.Label lblGroupText; private System.Windows.Forms.GroupBox gbFields; 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; private System.Windows.Forms.Button btnRemove; private System.Windows.Forms.Button btnNew; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private RODB myrodb; ArrayList AvailList; 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 string strFieldsInUse; private string origFieldsInUse; private string origApplicFields; private string origRetVal; private string origMenuItem; 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) { myrodb = rodb; strFieldsInUse = fields; dbtype = idbtype; if (fields == "FieldsInUse") // not a group level edit. editlevel = (uint) RecordType.Schema; else editlevel = (uint) RecordType.GroupSchema; elem = pelem; // // Required for Windows Form Designer support // InitializeComponent(); // 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); } /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } private void FillInAvailable() { ROField rof; // put the items in the AvailList box. for (int i = 0; i < AvailList.Count; i++) { rof = (ROField)AvailList[i]; if (rof.GetFieldname != null) // DO YET: Why null? 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, 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) { // add items to the InUseList box. for (int i = 0; i < InUseList.Count; i++) { rof = (ROField)InUseList[i]; if (rof.GetFieldname != null) //DO YET: why null? { // 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; } private void DoValueTextBoxes() { string menuitm, retval; if (editlevel == (uint) RecordType.GroupSchema) { menuitm = elem.GetAttribute("GroupMenuItem"); this.tbRetVal.Visible = false; this.lblRetVal.Visible = false; VlnXmlElement parent; parent = (VlnXmlElement) elem.ParentNode; while (parent != null && (menuitm == "")) { // walk up tree to get parent and check for data there if (menuitm == "") menuitm = parent.GetAttribute("GroupMenuItem"); if (parent.Name != "RO_Root") parent = (VlnXmlElement) parent.ParentNode; else parent = null; } if (menuitm != "") this.tbMenuVal.Text = CvtFldToUserFld(menuitm); else this.tbMenuVal.Text = ""; } else { menuitm = elem.GetAttribute("MenuItem"); retval = elem.GetAttribute("RetVal"); this.tbRetVal.Visible = true; this.lblRetVal.Visible = true; VlnXmlElement parent; parent = (VlnXmlElement) elem.ParentNode; while (parent != null && (menuitm == "" || retval == "")) { // walk up tree to get parent and check for data there if (menuitm == "") menuitm = parent.GetAttribute("MenuItem"); if (retval == "") retval = parent.GetAttribute("RetVal"); if (parent.Name != "RO_Root") parent = (VlnXmlElement)parent.ParentNode; else parent = null; } if (menuitm != "") this.tbMenuVal.Text = CvtFldToUserFld(menuitm); else this.tbMenuVal.Text = ""; if (retval != "") this.tbRetVal.Text = CvtFldToUserFld(retval); else this.tbRetVal.Text = ""; } } private void FillInData(string grptxt) { this.lblGroupText.Text = grptxt; DoValueTextBoxes(); SetUpListBoxes(); 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); lboxInUse.MouseUp += new System.Windows.Forms.MouseEventHandler(this.lboxInUse_MouseUp); lboxInUseCB.MouseUp += new System.Windows.Forms.MouseEventHandler(this.lboxInUseCB_MouseUp); // save copies of local data, so if there is a change, we know we must save them. origRetVal = this.tbRetVal.Text; origMenuItem = this.tbMenuVal.Text; // if this is a database level definition & it's a user defined database, // the okay button is disabled until a field is used. if (elem.ParentNode.Name == "RO_Root" && dbtype == 3) { string attr; if (editlevel == (uint)RecordType.Schema) attr = elem.GetAttribute("FieldsInUse"); else attr = elem.GetAttribute("GroupFieldsInUse"); if (attr == null || attr == "") btnOK.Enabled = false; } } protected void lboxInUse_GotFocus(object sender, EventArgs e) { lboxAvail.ClearSelected(); this.btnRemove.Enabled = true; 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) { if (PCApplicabilityEnabled) lboxInUseCB.ClearSelected(); else lboxInUse.ClearSelected(); this.btnAdd.Enabled = true; this.btnRemove.Enabled = false; this.btnEdit.Enabled = true; } //CSM C2024-024 //Simple Selection of Fields to add to Return Values and Menu Values. //Part of 2024 PROMS Upgrades //Add Context Menu for In Use Listbox //Will allow user to right click Selected Items //and add then to the Return Value / Menu Value Text Boxes //without re-typing them protected void lboxInUse_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right && lboxInUse.SelectedItems.Count > 0) { ContextMenuStrip cn = new ContextMenuStrip(); if (tbRetVal.Visible) { var AddToReturnItem = new ToolStripMenuItem("Add to Return Value"); AddToReturnItem.Click += new EventHandler(lboxInUse_Click); AddToReturnItem.Name = "Add to Return Value"; cn.Items.Add(AddToReturnItem); } var AddToMenuItem = new ToolStripMenuItem("Add to Menu Value"); AddToMenuItem.Click += new EventHandler(lboxInUse_Click); AddToMenuItem.Name = "Add to Menu Value"; cn.Items.Add(AddToMenuItem); this.lboxInUse.ContextMenuStrip = cn; cn.Show(Control.MousePosition.X, Control.MousePosition.Y); } } private void lboxInUse_Click(object sender, EventArgs e) { switch (((ToolStripMenuItem)sender).Name) { case "Add to Return Value": if (tbRetVal.Text == "") tbRetVal.Text += $"<{lboxInUse.SelectedItem}>"; else tbRetVal.Text += $" - <{lboxInUse.SelectedItem}>"; break; case "Add to Menu Value": if (tbMenuVal.Text == "") tbMenuVal.Text += $"<{lboxInUse.SelectedItem}>"; else tbMenuVal.Text += $" - <{lboxInUse.SelectedItem}>"; break; } } //CSM C2024-024 //Simple Selection of Fields to add to Return Values and Menu Values. //Part of 2024 PROMS Upgrades //Add Context Menu for In Use ComboBox //(Replaces In Use Listbox when Applicability //to allow for selection of items per Unit) //Will allow user to right click Selected Items //and add then to the Return Value / Menu Value Text Boxes //without re-typing them protected void lboxInUseCB_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right && lboxInUseCB.SelectedItems.Count > 0) { ContextMenuStrip cn = new ContextMenuStrip(); if (tbRetVal.Visible) { var AddToReturnItem = new ToolStripMenuItem("Add to Return Value"); AddToReturnItem.Click += new EventHandler(lboxInUseCB_Click); AddToReturnItem.Name = "Add to Return Value"; cn.Items.Add(AddToReturnItem); } var AddToMenuItem = new ToolStripMenuItem("Add to Menu Value"); AddToMenuItem.Click += new EventHandler(lboxInUseCB_Click); AddToMenuItem.Name = "Add to Menu Value"; cn.Items.Add(AddToMenuItem); this.lboxInUseCB.ContextMenuStrip = cn; cn.Show(Control.MousePosition.X, Control.MousePosition.Y); } } private void lboxInUseCB_Click(object sender, EventArgs e) { switch (((ToolStripMenuItem)sender).Name) { case "Add to Return Value": if (tbRetVal.Text == "") tbRetVal.Text += $"<{lboxInUseCB.SelectedItem}>"; else tbRetVal.Text += $" - <{lboxInUseCB.SelectedItem}>"; break; case "Add to Menu Value": if (tbMenuVal.Text == "") tbMenuVal.Text += $"<{lboxInUseCB.SelectedItem}>"; else tbMenuVal.Text += $" - <{lboxInUseCB.SelectedItem}>"; break; } } private void btnRemove_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 (PCApplicabilityEnabled) // C2021-026 use the Check Box list { 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); lboxAvail.Items.Add(CvtFldToUserFld(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(CvtFldToUserFld(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 (PCApplicabilityEnabled) // C2021-026 using the Check Box List { 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); lboxInUseCB.Items.Add(CvtFldToUserFld(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(CvtFldToUserFld(copyrof.GetFieldname)); AvailList.RemoveAt(indx); lboxAvail.Refresh(); lboxInUse.Refresh(); btnOK.Enabled = true; } } } private void syntax(string prob,int start, int end) { lo=start; hi=end; parseerror.Append("Invalid Syntax - "); parseerror.Append(prob); } private void missingDelimiter(char chr,int start,int end) { lo=start; hi=end; string delim = "{}{<><"; int delindx; delindx = delim.IndexOf(chr,0); parseerror.Append("Couldn't find matching "); if (delindx >-1) parseerror.Append(delim.Substring(delindx,1)); else parseerror.Append("?"); } private bool isWhiteSpace(char chr) { return(chr!=0 && " \t\n\r".IndexOf(chr)!=-1); } private int endsIn(char chr, string str, int start, int end) { while(start <= end && isWhiteSpace(str[end]))end--; if(start <= end && str[end]==chr)return 1; return 0; } private void processBrace(string str, int start, int end) { int where=str.IndexOfAny("<>{}=".ToCharArray(),start,end-start); if(where!=0) { char chr=str[where]; switch(chr) { case '{': // verify that this ends in a } if(endsIn('}',str,where,end)==0) { syntax("should end with }",where,end); } break; case '<': syntax("< not permitted here",where,where); break; case '}': syntax("} not permitted here",start,where); break; case '>': syntax("> not permitted here",start,where); break; } } } private int findMatchingBrace(string str, int start, int end) { int where=start+1; int last=where; int termlevel=1; while(hi==0 && where <= end && termlevel!=0) { char chr=str[where]; switch (chr) { case '{': where=findMatchingBrace(str,where,end); where++; break; case '}': termlevel=0; break; case '>': missingDelimiter(chr,last,where); break; case '<': int next; next=str.IndexOfAny("{}<>".ToCharArray(),where+1,end-where); if(next==0) { missingDelimiter(chr,last,end); } else if(str[next]!='>') { missingDelimiter(chr,last,next); } else { last=where=next+1; } break; default: where++; break; } } if(hi==0 && termlevel!=0) { missingDelimiter('{',start,end); } return where; } private bool ValidReturnFieldSpec(string str, int start, int end) { if (parseerror != null) parseerror.Remove(0,parseerror.Length); else parseerror = new StringBuilder(); int where=start; int last=start; hi=lo=0; while(hi==0 && where <= end) { char chr=str[where]; switch (chr) { case '{': int next; next=findMatchingBrace(str,where,end); if(hi==0) { processBrace(str,where+1,next-1); where=next+1; last=where; } break; case '}': missingDelimiter(chr,last,where); break; case '>': missingDelimiter(chr,last,where); break; case '<': int strt=where+1; where = str.IndexOfAny("<>{}".ToCharArray(),where+1,end-where); if (where==0) missingDelimiter('<',start,end); else if (str[where]=='>') { string inusename = str.Substring(strt,where-strt); // now check field name. bool found = false; string rofname; for (int i=0; i0) { MessageBox.Show(parseerror.ToString(),"Error in validating return value"); return false; } else return true; } private bool ValidFieldSpec(string field) { int left = field.IndexOf("<"); int right; int stindx = 0; while (left != -1) { // get right bracket and then check for valid field & if commas with // this, check for integer values. right = field.IndexOf(">",stindx); if (right == -1) { MessageBox.Show("Missing > in Menu value."); return false; } string substring = field.Substring(left+1,right-left-1); // do comma parts now. string inusename; int comma1 = substring.IndexOf(","); if (comma1 != -1) { // get any numbers for formatting & check for ints. int comma2 = substring.IndexOf(",",comma1+1); if (comma2 != -1) // two ints. { if (comma2-comma1 > 1) // first format field - not empty { string int1 = substring.Substring(comma1+1,comma2-comma1-1); try { int l = System.Convert.ToInt32(int1); } catch (Exception e) { MessageBox.Show(e.Message,"invalid format number"); return false; } } if (comma2field.Length) left = -1; else { stindx=right+1; left = field.IndexOf("<",left+1); } } return true; } private bool ProcessRROMenuChange(VlnXmlElement mnuele, string newtmpl) { bool success; XmlNode chldnode = (XmlNode) mnuele.FirstChild; VlnXmlElement echild; while (chldnode != null) { if (chldnode is VlnXmlElement) { echild = (VlnXmlElement) chldnode; if (echild.Name != "vlnGroup") { // If this is a group defintion subtree it will only have one // child, which is the text definition for the subgroup. Don't // include these in the tree. int levelCnt = chldnode.ChildNodes.Count; string TheMenuTitle = echild.GetAttribute("MenuTitle"); if ((levelCnt >= 1) && !TheMenuTitle.Equals("")) { string mnustring = echild.GetMenuString(newtmpl,false); echild.SetAttribute("MenuTitle",mnustring); success = myrodb.RODB_WriteRO(echild); if (success==false) return false; } } } chldnode = chldnode.NextSibling; } return true; } private bool UpdateMenuTitles(VlnXmlElement mnuele, string newtmpl, string stredittype, VlnStatusMessage StatMsgWindow) { // For this group and below in the xml tree, update menu titles using the new // template. bool success; string haskids; string kidsloaded; XmlNode node = (XmlNode) mnuele.FirstChild; VlnXmlElement child; while (node != null) { if (node is VlnXmlElement) { child = (VlnXmlElement) node; // If this is a group menu edit, process group nodes, otherwise // process rros. For both, when hitting a group node, check that // it doesn't have a menu item string redefining the menu template. if (child.Name == "vlnGroup" && child.HasAttribute(stredittype) == false) { haskids = child.GetAttribute("HasChild"); kidsloaded = child.GetAttribute("ChildLoaded"); if (haskids == "True" && kidsloaded == "False" ) { myrodb.RODB_GetChildData(child,true); child.SetAttribute("ChildLoaded","True"); } StatMsgWindow.StatusMessage = child.GetAttribute("MenuTitle"); success = UpdateMenuTitles(child,newtmpl, stredittype, StatMsgWindow); if (success == false) return false; if (editlevel == (uint) RecordType.Schema) { success = ProcessRROMenuChange(mnuele, newtmpl); if (success==false)return false; } else if (editlevel == (uint) RecordType.GroupSchema) { string mnustring = child.GetMenuString(newtmpl,true); child.SetAttribute("MenuTitle",mnustring); success = myrodb.RODB_WriteGroup(child,child); if (success==false) return false; } } } node = node.NextSibling; } // if doing RO menu updates, do all at the current level, otherwise, skip it // because it is a group menu item. if (stredittype == "MenuItem") { success = ProcessRROMenuChange(mnuele, newtmpl); if (success==false) return false; } return true; } private string CvtUserFldToFld(string fldname) { if (fldname.Length < 2) return fldname; // a digit cannot start an xml fieldname, prepend a "__" to it. string tmp0; if (char.IsDigit(fldname,0)) tmp0 = "__" + fldname; else tmp0 = fldname; // an xml fieldname cannot have a space, change it to a "__" string tmpstr = tmp0.Replace(" ","__"); int len = tmpstr.Length; int cnt = 0; // this is also our sequence that tells us the follow 3 digits is the ascii number (base 10) // of the character we replaced. string OKpunch = "-._"; string outstr = ""; int decval; while (cnt < len) { char tmpchr = tmpstr[cnt]; if(!char.IsLetterOrDigit(tmpchr)&& (OKpunch.IndexOf(tmpchr) == -1) ) { decval = tmpchr; outstr += OKpunch + decval.ToString("D3"); } else { outstr += tmpchr.ToString(); } cnt++; } return outstr; } private string CvtFldToUserFld(string fldname) { string tmpstr0; if (fldname.Length < 2) return fldname; // an xml element name cannot begin with a digit. we had prepended a "__" if (fldname.Substring(0,2) == "__" && char.IsDigit(fldname,2)) tmpstr0 = fldname.Substring(2,fldname.Length-2); else tmpstr0 = fldname; // an xml element name cannot have a space, we converted to a "__" string tmpstr = tmpstr0.Replace("__"," "); int len = tmpstr.Length; int cur = 0; // this is also our sequence that tells us the follow 3 digits is the ascii number (base 10) // of the character we replaced. string OKpunch = "-._"; string outstr = ""; int decval, indx; if (tmpstr.Length <6) indx = -1; else indx=tmpstr.IndexOf(OKpunch,cur); string asc_spchar; while (indx>=0) { outstr += tmpstr.Substring(cur,indx-cur); asc_spchar = tmpstr.Substring(indx+3,3); decval = System.Convert.ToInt16(asc_spchar,10); outstr += System.Convert.ToChar(decval).ToString(); cur = indx+6; if (cur+6 > len) indx = -1; else indx = tmpstr.IndexOf(OKpunch,cur); } if (cur= 0) rof = (ROField) InUseList[indx]; else { isInSelList = false; indx = lboxAvail.SelectedIndex; if (indx >= 0) rof = (ROField) AvailList[indx]; else { // message - bad one. return; } } string origname = CvtFldToUserFld(rof.GetFieldname); uint ftype = rof.GetFieldType; if (ftype == (uint)FieldTypes.FrmtSingleTxt || ftype == (uint)FieldTypes.VariableTxt || ftype == (uint)FieldTypes.SingleTxt || ftype == (uint)FieldTypes.Table || ftype == (uint)FieldTypes.XYPlot || ftype == (uint)FieldTypes.Image) { FieldTypeDefFrm nwtyp = new FieldTypeDefFrm(rof, myrodb, elem, editlevel, AvailList, InUseList); nwtyp.ShowDialog(); } else { FieldCombFrm nwcomb = new FieldCombFrm(rof, myrodb, elem, editlevel, rof.GetFieldname, AvailList, InUseList); nwcomb.ShowDialog(); } //need to refresh pull from table for fields in use. _ = myrodb.RODB_GetFields(elem, 0, true); string newname = CvtFldToUserFld(rof.GetFieldname); // Update Lists & Text boxes to represent any modified text. if (isInSelList) { 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) { string fieldname = CvtFldToUserFld(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(fieldname); if (rof.FieldTypeCanDoApplicability()) { if (ContainedInUseApplicList(rof)) this.lboxInUseCB.SetItemCheckState(lboxInUseCB.Items.IndexOf(fieldname), CheckState.Checked); } } else this.lboxInUse.Items.Add(fieldname); } } if (origname != newname) { tbMenuVal.Text = tbMenuVal.Text.Replace($"<{origname}>", $"<{newname}>"); tbRetVal.Text = tbRetVal.Text.Replace($"<{origname}>", $"<{newname}>"); //CSM-C2024-035 This is needed for items like Setpoint Value that may have commas with field lengths in them tbMenuVal.Text = tbMenuVal.Text.Replace($"<{origname},", $"<{newname},"); tbRetVal.Text = tbRetVal.Text.Replace($"<{origname},", $"<{newname},"); } } else { lboxAvail.Items.Clear(); // add items to the AvailList box. for (int i=0; i< AvailList.Count; i++) { rof = (ROField) AvailList[i]; if (rof.GetFieldname != null) this.lboxAvail.Items.Add(CvtFldToUserFld(rof.GetFieldname)); } } } private void btnNew_Click(object sender, System.EventArgs e) { ROField rof = new ROField(null,null,null,0); FieldTypeDefFrm nwtyp = new FieldTypeDefFrm(rof, myrodb, elem, editlevel, AvailList, InUseList); nwtyp.ShowDialog(); if (rof.GetFieldname != null) { AvailList.Add(rof); lboxAvail.Items.Add(CvtFldToUserFld(rof.GetFieldname)); } //need to refresh pull from table for fields in use. _ = myrodb.RODB_GetFields(elem, 0, true); } // 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 /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.lblGroup = new System.Windows.Forms.Label(); this.lblRetVal = new System.Windows.Forms.Label(); this.lblMenuVal = new System.Windows.Forms.Label(); this.tbRetVal = new System.Windows.Forms.TextBox(); 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(); this.btnCancel = new System.Windows.Forms.Button(); this.gbFields.SuspendLayout(); this.SuspendLayout(); // // lblGroup // this.lblGroup.Location = new System.Drawing.Point(24, 0); this.lblGroup.Name = "lblGroup"; this.lblGroup.Size = new System.Drawing.Size(88, 16); this.lblGroup.TabIndex = 0; this.lblGroup.Text = "Group:"; this.lblGroup.TextAlign = System.Drawing.ContentAlignment.TopRight; // // lblRetVal // this.lblRetVal.Location = new System.Drawing.Point(16, 32); this.lblRetVal.Name = "lblRetVal"; this.lblRetVal.Size = new System.Drawing.Size(96, 16); this.lblRetVal.TabIndex = 1; this.lblRetVal.Text = "Return Value:"; this.lblRetVal.TextAlign = System.Drawing.ContentAlignment.TopRight; // // lblMenuVal // this.lblMenuVal.Location = new System.Drawing.Point(16, 64); this.lblMenuVal.Name = "lblMenuVal"; this.lblMenuVal.Size = new System.Drawing.Size(96, 16); this.lblMenuVal.TabIndex = 2; this.lblMenuVal.Text = "Menu Value:"; this.lblMenuVal.TextAlign = System.Drawing.ContentAlignment.TopRight; // // tbRetVal // this.tbRetVal.Location = new System.Drawing.Point(120, 32); this.tbRetVal.Name = "tbRetVal"; this.tbRetVal.Size = new System.Drawing.Size(464, 22); this.tbRetVal.TabIndex = 4; this.tbRetVal.Text = "textBox1"; // // tbMenuVal // this.tbMenuVal.Location = new System.Drawing.Point(120, 64); this.tbMenuVal.Name = "tbMenuVal"; this.tbMenuVal.Size = new System.Drawing.Size(464, 22); this.tbMenuVal.TabIndex = 5; this.tbMenuVal.Text = "textBox1"; // // lblGroupText // this.lblGroupText.Location = new System.Drawing.Point(120, 0); this.lblGroupText.Name = "lblGroupText"; this.lblGroupText.Size = new System.Drawing.Size(464, 16); this.lblGroupText.TabIndex = 7; this.lblGroupText.Text = "label1"; // // gbFields // 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, 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); this.btnNew.Name = "btnNew"; this.btnNew.Size = new System.Drawing.Size(80, 24); this.btnNew.TabIndex = 7; this.btnNew.Text = "New..."; this.btnNew.Click += new System.EventHandler(this.btnNew_Click); // // btnRemove // this.btnRemove.Enabled = false; this.btnRemove.Location = new System.Drawing.Point(272, 144); this.btnRemove.Name = "btnRemove"; this.btnRemove.Size = new System.Drawing.Size(80, 24); this.btnRemove.TabIndex = 6; this.btnRemove.Text = "Remove>>"; this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); // // btnEdit // this.btnEdit.Enabled = false; this.btnEdit.Location = new System.Drawing.Point(272, 96); this.btnEdit.Name = "btnEdit"; this.btnEdit.Size = new System.Drawing.Size(80, 24); this.btnEdit.TabIndex = 5; this.btnEdit.Text = "Edit..."; this.btnEdit.Click += new System.EventHandler(this.btnEdit_Click); // // btnAdd // this.btnAdd.Enabled = false; this.btnAdd.Location = new System.Drawing.Point(272, 48); this.btnAdd.Name = "btnAdd"; this.btnAdd.Size = new System.Drawing.Size(80, 24); this.btnAdd.TabIndex = 4; this.btnAdd.Text = "<< Add"; this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); // // lboxAvail // 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, 172); this.lboxAvail.TabIndex = 3; // // lboxInUse // this.lboxInUse.ItemHeight = 14; this.lboxInUse.Location = new System.Drawing.Point(27, 48); this.lboxInUse.Name = "lboxInUse"; 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); this.lblAvail.Name = "lblAvail"; this.lblAvail.Size = new System.Drawing.Size(80, 16); this.lblAvail.TabIndex = 1; this.lblAvail.Text = "Available:"; // // lblInUse // this.lblInUse.Location = new System.Drawing.Point(24, 24); this.lblInUse.Name = "lblInUse"; this.lblInUse.Size = new System.Drawing.Size(64, 16); this.lblInUse.TabIndex = 0; this.lblInUse.Text = "In Use:"; // // btnOK // this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.btnOK.Location = new System.Drawing.Point(512, 376); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(88, 24); this.btnOK.TabIndex = 9; this.btnOK.Text = "OK"; this.btnOK.Click += new System.EventHandler(this.btnOK_Click); // // btnCancel // this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Location = new System.Drawing.Point(616, 376); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(80, 24); this.btnCancel.TabIndex = 10; this.btnCancel.Text = "Cancel"; // // RODefFrm // this.AutoScaleBaseSize = new System.Drawing.Size(6, 15); this.ClientSize = new System.Drawing.Size(792, 437); 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(); } //if User clicked save (DialogResult.OK) close the form //if use did not click save, ask if they are sure they want to close the form //only close if they say "Yes, they want to" protected override void OnFormClosing(FormClosingEventArgs e) { if (this.DialogResult != System.Windows.Forms.DialogResult.OK && IsPendingChange() && !CloseCancel()) { e.Cancel = true; } } public static bool CloseCancel() { const string message = "Are you sure that you would like to cancel? Information may not be saved."; const string caption = "Cancel"; var result = MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question); return result == DialogResult.Yes; } //return true if a field has been modified private bool IsPendingChange() { if (origRetVal != this.tbRetVal.Text) return true; if (origMenuItem != this.tbMenuVal.Text) return true; // check if in use records have changed string inuserecs = null; ROField rof; for (int i = 0; i < InUseList.Count; i++) { rof = (ROField)InUseList[i]; if (rof.GetFieldname != null) //DO YET: why null? { inuserecs = inuserecs + rof.GetRecID; if (i + 1 < InUseList.Count) inuserecs = inuserecs + " "; } } if (inuserecs != origFieldsInUse) return true; //check if applicability fields have changed 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 + " "; } } if (applicfieldrecs != origApplicFields) return true; //nothing has changed return false; } #endregion } }