Some of Point Beach RO's have curly braces in the RO return value for the units in P/C. Found this on some (5-7) Annunciator RO values. The definition of the return value (multiple return values) uses curly braces so PROMS cannot distinguish between brackets being part of a unit value or part of the format for multiple return values. Equipment Designation, Main Steam (MS), Annunciators have examples of return values with curly braces. Look at the Referenced Object Definition on the Annunciators tree node for the definition of the return value.
1344 lines
40 KiB
C#
1344 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;
|
|
|
|
//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;
|
|
}
|
|
}
|
|
}
|