Rich 29ffd0329c Added ability to perform a profile (Determine which sections of code are using the majority of the CPU time.)
Fixed logic that determines if the debug output should be created in the PDF.
Added ability to track DB actions.
Change cursor to a wait curcor when the print button is pressed.
Added Profile debug
Added a time-out for determining if a RO.FST file is newer.
Added a property (PrintAllAtOnce) to the ItemInfo object so that the code can differentiate between objects that are being used for edit or print.
Added logic to improve print performance.  Specifically initialize a number of item properties when the procedure is loaded for printing, rather than waiting for the properties to be lazy-loaded.
Added Profile debug
Changed NextItem property to use GetNextItem method when printing.
2015-01-19 20:49:15 +00:00

665 lines
18 KiB
C#

// ========================================================================
// Copyright 2006 - Volian Enterprises, Inc. All rights reserved.
// Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
// ------------------------------------------------------------------------
// $Workfile: $ $Revision: $
// $Author: $ $Date: $
//
// $History: $
// ========================================================================
using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using System.Collections.Generic;
using System.IO;
using System.Threading;
//using VEPROMS.Properties;
namespace VEPROMS.CSLA.Library
{
public partial class DocVersion: IVEDrillDown
{
public bool NewerRoFst
{
get
{
if (DocVersionAssociations == null || DocVersionAssociations.Count == 0) return false;
ROFstInfo roFstInfo = ROFstInfo.GetJustROFst(DocVersionAssociations[0].ROFstID);
RODbInfo rdi = RODbInfo.GetJustRODB(roFstInfo.RODbID);
string rofstPath = rdi.FolderPath + @"\ro.fst";
if (!File.Exists(rofstPath)) return false;
FileInfo fiRofst = new FileInfo(rofstPath);
// if the database Ro.Fst is newer or if the files have identical DTS,
// assume that they are the same file.
if (roFstInfo.DTS >= fiRofst.LastWriteTimeUtc) return false;
// next see if the data is the same size, i.e. byte count of record and byte count
// of file. If different sizes, the date/time stamp check will hold.
if (fiRofst.Length != roFstInfo.ROLookup.Length) return fiRofst.LastWriteTimeUtc > roFstInfo.DTS;
// if we can't tell by the DTS or size, compare the contents. Get all of the rodb's
// rofsts of the size of the file & compare bytes. If
ROFstInfoList fstList = ROFstInfoList.GetBySize(rdi.RODbID, (int)fiRofst.Length);
if (fstList.Count > 0)
{
FileStream fsIn = new FileStream(rofstPath, FileMode.Open, FileAccess.Read, FileShare.Read);
// Create an instance of StreamReader that can read characters from the FileStream.
BinaryReader r = new BinaryReader(fsIn);
byte[] ab = r.ReadBytes((int)fsIn.Length);
fsIn.Close();
foreach (ROFstInfo irofst in fstList)
{
// compare contents by comparing each byte.
for (int i = 0; i < fiRofst.Length; i++)
if (ab[i] != irofst.ROLookup[i]) return true;
}
}
return false;
}
}
#region VersionType
public VersionTypeEnum eVersionType
{
get { return (VersionTypeEnum)_VersionType; }
set { _VersionType = (int)value; }
}
#endregion
#region DocVersion Config
[NonSerialized]
private DocVersionConfig _DocVersionConfig;
public DocVersionConfig DocVersionConfig
{
get
{
if (_DocVersionConfig == null)
{
_DocVersionConfig = new DocVersionConfig(this);
_DocVersionConfig.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_DocVersionConfig_PropertyChanged);
}
return _DocVersionConfig;
}
}
private void _DocVersionConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
Config = _DocVersionConfig.ToString();
}
#endregion
#region UserSettings
/// <summary>
/// These settings are set on the user interface side.
/// This is used to control whether the Name and/or Title is displayed
/// next to the tree nodes in the user interface
/// </summary>
private bool _DisplayTreeNodeNames = true;
public bool DisplayTreeNodeNames
{
get { return _DisplayTreeNodeNames; }
set { _DisplayTreeNodeNames = value; }
}
private bool _DisplayTreeNodeTitles = false;
public bool DisplayTreeNodeTitles
{
get { return _DisplayTreeNodeTitles; }
set { _DisplayTreeNodeTitles = value; }
}
#endregion
public override string ToString()
{
// assume that at least one of the two options was selected
string rtnstr = "";
if (_DisplayTreeNodeNames) rtnstr = Name;
if (_DisplayTreeNodeTitles)
{
if (rtnstr.Length > 0) rtnstr += " - ";
rtnstr += Title;
}
return rtnstr;
//return string.Format("{0} - {1}", Name, Title);
}
#region IVEDrillDown
//public System.Collections.IList GetChildren()
//{
// return null;
//}
//public bool HasChildren
//{
// get { return _ItemID > 0; }
//}
//public IVEDrillDown ActiveParent
//{
// get
// {
// return MyFolder;
// }
//}
//private Format _ActiveFormat = null;
//public Format ActiveFormat
//{
// get
// {
// if (_ActiveFormat == null)
// _ActiveFormat = LocalFormat != null ? LocalFormat : ActiveParent.ActiveFormat;
// return _ActiveFormat;
// }
// set
// {
// _ActiveFormat = null;
// }
//}
//public Format LocalFormat
//{
// get { return MyFormat; }
//}
public ConfigDynamicTypeDescriptor MyConfig
{
get { return DocVersionConfig; }
}
#endregion
public DocVersionInfo MyDocVersionInfo
{ get { return DocVersionInfo.Get(VersionID); } }
}
public partial class DocVersionInfo : IVEDrillDownReadOnly
{
public TimeSpan tsTimeOut = TimeSpan.FromSeconds(6);
public bool pathExists(string path)
{
bool exists = true;
Thread t = new Thread(
new ThreadStart(delegate()
{
exists = System.IO.File.Exists(path);
})
);
t.Start();
bool completed = t.Join(tsTimeOut); //wait 6 seconds then 3 then 1.5 then .75 seconds
if (!completed)
{
exists = false;
t.Abort();
if (tsTimeOut > TimeSpan.FromSeconds(1))
tsTimeOut = TimeSpan.FromTicks( tsTimeOut.Ticks / 2);
}
return exists;
}
public bool NewerRoFst
{
get
{
if (DocVersionAssociations == null) return false;
ROFstInfo roFstInfo = ROFstInfo.GetJustROFst(DocVersionAssociations[0].ROFstID);
RODbInfo rdi = RODbInfo.GetJustRODB(roFstInfo.RODbID);
string rofstPath = rdi.FolderPath + @"\ro.fst";
//if (!File.Exists(rofstPath)) return false;
if (!pathExists(rofstPath))
{
_MyLog.WarnFormat("RO Path '{0}' could not be found", rofstPath);
return false;
}
FileInfo fiRofst = new FileInfo(rofstPath);
// if the database Ro.Fst is newer or if the files have identical DTS,
// assume that they are the same file.
if (roFstInfo.DTS >= fiRofst.LastWriteTimeUtc) return false;
TimeSpan ts = roFstInfo.DTS - fiRofst.LastWriteTimeUtc;
if (ts.TotalSeconds > -1F) return false;
// next see if the data is the same size, i.e. byte count of record and byte count
// of file. If different sizes, the date/time stamp check will hold.
if (fiRofst.Length != roFstInfo.ROLookup.Length) return fiRofst.LastWriteTimeUtc > roFstInfo.DTS;
// if we can't tell by the DTS or size, compare the contents. Get all of the rodb's
// rofsts of the size of the file & compare bytes. If
ROFstInfoList fstList = ROFstInfoList.GetBySize(rdi.RODbID, (int)fiRofst.Length);
if (fstList.Count > 0)
{
FileStream fsIn = new FileStream(rofstPath, FileMode.Open, FileAccess.Read, FileShare.Read);
// Create an instance of StreamReader that can read characters from the FileStream.
BinaryReader r = new BinaryReader(fsIn);
byte[] ab = r.ReadBytes((int)fsIn.Length);
fsIn.Close();
foreach (ROFstInfo irofst in fstList)
{
// compare contents by comparing each byte.
for (int i = 0; i < fiRofst.Length; i++)
if (ab[i] != irofst.ROLookup[i]) return true;
}
}
return false;
}
}
#region SearchPaths
public string _SearchDVPath;
public string SearchDVPath
{
get
{
if (_SearchDVPath == null)
_SearchDVPath = ActiveParent.SearchDVPath + "\u0007" + Name;
return _SearchDVPath;
}
}
public string SearchPath { get { return ""; } }
#endregion
#region DocVersion Config
[NonSerialized]
private DocVersionConfig _DocVersionConfig;
public DocVersionConfig DocVersionConfig
{ get { return (_DocVersionConfig != null ? _DocVersionConfig : _DocVersionConfig = new DocVersionConfig(this)); } }
private void DocVersionConfigRefresh()
{
_DocVersionConfig = null;
}
#endregion
#region MOVE TO DOCVERSION CONFIG
private string GetProfile(string grp, string nam)
{
return GetProfile(grp, nam, false);
}
private string GetProfile(string grp, string nam, bool flag)
{
DocVersionConfig dvcfg = DocVersionConfig;
string buff = null;
if (grp != null && !grp.Equals(string.Empty))
{
buff = dvcfg.GetValue(grp, nam); // get the value of 'nam' in 'grp'
if (buff == null || buff.Equals(string.Empty))
{
if (!flag)
buff = string.Format("<{0}-{1}>", grp, nam);
else
buff = null;
}
}
return buff;
}
public string UnitSpecific(string str, int len)
{
// This routine retrieves the procedure number format from the
// current directory and uses it to adjust the procedure number
// in the specified string
string retvalu = "";
string asis = "#";
if (str == null || str.Equals(string.Empty)) return retvalu; // return a null (empty) string
/*
* Bug fix: B2005-017 3/2/2005
* Need to use the largest procedure number length that's in the
* SET.DFF file. "LargestNumber" is the largest length after the
* procedure number is replaced via the SET.INI file "replace" list.
*
if(len==0)len=LargestNumber;
*/
// TODO: Do we need this line?-->>> if(len==0)len=LargestRawSetNumber;
//GetPrivateProfileString("unit", "procedure number", asis, mstr, MAXPATH, "proc.ini");
string pnum = asis;
//rhm/jcb stuff 20120511
//string mstr = GetProfile("Unit", "ProcedureNumber", true);
string mstr = DocVersionConfig.Unit_ProcedureNumber;
if (mstr != null && !mstr.Equals(string.Empty))
pnum = mstr;
if (pnum.Equals(asis))
retvalu = str;
else if (pnum[0] == '!')
{
// look for mstr in SET.INI
// GetPrivateProfileString("replace", mstr, mstr, tonum, 24, "set.ini");
// TODO: NOT SURE IF SET.INI AND PROC.INI HAVE UNIQUE GROUP NAMES!!!!!!!
//mstr = GetProfile("Replace", mstr);
mstr = GetProfile("Replace", mstr, true); // true allow it to return a null if not found
if (mstr == null) retvalu = str; // no replacement, use procedure number as is
}
else
{
retvalu = "";
string[] pnumsplit = pnum.Split(new Char[] { '#' });
int cnt = 0;
foreach (string s in pnumsplit)
{
if (!s.Equals(string.Empty))
{
if ((cnt == 0) && (str.StartsWith(" ")))
{
string padding = new string(' ', s.Length);
retvalu += padding;
}
else
retvalu += s;
}
else
retvalu += str.Trim();
cnt++;
}
// append trailing blanks or procedure number (str)
if (str.EndsWith(" "))
{
// count number of trailing blanks and append them to retvalu
cnt = str.Length - 1;
while (cnt > 0 && str[cnt] == ' ') cnt--;
retvalu += new string(' ', str.Length - cnt - 1);
}
}
return retvalu;
}
public string Evaluate(string str, int len)
{
string retval = null;
string swhir = "PSU"; /* order inwhich to check */
string pn;
if (str.Length > 1 && str[1] == '-')
{
int swptr = swhir.IndexOf((str.ToUpper())[0]);
//char swchar = '';
//if (swptr != -1)
// swchar = swhir[swptr];
string sav = str.Substring(len);
str = str.Substring(0, len);
string substr = str.Substring(2);
substr = substr.Replace(" ","");
while (swptr >= 0 && swptr < swhir.Length && retval == null) //retval.Equals(string.Empty))
{
switch (swhir[swptr])
{
case 'U':
//retval = GetProfile("Unit", substr, true);
if (substr.ToLower() == "id")
retval = this.DocVersionConfig.Unit_ID;
if (substr.ToLower() == "name")
retval = this.DocVersionConfig.Unit_Name;
if (substr.ToLower() == "number")
retval = this.DocVersionConfig.Unit_Number;
if (substr.ToLower() == "text")
retval = this.DocVersionConfig.Unit_Text;
//retval = this.DocVersionConfig.Other_Unit_ID;
//retval = this.DocVersionConfig.Other_Unit_Name;
//retval = this.DocVersionConfig.Other_Unit_Number;
//retval = this.DocVersionConfig.Other_Unit_Text;
break;
case 'S':
//retval = GetProfile("Procedure_Set", substr, true);
if(substr.ToLower() == "id")
retval = this.DocVersionConfig.Unit_ProcedureSetID;
if (substr.ToLower() == "name")
retval = this.DocVersionConfig.Unit_ProcedureSetName;
break;
case 'P':
//TODO: THIS IS A GLOBAL IN THE 16 BIT CODE!!!!
string procnumber = "";
pn = UnitSpecific(procnumber, 0);
retval = GetProfile(pn, substr, true);
break;
}
if (retval == null) // .Equals(string.Empty))
swptr++;
}
str += sav;
}
else if (len == 1 && (str.ToUpper())[0] == 'U')
{
retval = this.DocVersionConfig.Unit_Number;
}
else if (len == 2 && str.StartsWith("ID"))
{
retval = this.DocVersionConfig.Unit_ID;
}
// if the return value is empty, then the resulting
// evaluation should repeat the token string including
// the braces. - the beginning brace is not passed in.
//if (retval.Equals(string.Empty))
//{
// retval = (char*)mallocq(len + 3);
// strncpy(retval, str - 1, len + 2);
//}
if (retval == null)
retval = string.Format("<{0}>", str.Substring(0, len));
return retval;
}
public string ProcessDocVersionSpecificInfo(string rawvalue)
{
string str = rawvalue;
string rtnstr = "";
int l = rawvalue.Length;
while (l > 0)
{
int ptr = str.IndexOf('<'); //nextDelimiter("<", str, l);
int cptr = (ptr == -1) ? -1 : str.IndexOf('>'); //nextDelimiter(">", ptr, strlen(ptr));
// jsj 2/5/10 added "|| (ptr > cptr)" to fix bug where rawvalue = "Insert token for ->Step<- to transition back to."
if (ptr == -1 || (ptr > -1 && ((cptr == -1) || (ptr > cptr))))
{
//add(new seText(str, l));
//str += l;
rtnstr += str;
l = 0; // jump out of while loop
}
else
{
int cnt = ptr;
if (cnt > 0)
{
//add(new seText(str, cnt));
rtnstr += str.Substring(0, cnt);
l -= cnt;
str = str.Substring(ptr);
}
ptr = str.IndexOf('>')+1; //nextDelimiter(">", str, l) + 1;
cnt = ptr; //(int)(ptr - str);
//add(new seUser(str + 1, cnt - 2));
rtnstr += Evaluate(str.Substring(1, cnt - 2),cnt-2);
l -= cnt;
str = str.Substring(ptr); //ptr;
}
}
return rtnstr;
}
#endregion
ItemInfoList _Procedures = null;
public ItemInfoList Procedures
{ get { return (_Procedures != null ? _Procedures : _Procedures = ItemInfoList.GetList(_ItemID, (int)E_FromType.Procedure)); } }
public void ResetProcedures()
{
_Procedures = null;
}
public static void ResetProcedures(int versionID)
{
string key = versionID.ToString();
if (_CacheByPrimaryKey.ContainsKey(key))
foreach (DocVersionInfo dvi in _CacheByPrimaryKey[key])
dvi.ResetProcedures();
}
#region IVEReadOnlyItem
public System.Collections.IList GetChildren()
{
return Procedures;
}
//public bool ChildrenAreLoaded
//{
// get { return _iil == null; }
//}
public bool HasChildren
{
get { return _ItemID > 0; }
}
public IVEDrillDownReadOnly ActiveParent
{
get
{
return MyFolder;
}
}
public FormatInfo ActiveFormat
{
get {return LocalFormat != null ? LocalFormat : ActiveParent.ActiveFormat;}
}
public FormatInfo LocalFormat
{
get {
//Console.WriteLine("DV Local {0} {1} {2}", (MyFormat == null) ? "MYformat is null" : MyFormat.Name,FormatID,(MyFormat == null)?0:MyFormat.FormatID);
return MyFormat;
}
}
public ConfigDynamicTypeDescriptor MyConfig
{
get { return Get().DocVersionConfig; }
}
//public bool HasStandardSteps()
//{ return false; }
#region UserSettings
/// <summary>
/// These settings are set on the user interface side.
/// This is used to control whether the Name and/or Title is displayed
/// next to the tree nodes in the user interface
/// </summary>
private bool _DisplayTreeNodeNames = true;
public bool DisplayTreeNodeNames
{
get { return _DisplayTreeNodeNames; }
set { _DisplayTreeNodeNames = value; }
}
private bool _DisplayTreeNodeTitles = false;
public bool DisplayTreeNodeTitles
{
get { return _DisplayTreeNodeTitles; }
set { _DisplayTreeNodeTitles = value; }
}
#endregion
public override string ToString()
{
// assume that at least one of the two options was selected
string rtnstr = "";
if (_DisplayTreeNodeNames) rtnstr = Name;
if (_DisplayTreeNodeTitles)
{
if (rtnstr.Length > 0) rtnstr += " - ";
rtnstr += Title;
}
return rtnstr;
//return string.Format("{0} - {1}", Name, Title);
}
//public string ToString(string str,System.IFormatProvider ifp)
//{
// return ToString();
//}
public ItemInfo LastChild()
{
return MyItem.LastSibling;
}
public ItemInfo FirstChild()
{
return MyItem;
}
#endregion
#region Extension
partial class DocVersionInfoExtension : extensionBase
{
public override void Refresh(DocVersionInfo tmp)
{
tmp.DocVersionConfigRefresh();
}
}
#endregion
public ROFstInfo GetROFst(int rodbid)
{
foreach (AssociationInfo dva in DocVersionAssociations)
{
if (dva.MyROFst.RODbID == rodbid)
return dva.MyROFst;
}
return null;
}
public bool IsFolder
{
get
{
return false;
}
}
public bool IsDocVersion
{
get
{
return true;
}
}
public bool IsProcedure
{
get
{
return false;
}
}
public bool IsSection
{
get
{
return false;
}
}
public bool IsStep
{
get
{
return false;
}
}
public int MultiUnitCount
{
get
{
return DocVersionConfig.Unit_Count;
}
}
private string[] _UnitNames;
public string[] UnitNames
{
get
{
if (_UnitNames == null)
{
// _UnitNames = DocVersionConfig.Unit_Name.Split(',');
_UnitNames = new string[DocVersionConfig.Unit_Count];
int j = 0;
for (int k = 1; k <= DocVersionConfig.MaxSlaveIndex; k++)
{
DocVersionConfig.SelectedSlave = k;
try
{
_UnitNames[j] = DocVersionConfig.Unit_Name;
j++;
}
catch
{
}
}
DocVersionConfig.SelectedSlave = 0;
}
return _UnitNames;
}
}
}
public enum VersionTypeEnum : int
{
WorkingDraft = 0, Temporary = 1, Revision = 128, Approved = 129
}
}