1348 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1348 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| /*********************************************************************************************
 | |
|  * Copyright 2021 - Volian Enterprises, Inc. All rights reserved.
 | |
|  * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
 | |
|  * ------------------------------------------------------------------------------
 | |
|  * $Workfile: VlnXml.cs $     $Revision: 23 $
 | |
|  * $Author: Jsj $   $Date: 6/20/05 1:29p $
 | |
|  *
 | |
|  * $History: VlnXml.cs $
 | |
|  * 
 | |
|  * *****************  Version 23  *****************
 | |
|  * User: Jsj          Date: 6/20/05    Time: 1:29p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * added status message while reading ROs for Complete RO Report.
 | |
|  * 
 | |
|  * *****************  Version 22  *****************
 | |
|  * User: Jsj          Date: 6/08/05    Time: 4:32p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * Complete RO Report Bug fix  B2001-001
 | |
|  * 
 | |
|  * *****************  Version 21  *****************
 | |
|  * User: Jsj          Date: 9/27/04    Time: 11:02a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * upped release number
 | |
|  * 
 | |
|  * *****************  Version 20  *****************
 | |
|  * User: Kathy        Date: 7/15/04    Time: 11:11a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * Fix B2004-017
 | |
|  * 
 | |
|  * *****************  Version 19  *****************
 | |
|  * User: Kathy        Date: 5/06/04    Time: 9:52a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * B2004-012 fix: skip process of param display data for RO Cmp Rpt
 | |
|  * 
 | |
|  * *****************  Version 18  *****************
 | |
|  * User: Jsj          Date: 4/08/04    Time: 9:43a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * Added and commented out calls to VlnProfiler
 | |
|  * 
 | |
|  * *****************  Version 17  *****************
 | |
|  * User: Jsj          Date: 1/21/04    Time: 12:10p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * added function to return current selected field type of multi type
 | |
|  * field
 | |
|  * 
 | |
|  * *****************  Version 16  *****************
 | |
|  * User: Kathy        Date: 5/21/03    Time: 12:41p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * B2003-035: process ro's with just one field
 | |
|  * 
 | |
|  * *****************  Version 15  *****************
 | |
|  * User: Jsj          Date: 4/14/03    Time: 2:59p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * changes resulting from speeding up RO FST creation
 | |
|  * 
 | |
|  * *****************  Version 14  *****************
 | |
|  * User: Kathy        Date: 3/11/03    Time: 11:24a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * allow extra text on accpageid template
 | |
|  * 
 | |
|  * *****************  Version 13  *****************
 | |
|  * User: Kathy        Date: 12/17/02   Time: 12:53p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * get image data by node for rofst creation
 | |
|  * 
 | |
|  * *****************  Version 12  *****************
 | |
|  * User: Kathy        Date: 12/10/02   Time: 2:25p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * fieldname special chars & various bugs
 | |
|  * 
 | |
|  * *****************  Version 11  *****************
 | |
|  * User: Kathy        Date: 12/02/02   Time: 8:29a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * fieldname replace chars
 | |
|  * 
 | |
|  * *****************  Version 10  *****************
 | |
|  * User: Jsj          Date: 11/27/02   Time: 12:47p
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * modifications for RO.FST file creation
 | |
|  * 
 | |
|  * *****************  Version 9  *****************
 | |
|  * User: Kathy        Date: 11/19/02   Time: 11:32a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * fields within {} are not required
 | |
|  * 
 | |
|  * *****************  Version 8  *****************
 | |
|  * User: Kathy        Date: 11/11/02   Time: 7:14a
 | |
|  * Updated in $/LibSource/RODBInterface
 | |
|  * Added complete report methods.
 | |
|  *********************************************************************************************/
 | |
| using System;
 | |
| using System.Xml;
 | |
| using System.Text;
 | |
| using System.Collections;
 | |
| using System.IO;
 | |
| using System.Windows.Forms;
 | |
| using ROFields;
 | |
| using VlnStatus;
 | |
| //using VlnProfiler; //don't forget to add VlnProfiler to the reference list
 | |
| 
 | |
| namespace RODBInterface
 | |
| {
 | |
| 	/// <summary>
 | |
| 	/// Summary description for Class1.
 | |
| 	/// </summary>
 | |
|  
 | |
| 	public class VlnXmlDocument:XmlDocument 
 | |
| 	{
 | |
| 		FileStream Rptfs;		// for complete report of this document
 | |
| 		BinaryWriter RptBW;
 | |
| 		
 | |
| 		public VlnXmlDocument():base() 
 | |
| 		{
 | |
| 		}
 | |
| 
 | |
| 		public override XmlElement CreateElement( string prefix, string localname, string nsURI) 
 | |
| 		{
 | |
| 			VlnXmlElement elem = new VlnXmlElement(prefix, localname, nsURI, this);
 | |
| 			return elem;
 | |
| 		}
 | |
| 
 | |
| 		public bool OpenTemp()
 | |
| 		{
 | |
| 			try
 | |
| 			{
 | |
| 				//Rptfs = new FileStream("print.tmp", FileMode.Create);
 | |
| 				Rptfs = new FileStream("print.tmp", FileMode.Append);
 | |
| 				// Create the writer for data.
 | |
| 				RptBW = new BinaryWriter(Rptfs);
 | |
| 			}
 | |
| 			catch (Exception ex) 
 | |
| 			{
 | |
| 				Console.WriteLine("Open Print.Tmp: {0}", ex.Message);
 | |
| 				return false;
 | |
| 			}
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		public void CloseTemp()
 | |
| 		{
 | |
| 			RptBW.Close();
 | |
| 			Rptfs.Close();
 | |
| 		}
 | |
| 
 | |
| 		public void writeInt(short val)
 | |
| 		{
 | |
| 			RptBW.Write(val);
 | |
| 		}
 | |
| 
 | |
| 		public void writeText(string str)
 | |
| 		{
 | |
| 			short n = (short) str.Length;
 | |
| 			writeInt(n);
 | |
| 			// write out char by char. (Using rite
 | |
| 			// of entire stirng caused special characters to be
 | |
| 			// written as two bytes - which temp file reading code
 | |
| 			int i;
 | |
| 			for(i =0; i < str.Length; i++)
 | |
| 			{
 | |
| 				byte WrByte;
 | |
| 				WrByte = (byte)str[i];
 | |
| 				RptBW.Write(WrByte);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public void writeTextValue(string str)
 | |
| 		{
 | |
| 			writeInt(100);
 | |
| 			writeText(str);
 | |
| 		}
 | |
| 
 | |
| 		public void writePlot(string str)
 | |
| 		{
 | |
| 			writeInt(101);
 | |
| 			writeText(str);
 | |
| 		}
 | |
| 
 | |
| 		public void writeImage(string str)
 | |
| 		{
 | |
| 			writeInt(102);
 | |
| 			writeText(str);
 | |
| 		}
 | |
| 
 | |
| 		public void pushHeader(string str)
 | |
| 		{
 | |
| 			writeInt(2);
 | |
| 			writeText(str);
 | |
| 		}
 | |
| 
 | |
| 		public void popHeader()
 | |
| 		{
 | |
| 			writeInt(3);
 | |
| 		}
 | |
| 
 | |
| 		public void doHeader(ArrayList headers)
 | |
| 		{
 | |
| 			int spaces = -1;
 | |
| 			short cnt = (short) headers.Count;
 | |
| 			writeInt(255);
 | |
| 			writeInt(1);
 | |
| 			writeInt(cnt);
 | |
| 			for (int i=0; i < cnt ;i++)
 | |
| 			{
 | |
| 				writeInt(0);
 | |
| 				if (spaces>0)
 | |
| 				{
 | |
| 					string spc = new String(' ',2*(spaces-1));
 | |
| 					writeText(spc+headers[i].ToString());
 | |
| 				}
 | |
| 				else
 | |
| 				writeText(headers[i].ToString());
 | |
| 				spaces++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public void writeRROBegin()
 | |
| 		{
 | |
| 			writeInt(4);
 | |
| 		}
 | |
| 
 | |
| 		public void writeRROEnd()
 | |
| 		{
 | |
| 			writeInt(5);
 | |
| 		}
 | |
| 	
 | |
| 		public void writeMultiBegin()
 | |
| 		{
 | |
| 			writeInt(103);
 | |
| 		}
 | |
| 
 | |
| 		public void writeMultiEnd()
 | |
| 		{
 | |
| 			writeInt(104);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public class VlnXmlElement:XmlElement 
 | |
| 	{
 | |
| 		public VlnXmlElement( string prefix, string localname, string nsURI, XmlDocument doc ):base( prefix,localname,nsURI, doc )
 | |
| 		{
 | |
| 		}
 | |
| 		private string _MyROID;
 | |
| 		public string MyROID
 | |
| 		{
 | |
| 			get { return _MyROID; }
 | |
| 			set { _MyROID = value; }
 | |
| 		}
 | |
| 		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<len) outstr += tmpstr.Substring(cur,len-cur);	
 | |
| 
 | |
| 			return outstr;
 | |
| 		}
 | |
| 
 | |
| 		// for this (VlnXmlElement), get it's accessory page id based on it's data, using
 | |
| 		// the passed in template (AccPageID template from the xmlelement's attributes).
 | |
| 		// Note that the template represents only 1 field. This was a req/design decision 
 | |
| 		// made during the development based on engineering review.
 | |
| 		public string GetAccPageIDString(string newtmpl)
 | |
| 		{
 | |
| 			string fld;
 | |
| 			// If there aren't properties definied for the group/subgroup - give a message
 | |
| 			// rather than crash (B2004-017)
 | |
| 			if (newtmpl==null)
 | |
| 			{
 | |
| 				MessageBox.Show("Missing Accessory Page Information, check Group definition on Properties.");
 | |
| 				return null;
 | |
| 			}
 | |
| 			VlnXmlElement elm = this;
 | |
| 			int left = newtmpl.IndexOf("<");
 | |
| 			int right= newtmpl.IndexOf(">");
 | |
| 			if (left >= 0 && right > 0) 
 | |
| 				fld = newtmpl.Substring(left+1,right-left-1);
 | |
| 			else
 | |
| 				return null;
 | |
| 			string usefld = CvtUserFldToFld(fld);
 | |
| 			
 | |
| 			XmlNode elmnode = (XmlNode) elm;
 | |
| 			XmlNode nd = elmnode.SelectSingleNode(usefld);
 | |
| 			// if not found it may be a combination, try this.
 | |
| 			if (nd == null)
 | |
| 			{
 | |
| 				string tmp = usefld + "a";
 | |
| 				nd = elmnode.SelectSingleNode(tmp);
 | |
| 			}
 | |
| 			if (nd == null)
 | |
| 			{
 | |
| 				string tmp = usefld + "b";
 | |
| 				nd = elmnode.SelectSingleNode(tmp);
 | |
| 			}
 | |
| 			if (nd == null)
 | |
| 			{
 | |
| 				string tmp = usefld + "c";
 | |
| 				nd = elmnode.SelectSingleNode(tmp);
 | |
| 			}
 | |
| 			if (nd == null)
 | |
| 			{
 | |
| 				string tmp = usefld + "d";
 | |
| 				nd = elmnode.SelectSingleNode(tmp);
 | |
| 			}
 | |
| 			if(nd != null)
 | |
| 			{
 | |
| 				StringBuilder strbld = new StringBuilder();
 | |
| 				if (left > 0) strbld.Append(newtmpl.Substring(0,left));
 | |
| 				strbld.Append(nd.InnerText.ToString());
 | |
| 				if (right+1<newtmpl.Length)
 | |
| 					strbld.Append(newtmpl.Substring(right+1,newtmpl.Length-right-1));
 | |
| 				return strbld.ToString();
 | |
| 			}
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		// for this (VlnXmlElement), get the accessorypageid template by walking up
 | |
| 		// the tree, starting at this element.
 | |
| 		public string GetAccPageIDTemplate()
 | |
| 		{
 | |
| 			VlnXmlElement parent;
 | |
| 			VlnXmlElement tmp=null;
 | |
| 			
 | |
| 			// get to top node of the ROs & groups to get the accpageID for this tree.
 | |
| 			parent = (VlnXmlElement) this;
 | |
| 			while(parent.Name != "RO_Root")
 | |
| 			{
 | |
| 				tmp = parent;
 | |
| 				parent = (VlnXmlElement) parent.ParentNode;
 | |
| 			}
 | |
| 			if (tmp.HasAttribute("AccPageID") == false) return null;
 | |
| 			else return tmp.GetAttribute("AccPageID");
 | |
| 		}
 | |
| 
 | |
| 		// check to see if the input string makes a duplicate menu title.
 | |
| 		public bool IsDuplicateMenuTitle(string menutitle)
 | |
| 		{
 | |
| 			// see if this is a duplicate menu, just check ROs at this level except
 | |
| 			// myself.
 | |
| 			XmlNode parent = this.ParentNode;
 | |
| 			XmlNode chld = parent.FirstChild;
 | |
| 			while (chld != null)
 | |
| 			{
 | |
| 				if (chld is VlnXmlElement)
 | |
| 				{
 | |
| 					VlnXmlElement echld = (VlnXmlElement) chld;
 | |
| 					if (this != echld)
 | |
| 					{
 | |
| 						string chldmenutitle = echld.GetAttribute("MenuTitle");
 | |
| 						if (chldmenutitle != null && chldmenutitle == menutitle)return true;
 | |
| 					}
 | |
| 				}
 | |
| 				chld = chld.NextSibling;
 | |
| 			}
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// for this (VlnXmlElement), get the menu title string. Passed in, menuitm, is the
 | |
| 		// template which is used to generate the menu title for this XmlElement. Also
 | |
| 		// passed in is a flag to state whether this is a 'Group' menu title.
 | |
| 		public string GetMenuString(string menuitm, bool isgrp)
 | |
| 		{
 | |
| 			VlnXmlElement elm = this;
 | |
| 			StringBuilder strbld = new StringBuilder();
 | |
| 
 | |
| 			// use grpmenuitm, parse for field(s) and generate a string to return
 | |
| 			int left = menuitm.IndexOf("<");
 | |
| 			int right=0;
 | |
| 			int stindx = 0;
 | |
| 			if (left > 0) strbld.Append(menuitm.Substring(0,left));
 | |
| 	
 | |
| 			while (left != -1)
 | |
| 			{
 | |
| 				// get right bracket and then check for valid field & if commas with
 | |
| 				// this, check for integer values.
 | |
| 				right = menuitm.IndexOf(">",stindx);
 | |
| 				string tmpd = menuitm.Substring(left+1,right-left-1);
 | |
| 				// do comma parts now.
 | |
| 				string inusename;
 | |
| 				int comma1 = tmpd.IndexOf(",");
 | |
| 				int frmt1=0, frmt2=0;
 | |
| 				if (comma1 != -1)
 | |
| 				{
 | |
| 					// get any numbers for formatting & check for ints.
 | |
| 					int comma2 = tmpd.IndexOf(",",comma1+1);
 | |
| 					if (comma2 != -1) // two ints.
 | |
| 					{
 | |
| 						if (comma2-comma1 > 1) // first format field - not empty 
 | |
| 						{
 | |
| 							string int1 = tmpd.Substring(comma1+1,comma2-comma1-1);
 | |
| 							frmt1 = System.Convert.ToInt32(int1);
 | |
| 						}
 | |
| 						if (comma2<tmpd.Length)  // second part - not empty
 | |
| 						{
 | |
| 							string int2 = tmpd.Substring(comma2+1,tmpd.Length-comma2-1);
 | |
| 							frmt2 = System.Convert.ToInt32(int2);
 | |
| 						}
 | |
| 					}
 | |
| 					else  // just one format 
 | |
| 					{
 | |
| 						string int1 = tmpd.Substring(comma1,comma2-comma1);
 | |
| 						frmt1 = System.Convert.ToInt32(int1);
 | |
| 					}
 | |
| 					inusename = CvtUserFldToFld(tmpd.Substring(0,comma1));
 | |
| 				}
 | |
| 				else  // no commas, it's just a field name.
 | |
| 					inusename = CvtUserFldToFld(tmpd);
 | |
| 
 | |
| 				// get contents of field & append it onto the string builder.
 | |
| 				XmlNode elmnode = (XmlNode) elm;
 | |
| 				XmlNode nd = elmnode.SelectSingleNode(inusename);
 | |
| 				// if not found it may be a combination, try this.
 | |
| 				ushort FieldType = 0;
 | |
| 				string text;
 | |
| 				if (nd == null)
 | |
| 					text = GetComboFieldValueAndType(elmnode,inusename,ref FieldType,true);
 | |
| 				else
 | |
| 					text = nd.InnerText;
 | |
| 				if (!text.Equals(""))
 | |
| 				{
 | |
| 					if (isgrp)
 | |
| 					{
 | |
| 						if (frmt2 != 0)
 | |
| 							strbld.Append(CvtFldToUserFld(text).PadRight(frmt2,' '));
 | |
| 						else
 | |
| 							strbld.Append(CvtFldToUserFld(text));
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						if (frmt1 == 0)
 | |
| 						{
 | |
| 							if (frmt2>0)
 | |
| 								strbld.Append(text.PadRight(frmt2,' '));
 | |
| 							else
 | |
| 								strbld.Append(text);
 | |
| 						}
 | |
| 						else if (frmt1 != frmt2)
 | |
| 						{
 | |
| 							int cnt = 0;
 | |
| //							while (cnt < tmp.Length && tmp[cnt] <= '9' && tmp[cnt] >= '0') cnt++; // new RO logic
 | |
| //							int padcnt = (cnt>frmt1)?0:frmt1-cnt;
 | |
| 							int padcnt = OldROFSTMenuLogic(text,frmt1,frmt2); // testing!!!!!
 | |
| 							StringBuilder strtmp = new StringBuilder();
 | |
| 							cnt = 0;
 | |
| 							while(cnt<padcnt) 
 | |
| 							{
 | |
| 								strtmp.Append(" ");
 | |
| 								cnt++;
 | |
| 							}
 | |
| 							if ((cnt + text.Length) > frmt2) // longer than the field length?
 | |
| 								strtmp.Append(text.Substring(0,frmt2-cnt));
 | |
| 							else
 | |
| 								strtmp.Append(text);
 | |
| 							string tmpstr = strtmp.ToString();
 | |
| 							strbld.Append(tmpstr.PadRight(frmt2,' '));
 | |
| 						}
 | |
| 						else
 | |
| 							strbld.Append(text.PadLeft(frmt2,' '));
 | |
| 					}
 | |
| 				}
 | |
| 				stindx = right+1;
 | |
| 				left = menuitm.IndexOf("<",left+1);
 | |
| 				if (left != -1 && left > right+1)  // append any plain text.
 | |
| 					strbld.Append(menuitm.Substring(right+1,left-right-1));
 | |
| 			}
 | |
| 			if (right+1<menuitm.Length)
 | |
| 				strbld.Append(menuitm.Substring(right+1,menuitm.Length-right-1));
 | |
| 			return strbld.ToString();
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		int OldROFSTMenuLogic(string text,int doff, int wid)
 | |
| 		{
 | |
| 			int siznum = 0;
 | |
| 			int idx =0;
 | |
| 			int sps = 0;
 | |
| 			int newoff = doff;
 | |
| 			int tmpwid;
 | |
| 			char[] str = text.ToCharArray();
 | |
| 			// skip leading blanks
 | |
| 			while (idx < text.Length && str[idx] == ' ') idx++;
 | |
| 			int slen = text.Length - idx;
 | |
| 			while (idx < text.Length && ((str[idx]<='9' && str[idx]>='0') || str[idx] =='-' || str[idx]=='+'))
 | |
| 			{
 | |
| 				siznum++;
 | |
| 				idx++;
 | |
| 			}
 | |
| 			if (siznum == 0)
 | |
| 			{
 | |
| 				newoff= siznum+(wid-slen)/2;
 | |
| 			} 
 | |
| 			else if (((doff-siznum)+slen)> wid)
 | |
| 			{
 | |
| 				newoff = wid-siznum-slen;
 | |
| 			}
 | |
| 			tmpwid = wid;
 | |
| 			while (tmpwid > 0 && siznum < newoff)
 | |
| 			{
 | |
| 				sps++;
 | |
| 				siznum++;
 | |
| 				tmpwid--;
 | |
| 			}
 | |
| 			return sps;
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		// for this (VlnXmlElement), get it's menu value template. This template is
 | |
| 		// used to generate the menu titles. Pass in a string 'GroupMenuItem' or
 | |
| 		// 'MenuItem' so that the group level or RRO level menu template is found.
 | |
| 		// This walkds up the tree to find the attribute ('GroupMenuItem' or 'MenuItem')
 | |
| 		// and returns it.
 | |
| 		public string GetMenuValueTemplate(string menuitm)
 | |
| 		{
 | |
| 			VlnXmlElement parent;
 | |
| 			string strmenuitm;
 | |
| 			VlnXmlElement tmp;
 | |
| 			if (menuitm == "GroupMenuItem")
 | |
| 			{		
 | |
| 				// if at top of tree, use this top GroupMenuItem. but if not,
 | |
| 				// the parent node defines the GroupMenuItem for the subgroups.
 | |
| 				if (this.ParentNode.Name == "RO_Root")
 | |
| 				{
 | |
| 					tmp = (VlnXmlElement) this.ParentNode;
 | |
| 					strmenuitm=tmp.GetAttribute(menuitm);
 | |
| 					return(strmenuitm);
 | |
| 				}
 | |
| 				else
 | |
| 					parent = (VlnXmlElement) this.ParentNode;
 | |
| 				while (parent != null) 
 | |
| 				{
 | |
| 					if (parent.HasAttribute(menuitm) == true) break;
 | |
| 					if (parent.Name != "RO_Root")
 | |
| 						parent = (VlnXmlElement) parent.ParentNode;
 | |
| 					else
 | |
| 						parent = null;
 | |
| 				}
 | |
| 				if (parent == null) return null;
 | |
| 				strmenuitm = parent.GetAttribute(menuitm);
 | |
| 				return strmenuitm;
 | |
| 			}
 | |
| 
 | |
| 			// Now just do 'MenuItem', which is for ROs
 | |
| 			parent = (VlnXmlElement) this;
 | |
| 			strmenuitm = parent.GetAttribute(menuitm);
 | |
| 			while (parent != null && strmenuitm == "")
 | |
| 			{
 | |
| 				// walk up tree to get parent.
 | |
| 				strmenuitm = parent.GetAttribute(menuitm);
 | |
| 				parent = (VlnXmlElement) parent.ParentNode;
 | |
| 			}
 | |
| 			return strmenuitm;
 | |
| 		}
 | |
| 
 | |
| 		// for this (VlnXmlElement), get the Return Value template.
 | |
| 		public string GetReturnValueTemplate()
 | |
| 		{
 | |
| 			VlnXmlElement parent;
 | |
| 			VlnXmlElement tmp=null;
 | |
| 			
 | |
| 			// get to top node of the ROs & groups to get the return for this tree.
 | |
| 			parent = (VlnXmlElement) this;
 | |
| 			tmp = parent;
 | |
| 			while((tmp.HasAttribute("RetVal") == false) && parent.Name != "RO_Root")
 | |
| 			{
 | |
| 				tmp = parent;
 | |
| 				parent = (VlnXmlElement) parent.ParentNode;
 | |
| 			}
 | |
| 			if (tmp.HasAttribute("RetVal") == false) return null;
 | |
| 			else return tmp.GetAttribute("RetVal");
 | |
| 		}
 | |
| 
 | |
| 		/*
 | |
| 		 * return true if the field is a pre defined PROC.INI field name
 | |
| 		 */
 | |
| 		private bool IsProcIniDef(string fld)
 | |
| 		{
 | |
| 			bool rtnval = false;
 | |
| 			string tmpstr = fld.ToUpper();
 | |
| 
 | |
| 			rtnval = (tmpstr.Equals("U") || 
 | |
| 						tmpstr.Equals("U-") ||
 | |
| 						tmpstr.Equals("P") || 
 | |
| 						tmpstr.Equals("P-") ||
 | |
| 						tmpstr.Equals("S") ||
 | |
| 						tmpstr.Equals("S-"));
 | |
| 
 | |
| 			return rtnval;
 | |
| 		}
 | |
| 
 | |
| 		/*
 | |
| 		 * This function checks the given field name with the list of fields
 | |
| 		 * that are "in use" for the current group.
 | |
| 		 * If the field name is of one of the pre-defined PROC.INI RO fields
 | |
| 		 * treat that field name as plain text (i.e. NOT in use)
 | |
| 		 */
 | |
| 		private bool IsAInUseField(ArrayList InUseList, string fld)
 | |
| 		{
 | |
| 			bool rtnval = false;
 | |
| 			int i;
 | |
| 
 | |
| 			if (IsProcIniDef(fld)) // is this a pre-defined PROC.INI field?
 | |
| 				return rtnval; //return false!
 | |
| 
 | |
| 			string tmpstr = fld.Substring(0,1);
 | |
| 			if (tmpstr.Equals("_"))
 | |
| 				tmpstr = fld.Substring(1,fld.Length-1);
 | |
| 			else
 | |
| 				tmpstr = fld;
 | |
| 			tmpstr = CvtFldToUserFld(fld);
 | |
| 			for(i=0; rtnval == false && i<InUseList.Count; i++)
 | |
| 			{
 | |
| 				ROField rof = (ROField) InUseList[i];
 | |
| 				string fldname = rof.GetFieldname;
 | |
| 				if (fldname.Equals(tmpstr))
 | |
| 				{
 | |
| 					rtnval = true; // found
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			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 = "";
 | |
| 
 | |
| 				if (nd == null)
 | |
| 				{
 | |
| 					XmlNode radNode = elmnode.FirstChild;
 | |
| 					string radNodeName = radNode.Name;
 | |
| 					//B2021-146 added a null reference check of the next sibling
 | |
| 					while (radNode != null && radNode.NextSibling != null && !radNodeName.StartsWith(inusename))
 | |
| 					{
 | |
| 						radNode = radNode.NextSibling;
 | |
| 						radNodeName = radNode.Name;
 | |
| 					}
 | |
| 					parentValue = radNode.InnerText;
 | |
| 					parentName = radNodeName;
 | |
| 				}
 | |
| 				else
 | |
| 					parentValue = nd.InnerText;
 | |
| 
 | |
| 				if (parentName != "#whitespace")
 | |
| 				{
 | |
| 					//applicValues = "";
 | |
| 					applicValues = string.Format("<APL DefaultVal={0}", parentValue);
 | |
| 					int pcChildIdx = 0;
 | |
| 					//C2022-001 only save the child ro value in the RO.FST if it is different than the parent (default) value
 | |
| 
 | |
| 					foreach (string c in pcChildern)
 | |
| 					{
 | |
| 						//string csufx = CvtUserFldToFld(c);
 | |
| 						pcChildIdx++;
 | |
| 						string csufx = string.Format("_PCCHILD{0}", pcChildIdx);
 | |
| 						//applicValues += ",";
 | |
| 						XmlNode cn = elmnode.SelectSingleNode(parentName + csufx);
 | |
| 						if (cn == null || cn.InnerText.Length == 0) // B2024-004 use Parent value if Child text length is zero
 | |
| 							applicValues += string.Format(",UnitIdx={0} Value={1}", pcChildIdx, parentValue); // use parent value as default
 | |
| 						else
 | |
| 						{
 | |
| 							if (parentValue != cn.InnerText)
 | |
| 								applicValues += string.Format(",UnitIdx={0} Value={1}", pcChildIdx, cn.InnerText);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				applicValues += " /APL>";
 | |
| 			}
 | |
| 			return applicValues;
 | |
| 		}
 | |
| 
 | |
| 		public string GetReturnValue(RODB theDb, string TableName, string RtnValTemplate, ArrayList InUseList, ref ushort ValueType, string[] pcChildern)
 | |
| 		{
 | |
| 			string RtnValStr = "";
 | |
| 			VlnXmlElement elm = this;
 | |
| 			StringBuilder strbld = new StringBuilder();
 | |
| 			bool PCApplicability = (pcChildern != null && pcChildern.Length > 0);
 | |
| 
 | |
| 			// Parse the template for the fields and generate a return string
 | |
| 			int left = RtnValTemplate.IndexOf("<"); // look for begining of field
 | |
| 			int right = -1;
 | |
| 			int stindx = 0;
 | |
| 			ushort FldType = 0;
 | |
| 
 | |
| 			if (left > 0) strbld.Append(RtnValTemplate.Substring(0,left));
 | |
| 
 | |
| 			while (left != -1)
 | |
| 			{
 | |
| 				// get right bracket and then check for valid field & if commas with
 | |
| 				// this, check for integer values.
 | |
| 				right = RtnValTemplate.IndexOf(">",stindx);
 | |
| 				string inusename;
 | |
| 				string substr = RtnValTemplate.Substring(left+1,right-left-1);
 | |
| 				inusename = CvtUserFldToFld(substr);
 | |
| 
 | |
| 				// get contents of field & append it onto the string builder.
 | |
| 				XmlNode elmnode = (XmlNode) elm;
 | |
| 				XmlNode nd = elmnode.SelectSingleNode(inusename);
 | |
| 				// Check to see if the found field is a "Field In Use"
 | |
| 
 | |
| 				if (IsAInUseField(InUseList,inusename))
 | |
| 				{
 | |
| 					string text="";
 | |
| 					if (nd == null)
 | |
| 					{
 | |
| 						text = GetComboFieldValueAndType(elmnode,inusename,ref FldType,false);
 | |
| 						if (text.Equals(""))
 | |
| 							text = " ";
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| //						Profiler.Start("Grv7");
 | |
| 						FldType = theDb.RODB_GetFieldType((VlnXmlElement)nd,TableName,inusename);
 | |
| //						Profiler.End("Grv7");
 | |
| //						Profiler.Start("Grv8");
 | |
| 						// for an image, get the filename, height, width, otherwise just use
 | |
| 						// data in the node.
 | |
| 						if (FldType == 8) // for the '8' see RODBInterface - GetFSTreturntype
 | |
| 						{
 | |
| 							// get filename, length, width in that order, separated by newlines
 | |
| 							XmlNode tmp = nd.SelectSingleNode("Image_Filename");
 | |
| 							if (tmp != null && tmp.InnerText != null)
 | |
| 								text = tmp.InnerText + "\r\n";
 | |
| 							else
 | |
| 								text = " \r\n";
 | |
| 							tmp = nd.SelectSingleNode("Image_Height");
 | |
| 							if (tmp != null && tmp.InnerText != null)
 | |
| 								text = text + tmp.InnerText + "\r\n";
 | |
| 							else
 | |
| 								text = text + " \r\n";
 | |
| 							tmp = nd.SelectSingleNode("Image_Width");
 | |
| 							if (tmp != null && tmp.InnerText != null)
 | |
| 								text = text + tmp.InnerText + "\r\n";
 | |
| 							else
 | |
| 								text = text + " \r\n";
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							text = nd.InnerText;
 | |
| 						}
 | |
| //						Profiler.End("Grv8");
 | |
| 					}
 | |
| 
 | |
| 					ValueType |= FldType;
 | |
| 					if (PCApplicability)
 | |
| 						text = GetPCReturnValues(theDb, pcChildern, elm, PCApplicability, inusename, text); // C2021-026 Get P/C Children return values
 | |
| 					strbld.Append(text.Replace("{", "&123;").Replace("}", "&125;"));
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					strbld.Append(RtnValTemplate.Substring(left,right-left+1));			
 | |
| 				}
 | |
| 
 | |
| 				stindx = right+1;
 | |
| 				left = RtnValTemplate.IndexOf("<",left+1);
 | |
| 				if (left != -1 && left > right+1)  // append any plain text.
 | |
| 					strbld.Append(RtnValTemplate.Substring(right+1,left-right-1));			
 | |
| 			}
 | |
| 
 | |
| 			right++; // move past the right bracket ('>')
 | |
| 			if (right < RtnValTemplate.Length)
 | |
| 				strbld.Append(RtnValTemplate.Substring(right,RtnValTemplate.Length-right));
 | |
| 
 | |
| // Bug fix: B2004-044
 | |
| // If the ValueType is zero, then it will not appear on the list of ROs in the
 | |
| // procedure editor.
 | |
| 			if (ValueType == 0)
 | |
| 				ValueType = 1;
 | |
| 
 | |
| 			RtnValStr = strbld.ToString();
 | |
| 			return RtnValStr;
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		public string GetComboFieldValueAndType(XmlNode CurNode, string Fld, ref ushort FldTyp, bool ForMenu)
 | |
| 		{
 | |
| 			string RtnVal = "";
 | |
| 			XmlNode ChildNode = CurNode.FirstChild;
 | |
| 			FldTyp = 0;
 | |
| 
 | |
| 			while (ChildNode != null && FldTyp == 0)
 | |
| 			{
 | |
| 				if (ChildNode is VlnXmlElement)
 | |
| 				{
 | |
| 					string ChildName = ChildNode.Name.ToString();
 | |
| 					if (ChildName.StartsWith(Fld))
 | |
| 					{
 | |
| 						char CmboChar = Convert.ToChar(ChildName.Substring(ChildName.Length-1,1));
 | |
| 						switch (CmboChar)
 | |
| 						{
 | |
| 							case 'a': // Fixed Text
 | |
| 							case 'b': // Multi Line Text
 | |
| 								FldTyp = 1;
 | |
| 								RtnVal = ChildNode.InnerText;
 | |
| 								break;
 | |
| 							case 'c': // Table
 | |
| 								FldTyp = 2;
 | |
| 								if (ForMenu)
 | |
| 									RtnVal = "(Table)";
 | |
| 								else
 | |
| 									RtnVal = ChildNode.InnerText;
 | |
| 								break;
 | |
| 							case 'd': // X/Y Plot
 | |
| 								FldTyp = 4;
 | |
| 								if (ForMenu)
 | |
| 									RtnVal = "(Graph)";
 | |
| 								else
 | |
| 									RtnVal = ChildNode.InnerText;
 | |
| 								break;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 					ChildNode = ChildNode.NextSibling;
 | |
| 			}
 | |
| 			return RtnVal;
 | |
| 		}
 | |
| 
 | |
| 		// For this (VlnXmlElement), get the list of used fields. Need to find the
 | |
| 		// fields from the accessory page id template, the return value template 
 | |
| 		// and the menu title template or group title template (depends on if a
 | |
| 		// group edit or a RRO edit.
 | |
| 		public ArrayList GetRequiredFields()
 | |
| 		{
 | |
| 			ArrayList fldlist = new ArrayList();
 | |
| 			string accpagetmpl = GetAccPageIDTemplate();
 | |
| 			string retvaltmpl = null;
 | |
| 			string menutmpl = null;
 | |
| 			if (this.Name == "vlnGroup")
 | |
| 			{
 | |
| 				menutmpl = GetMenuValueTemplate("GroupMenuItem");
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				menutmpl = GetMenuValueTemplate("MenuItem");
 | |
| 				retvaltmpl = GetReturnValueTemplate();
 | |
| 			}
 | |
| 			// for each string, add its field names to the list.
 | |
| 			// accessory page id's only have a field and only used for ROs.
 | |
| 			if (this.Name != "vlnGroup" && accpagetmpl != null)
 | |
| 			{
 | |
| 				string fld = accpagetmpl.Substring(1,accpagetmpl.Length-2);
 | |
| 				fldlist.Add(fld+"\tAccessory Page Value");
 | |
| 			}
 | |
| 			// menutmpl's may have multiple fields. loop through them.
 | |
| 			int left, right, stindx, comma, rdelim;
 | |
| 			if (menutmpl != null)
 | |
| 			{
 | |
| 				left = menutmpl.IndexOf("<");
 | |
| 				right = 0;
 | |
| 				stindx = 0;
 | |
| 				comma = 0;
 | |
| 				while (left != -1)
 | |
| 				{
 | |
| 					// get right bracket and then check for valid field & if commas with
 | |
| 					// this, check for integer values.
 | |
| 					right = menutmpl.IndexOf(">",stindx);
 | |
| 					comma = menutmpl.IndexOf(",",stindx);
 | |
| 					rdelim = (comma>-1 && comma>left && comma<right)?comma:right;
 | |
| 					string substring = menutmpl.Substring(left+1,rdelim-left-1);
 | |
| 					string tmpds = CvtUserFldToFld(substring);
 | |
| 					substring = tmpds + "\tMenu Value";
 | |
| 					if(fldlist.Contains((Object)substring) == false)fldlist.Add(substring);
 | |
| 					left = menutmpl.IndexOf("<",right+1);
 | |
| 					stindx = right+1;
 | |
| 				}
 | |
| 			}
 | |
| 			// now add return value's if not a group level.
 | |
| 			if (this.Name != "vlnGroup" && retvaltmpl != null)
 | |
| 			{
 | |
| 				left = retvaltmpl.IndexOf('<');
 | |
| 				right = 0;
 | |
| 				stindx = 0;
 | |
| 				int leftbrace, rightbrace, stindxbrace=0;
 | |
| 				bool isreq;
 | |
| 				while (left != -1)
 | |
| 				{
 | |
| 					isreq = true;
 | |
| 					// get right bracket and then check for valid field & if commas with
 | |
| 					// this, check for integer values. Also, if it's within {}, it isn't
 | |
| 					// required.
 | |
| 					right = retvaltmpl.IndexOf('>',stindx);
 | |
| 					// first see if it is within it's own {}
 | |
| 					if (stindxbrace<retvaltmpl.Length)
 | |
| 						leftbrace = retvaltmpl.IndexOf('{',stindxbrace);
 | |
| 					else
 | |
| 						leftbrace=-1;
 | |
| 					if (leftbrace > -1) 
 | |
| 					{
 | |
| 						rightbrace = retvaltmpl.IndexOf('}',stindxbrace);
 | |
| 						if ((left>leftbrace&&left<rightbrace)&&(right>leftbrace&&right<rightbrace)) // don't do
 | |
| 							isreq=false;
 | |
| 						stindxbrace=rightbrace+1;
 | |
| 					}
 | |
| 					if (isreq==true)
 | |
| 					{
 | |
| 						string substring = retvaltmpl.Substring(left+1,right-left-1);
 | |
| 						string tmpds = CvtUserFldToFld(substring);
 | |
| 						substring = tmpds + "\tReturn Value";
 | |
| 						if(fldlist.Contains((Object)substring) == false)fldlist.Add(substring);
 | |
| 					}
 | |
| 					left = retvaltmpl.IndexOf("<",right+1);
 | |
| 					stindx = right+1;
 | |
| 				}
 | |
| 			}
 | |
| 			return fldlist;
 | |
| 		}
 | |
| 
 | |
| 		/// ******** RO Complete Report methods.
 | |
| 		/// 
 | |
| 		/// These methods are called by CmpRpt. They 'show', i.e. write to output
 | |
| 		/// file, print.tmp, the fields/data defining the group and Ro.
 | |
| 		/// 
 | |
| 
 | |
| 		// 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;
 | |
| 
 | |
| 		//	// 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 (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)
 | |
| 		{
 | |
| 			XmlNode nd = null;
 | |
| 			XmlNode grpnd = (XmlNode) CurElement.FirstChild;
 | |
| 			string CurFieldName = "";
 | |
| 			while (grpnd != null)
 | |
| 			{
 | |
| 				if (grpnd.Name.Substring(0,grpnd.Name.Length-1) == FldName.Substring(0,FldName.Length))
 | |
| 				{
 | |
| 					CurFieldName = grpnd.Name;
 | |
| 					break;
 | |
| 				}
 | |
| 				grpnd = grpnd.NextSibling;
 | |
| 			}
 | |
| 
 | |
| 			if (!CurFieldName.Equals(""))
 | |
| 				nd = CurElement.SelectSingleNode(CurFieldName);
 | |
| 
 | |
| 			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)
 | |
| 		{
 | |
| 			VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument;
 | |
| 			ROField rof;
 | |
| 			XmlNode nd;
 | |
| 			bool doingplot;
 | |
| 			string nm;
 | |
| 
 | |
| 			// Get used fields for this RO.
 | |
| 			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);
 | |
| 
 | |
| 			// Put out fields and their associated data.
 | |
| 			if (InUseList != null) 
 | |
| 			{
 | |
| 				xmldoc.writeRROBegin();
 | |
| 				xmldoc.writeInt(8);
 | |
| 				xmldoc.writeText(myrodb.MyDBID + MyROID);
 | |
| 				xmldoc.writeInt(7);
 | |
| 				xmldoc.writeText(this.GetAttribute("AccPageID").Trim());
 | |
| 				// add items to the InUseList box.
 | |
| 				for (int i=0; i< InUseList.Count; i++)
 | |
| 				{
 | |
| 					doingplot=false;
 | |
| 					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 ((uint)rof.GetFieldType == (uint)FieldTypes.Combination && nd==null)
 | |
| 						{	
 | |
| 							nd = GetCurrentOfMultiFields(this,nm);
 | |
| //							nd = this.SelectSingleNode(nm+"a");
 | |
| //							if (nd==null) nd = this.SelectSingleNode(nm+"b");
 | |
| //							if (nd==null) nd = this.SelectSingleNode(nm+"c");
 | |
| //							if (nd==null)
 | |
| //							{
 | |
| //								doingplot=true;
 | |
| //								nd = this.SelectSingleNode(nm+"d");
 | |
| //							}	
 | |
| 						}
 | |
| 						if (nd == null) // not found, write out a '0'.
 | |
| 							xmldoc.writeInt(0);
 | |
| 						else
 | |
| 						{
 | |
| 							if (nd.Equals(nm+"d"))
 | |
| 								doingplot = true;
 | |
| 							VlnXmlElement end;
 | |
| 							end = (VlnXmlElement) nd;
 | |
| 							if (rof.GetFieldType == (uint) FieldTypes.Image)
 | |
| 							{
 | |
| 								// get filename.
 | |
| 								XmlNode ind = this.SelectSingleNode("*/Image_Filename");
 | |
| 								if (ind==null) 
 | |
| 									xmldoc.writeInt(0);
 | |
| 								else
 | |
| 								{
 | |
| 									// find space & filename is after it.
 | |
| 									int indx = ind.InnerText.IndexOf(" ");
 | |
| 									if (indx < ind.InnerText.Length && indx > -1)
 | |
| 										xmldoc.writeImage(ind.InnerText.Substring(indx+1,ind.InnerText.Length-indx-1));
 | |
| 									else
 | |
| 										xmldoc.writeImage(ind.InnerText);
 | |
| 									// now do height & width??
 | |
| 									ind = this.SelectSingleNode("*/Image_Height");
 | |
| 									if (ind != null)
 | |
| 									{
 | |
| 										short iht = (short) System.Convert.ToInt16(ind.InnerText);
 | |
| 										xmldoc.writeInt(iht);
 | |
| 									}
 | |
| 									else
 | |
| 										xmldoc.writeInt(0);
 | |
| 									ind = this.SelectSingleNode("*/Image_Width");
 | |
| 									if (ind != null)
 | |
| 									{
 | |
| 										short iht = (short) System.Convert.ToInt16(ind.InnerText);
 | |
| 										xmldoc.writeInt(iht);
 | |
| 									}
 | |
| 									else
 | |
| 										xmldoc.writeInt(0);
 | |
| 								}
 | |
| 							}
 | |
| 							else
 | |
| 							{
 | |
| 								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();
 | |
| 			}
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		// ShowGroup processes the input group node for the complete report by
 | |
| 		// using ShowGroupDetail to output data for the group and ShowRRO to
 | |
| 		// output data for the RO
 | |
| 		DateTime last = DateTime.Now;		// use these to control status message output
 | |
| 		private bool ShowGroup(RODB myrodb, ArrayList headers, VlnStatusMessage showStat)
 | |
| 		{
 | |
| 			XmlNode chldnode;
 | |
| 			
 | |
| 			if (this.ParentNode.Name != "RO_Root")
 | |
| 			{	
 | |
| 				/* Bug fix:  B2001-001
 | |
| 				 * Compete RO Report for All ROs was printing an extra
 | |
| 				 * page showing just a prameter field.  This information
 | |
| 				 * was not always related to the RO Group being printed at
 | |
| 				 * this time.  Turns out that we don't need to call the
 | |
| 				 * ShowGroupDetail() at this point, only need to save
 | |
| 				 * header informat.  -jsj 6/8/2005
 | |
| 				 *
 | |
| 				ShowGroupDetail(myrodb);
 | |
| 				*/
 | |
| 				headers.Add(this.GetAttribute("MenuTitle"));
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				int bracket = this.InnerXml.IndexOf("<",0);
 | |
| 				if (bracket>-1) 
 | |
| 					headers.Add(this.InnerXml.Substring(0,bracket));
 | |
| 				else
 | |
| 					headers.Add(this.InnerXml);
 | |
| 			}
 | |
| 			string haskids, kidsloaded;
 | |
| 			haskids = this.GetAttribute("HasChild");
 | |
| 			kidsloaded = this.GetAttribute("ChildLoaded");
 | |
| 			if (haskids == "True" && kidsloaded == "False" )
 | |
| 			{
 | |
| 				myrodb.RODB_GetChildData(this,true);
 | |
| 				this.SetAttribute("ChildLoaded", "True");
 | |
| 			}
 | |
| 
 | |
| 			// go through all of the children for this node and put them out.
 | |
| 			chldnode = (XmlNode) this.FirstChild;
 | |
| 			
 | |
| 			while (chldnode != null)
 | |
| 			{
 | |
| 				if (chldnode is VlnXmlElement)
 | |
| 				{
 | |
| 					VlnXmlElement elem = (VlnXmlElement) chldnode;
 | |
| 					if (showStat != null)
 | |
| 						showStat.StatusMessage = elem.InnerText;
 | |
| 
 | |
| 					// if it's a group, recurse through it.
 | |
| 					if (chldnode.Name == "vlnGroup")
 | |
| 						elem.ShowGroup(myrodb, headers, showStat);
 | |
| 						// do RO's too.
 | |
| 					else
 | |
| 					{
 | |
| 						int levelcnt = chldnode.ChildNodes.Count;
 | |
| 						bool isParDisData = chldnode.Name == "Parameter__Display__Data";
 | |
| 						string TheMenuTitle = elem.GetAttribute("MenuTitle");
 | |
| 						if (showStat != null)
 | |
| 						{
 | |
| 							if (TimeSpan.FromTicks(DateTime.Now.Ticks - last.Ticks).Seconds > 1)
 | |
| 							{
 | |
| 								showStat.StatusMessage = TheMenuTitle;
 | |
| 								last = DateTime.Now;
 | |
| 							}
 | |
| 						}
 | |
| 						if (!isParDisData && ((levelcnt > 1) || (levelcnt==1 && !TheMenuTitle.Equals(""))))
 | |
| 							elem.ShowRRO(myrodb, headers);
 | |
| 					}
 | |
| 				}
 | |
| 				chldnode = chldnode.NextSibling;
 | |
| 			}
 | |
| 			// remove this group from the headers.
 | |
| 			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, 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;
 | |
| 
 | |
| 			// if this is the top node, i.e. with name "RO_Root", it is a complete report 
 | |
| 			// for all Ros, work from the root.
 | |
| 			if (this.Name == "RO_Root")
 | |
| 			{
 | |
| 				// show each 'table' group under the top.
 | |
| 				VlnXmlElement group = (VlnXmlElement) this.FirstChild;
 | |
| 				VlnXmlElement tmpgroup;
 | |
| 				while (group != null)
 | |
| 				{	
 | |
| 					// Now get subgroups for each group.
 | |
| 					myrodb.RODB_GetChildData(group,true);
 | |
| 					group.ShowGroup(myrodb, headers, showStat);
 | |
| 					tmpgroup = group;
 | |
| 					group.RemoveAll();
 | |
| 					group = (VlnXmlElement) tmpgroup.NextSibling;
 | |
| 				}
 | |
| 							
 | |
| 			}
 | |
| 			// this is a particular RO or group of ROs.
 | |
| 			else
 | |
| 			{
 | |
| 				if (this.Name == "vlnGroup")
 | |
| 					ShowGroup(myrodb, headers, showStat);
 | |
| 				else
 | |
| 					ShowRRO(myrodb, headers);
 | |
| 			}
 | |
| 			xmldoc.CloseTemp();
 | |
| 			return true;
 | |
| 		}
 | |
| 	}
 | |
| }
 |