/********************************************************************************************* * Copyright 2004 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: ProcSet.cs $ $Revision: 45 $ * $Author: Jsj $ $Date: 11/09/06 11:33a $ * * $History: ProcSet.cs $ * * ***************** Version 45 ***************** * User: Jsj Date: 11/09/06 Time: 11:33a * Updated in $/LibSource/VEObject * skip empty library document files * * ***************** Version 44 ***************** * User: Jsj Date: 10/06/06 Time: 11:21a * Updated in $/LibSource/VEObject * fixed logic in creating a new Enhanced Document set and in updating an * Enhanced Document SET file. * * ***************** Version 43 ***************** * User: Jsj Date: 8/30/06 Time: 10:04a * Updated in $/LibSource/VEObject * Added Multi Procedure Data Checker * * ***************** Version 42 ***************** * User: Jsj Date: 7/21/06 Time: 2:58p * Updated in $/LibSource/VEObject * fixed Unhandled Exception error * * ***************** Version 41 ***************** * User: Jsj Date: 7/06/06 Time: 2:08p * Updated in $/LibSource/VEObject * Fixed enhanced document set creation bug. The link files where being * put in the wrong place. * * ***************** Version 40 ***************** * User: Kathy Date: 6/15/06 Time: 8:59a * Updated in $/LibSource/VEObject * B2006-024 fix: check for exclusive connection before approval & lock * during approval * * ***************** Version 39 ***************** * User: Kathy Date: 5/01/06 Time: 11:18a * Updated in $/LibSource/VEObject * Fix B2006-018: single quote in proc number causes problem on data * request * * ***************** Version 38 ***************** * User: Jsj Date: 9/20/05 Time: 2:48p * Updated in $/LibSource/VEObject * ContAct.INI logic for approve and master/slave, also Proc.INI logic for * approve * * ***************** Version 37 ***************** * User: Kathy Date: 9/20/05 Time: 1:17p * Updated in $/LibSource/VEObject * Copy lib docs - initialize a variable * * ***************** Version 36 ***************** * User: Jsj Date: 9/16/05 Time: 9:55a * Updated in $/LibSource/VEObject * Additional approval checks for RO Usage, RO directory existance, and * date of RO.FST file * * ***************** Version 35 ***************** * User: Kathy Date: 9/06/05 Time: 11:25a * Updated in $/LibSource/VEObject * B2005-032 (use largest numDatabases for app ind write ro.fst) * * ***************** Version 34 ***************** * User: Kathy Date: 8/31/05 Time: 11:33a * Updated in $/LibSource/VEObject * B2005-032: new groups crashed when writing to ro.fst during approve * sel. * * ***************** Version 33 ***************** * User: Kathy Date: 8/16/05 Time: 2:56p * Updated in $/LibSource/VEObject * B2005-030: error if missing ndx * * ***************** Version 32 ***************** * User: Kathy Date: 7/26/05 Time: 2:07p * Updated in $/LibSource/VEObject * Improve error message on updatesetdti if bad largestnumber data * * ***************** Version 31 ***************** * User: Jsj Date: 7/15/05 Time: 4:06p * Updated in $/LibSource/VEObject * added check for empty RO usage * * ***************** Version 30 ***************** * User: Kathy Date: 7/11/05 Time: 8:02a * Updated in $/LibSource/VEObject * Fix status message * * ***************** Version 29 ***************** * User: Kathy Date: 7/07/05 Time: 1:49p * Updated in $/LibSource/VEObject * Fix Approve All Remove Change Bars from WD caption * * ***************** Version 28 ***************** * User: Kathy Date: 6/21/05 Time: 7:26a * Updated in $/LibSource/VEObject * update ro from procedures & minor fixes * * ***************** Version 27 ***************** * User: Jsj Date: 6/16/05 Time: 2:46p * Updated in $/LibSource/VEObject * Check for valid RO path before doing an approval * * ***************** Version 26 ***************** * User: Kathy Date: 6/06/05 Time: 12:35p * Updated in $/LibSource/VEObject * Allow lock to be set, even if plant or system lock exists * * ***************** Version 25 ***************** * User: Jsj Date: 6/02/05 Time: 11:35a * Updated in $/LibSource/VEObject * fix for approving with conditional ROs * * ***************** Version 24 ***************** * User: Kathy Date: 5/31/05 Time: 12:42p * Updated in $/LibSource/VEObject * ? in vfw for ro values if approve selected before vfw * * ***************** Version 23 ***************** * User: Kathy Date: 5/25/05 Time: 10:32a * Updated in $/LibSource/VEObject * Allow edits for tmpchg * * ***************** Version 22 ***************** * User: Kathy Date: 5/20/05 Time: 10:23a * Updated in $/LibSource/VEObject * explicit close of ro.fst * * ***************** Version 21 ***************** * User: Jsj Date: 5/20/05 Time: 9:22a * Updated in $/LibSource/VEObject * get the non-processed ro return value for saving in the RO.FST file * * ***************** Version 20 ***************** * User: Kathy Date: 5/19/05 Time: 11:07a * Updated in $/LibSource/VEObject * missed updating oldto transition field on approve all * * ***************** Version 19 ***************** * User: Jsj Date: 5/17/05 Time: 11:58a * Updated in $/LibSource/VEObject * Approve Graphic fix, cleanup * * ***************** Version 18 ***************** * User: Jsj Date: 5/12/05 Time: 11:52a * Updated in $/LibSource/VEObject * fixed logic dealing with PROC.INI parent (master) identification and * the EOP.LNK parent identification * * ***************** Version 17 ***************** * User: Kathy Date: 5/11/05 Time: 9:29a * Updated in $/LibSource/VEObject * bug fixes/mods for approval testing * * ***************** Version 16 ***************** * User: Jsj Date: 5/06/05 Time: 12:08p * Updated in $/LibSource/VEObject * bug fix setting creating new enhanced document set (setting up) * * ***************** Version 15 ***************** * User: Kathy Date: 4/21/05 Time: 10:23a * Updated in $/LibSource/VEObject * remove upgrade2005 define & cleanup * * ***************** Version 14 ***************** * User: Jsj Date: 4/15/05 Time: 9:46a * Updated in $/LibSource/VEObject * Bug fix B2005-021, parent and erg selections (backgrounds, deviations, * slaves) was not sticking when changed. * * ***************** Version 13 ***************** * User: Kathy Date: 4/12/05 Time: 1:04p * Updated in $/LibSource/VEObject * B2005-008: C2005-001: B2005-020. * * ***************** Version 12 ***************** * User: Jsj Date: 3/31/05 Time: 9:17a * Updated in $/LibSource/VEObject * * ***************** Version 11 ***************** * User: Jsj Date: 3/28/05 Time: 12:17p * Updated in $/LibSource/VEObject * * ***************** Version 10 ***************** * User: Kathy Date: 3/22/05 Time: 10:09a * Updated in $/LibSource/VEObject * approve: remove chg bar/log file * * ***************** Version 9 ***************** * User: Jsj Date: 3/14/05 Time: 1:37p * Updated in $/LibSource/VEObject * * ***************** Version 8 ***************** * User: Jsj Date: 3/10/05 Time: 4:01p * Updated in $/LibSource/VEObject * hooks to use the new rofst file namespace * * ***************** Version 7 ***************** * User: Kathy Date: 3/08/05 Time: 1:51p * Updated in $/LibSource/VEObject * Approval * * ***************** Version 6 ***************** * User: Kathy Date: 1/31/05 Time: 11:06a * Updated in $/LibSource/VEObject * Fix B2005-005 (connection & delete directory errors). also, fix icon * * ***************** Version 5 ***************** * User: Kathy Date: 1/24/05 Time: 2:45p * Updated in $/LibSource/VEObject * B2005-004 fixes * * ***************** Version 4 ***************** * User: Kathy Date: 1/10/05 Time: 1:07p * Updated in $/LibSource/VEObject * B2004-062: Allow new sets name of PROCS & PROCS2, and other fixes * * ***************** Version 3 ***************** * User: Jsj Date: 11/12/04 Time: 10:35a * Updated in $/LibSource/VEObject * Change Default Settings fix * * ***************** Version 2 ***************** * User: Kathy Date: 10/25/04 Time: 10:25a * Updated in $/LibSource/VEObject * Fix B2004-049 and don't load link info if only checking for child data * * ***************** Version 1 ***************** * User: Kathy Date: 7/27/04 Time: 8:53a * Created in $/LibSource/VEObject *********************************************************************************************/ using System; using System.Collections; using System.Text; using System.IO; using System.Windows.Forms; using System.Data; using System.ComponentModel; using System.Diagnostics; using Utils; using GUI_Utils; using VlnStatus; using VDB_Proc; using VENetwork; using VDB; using VDB_Set; using VDB_SetExt; using VDB_TransUsage; using VDB_ROUsage; using IniFileIO; namespace VEObject { /// /// VEO_ProcSet support procedure set functionality. /// public class VEO_ProcSet : VEO_Base { public bool isArchived; public bool isApproved; // flags that this is an approved set public bool isSetApproved; // flags set that has an approved subdirectory public bool isTempChange; // flags that this is a temporary change set, // i.e. tmpchg subdirectory in an approved dir public bool hasLibDocs; public bool setExists; public bool hasExtensions; // has setextension (proccomment) option public bool cfg_load; // flags whether cfg settings have been loaded yet public ProcTypeOptions _ProcType; public string parentLink; public string guideLink; public string ROPath; public string _curDirectory; public string _formatTitle; private PSProperties propdlg; public string ErrorOnPSName; protected string tmpTitle; protected string tmpLocation; protected bool changeLocation; protected bool changeTitle; private string[] LinkFiles={"\\BCK.LNK","\\DVT.LNK","\\ERG.LNK"}; private string PrevDirectory; public string SuffixFlags; public string ExtraRevNumber; public string origExtraRevNumber; // check against for saving public bool hasExtraRevNumber; public long accessFlags; public bool blnCopiedProcINI; public string DateTimeInit; public bool HasRevision; // flags that serial number includes approval revising function public bool UseLongProcTitles; // flag whether to remove change bars during approval (set on procset properties & // value saved in proc.ini). Default is true. public bool RmChgBarOnApp; public bool tmpRmChgBarOnApp; // the following should contain one of the procs to approve for approve selected, in case // of edit conflicts at the set or 'Procedures' level. public VEO_Proc AppSelForEdit; public VEO_ProcSet(UserRunTime iusrRunTime, string ititle, string ipath, long acFlags) { isTempChange=false; isApproved=false; accessFlags=acFlags; ErrorOnPSName=null; ExtraRevNumber=null; origExtraRevNumber=null; usrRunTime = iusrRunTime; cfg_load = false; hasExtensions = usrRunTime.SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_PROCCOMMENT_ON)>0; hasExtraRevNumber=false; SuffixFlags=null; blnCopiedProcINI = false; AppSelForEdit = null; if (ititle==null) { _curDirectory = ipath; isNew=true; _Title = "New Procedure Set"; _Location = ""; } else { int indx1, indx2; if (((indx1=ipath.IndexOf("\\approved"))>-1) || ((indx2=ipath.IndexOf("\\APPROVED"))>-1)) isApproved=true; isSetApproved=false; if(!isApproved) // see if this set has associated approved version { string apname = ipath + "\\approved\\set.dbf"; isSetApproved = File.Exists(apname); } changeLocation=false; changeTitle=false; isNew=false; string tmpstr = ipath.ToLower(); int indxd; int indxb; int indxs; indxd = tmpstr.IndexOf(".dvt"); indxb = tmpstr.IndexOf(".bck"); indxs = tmpstr.IndexOf(".sl"); if (indxd > -1) _ProcType=ProcTypeOptions.Deviation; else if (indxb > -1) _ProcType=ProcTypeOptions.Background; else if (indxs > -1) _ProcType=ProcTypeOptions.Slave; else _ProcType = ProcTypeOptions.Standard; string tmploc=ipath; int lstslash = tmploc.LastIndexOf("\\"); if (lstslash < 0) lstslash = 0; _curDirectory = tmploc.Substring(0,lstslash==0?tmploc.Length:lstslash); _Location = tmploc.Substring(lstslash+1,tmploc.Length-lstslash-1); _Title = ititle; VEObjectType = (int)VEObjectTypesDefs.ProcedureSet; isTempChange = (_Location.ToUpper().IndexOf("TMPCHG",0,_Location.Length)>-1); if (isTempChange) isApproved=false; } UseLongProcTitles=false; RmChgBarOnApp=true; FileInfo fi = new FileInfo(_curDirectory+"\\"+_Location+"\\PROC.INI"); if (fi.Exists) { PrivateProfile ppCfg; ppCfg = new PrivateProfile(_curDirectory+"\\"+_Location+"\\PROC.INI"); string pptmp=ppCfg.Attr("Set Options","UseLongProcTitles"); if (pptmp.ToUpper() == "TRUE") UseLongProcTitles=true; pptmp = ppCfg.Attr("Set Options","RemoveChangeBarOnApproval"); if (pptmp.ToUpper() == "FALSE") RmChgBarOnApp=false; } tmpRmChgBarOnApp=RmChgBarOnApp; LoadLockInfo(); if (isTempChange) iconStates = new int[5] {23,23,25,23,24}; else if (isApproved) iconStates = new int[5] {18,18,20,18,19}; else iconStates = new int[5] {12,21,14,22,13}; icon = iconStates[(int)Lock.LockStatus]; } // Return true/false if the "masterdir" setting in the PROC.INI file // matches the current directory name. Also set "mpath" to the // "masterdir" value public bool InMaster(ref string mpath) { PrivateProfile procINI; string iniMasterDir; procINI = new PrivateProfile(_curDirectory+"\\"+_Location+"\\PROC.INI"); iniMasterDir=procINI.Attr("Applicability","masterdir"); if (mpath != null) mpath = iniMasterDir; return (iniMasterDir.ToUpper()).Equals(_Location.ToUpper()); } public string GetMasterFromProcINI() { string rtnstr=""; InMaster(ref rtnstr); return rtnstr; } public override void LoadLockInfo() { Lock = new VELock(_curDirectory+"\\"+_Location, usrRunTime.myUserData, usrRunTime.InMultiUserMode?VENetwork.LockTypes.ProcSet:VENetwork.LockTypes.None); } [Description("Location"),Category("Procedure Set"),ReadOnly(true)]public string Location { get{return _Location;} set{_Location=value;} } [Description("Current Directory"),Category("Procedure Set"),ReadOnly(true)]public string CurDirectory { get{return _curDirectory;} set{_curDirectory=value;} } [Description("Title"),Category("Procedure Set"),EditorAttribute(typeof(VESymbDlg), typeof(System.Drawing.Design.UITypeEditor))]public string Title { get { if (!changeTitle) return _Title; else return tmpTitle; } set { changeTitle=true; tmpTitle=value; } } [Description("Format Title"),Category("Procedure Set"),ReadOnly(true)]public string FormatTitle { get{return _formatTitle;} set{_formatTitle=value;} } public override void Restore() { changeLocation=false; changeTitle=false; tmpRmChgBarOnApp=RmChgBarOnApp; if(hasExtraRevNumber)ExtraRevNumber=origExtraRevNumber; } public override bool Open() { if(_Location!=null) { isOpen = true; if (Directory.GetCurrentDirectory() == _curDirectory+"\\"+_Location) PrevDirectory = _curDirectory; else PrevDirectory = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(_curDirectory+"\\"+_Location); } return true; } // The close method resets, if necessary from any multi-user settings and // positions back to the parent directory (which is a level above the // current level) public override bool Close() { if (!isOpen)return false; isOpen = false; if (Connection !=null)Connection.Exit(); Directory.SetCurrentDirectory(".."); return true; } public string GetFormatTitle() { if (isNew) { _formatTitle = "No format selected"; return _formatTitle; } // get curset pathname, i.e. whether single or multi user. // for now, hardcode. CurSet cs = new CurSet(this._curDirectory+"\\"+this._Location+"\\curset.dat"); cs.Read(); FmtFile ff = new FmtFile(cs.DefaultPlantFmt+".fmt"); _formatTitle = ff.GetFormatTitle(usrRunTime); return _formatTitle; } public string GetParentLink() { if((_ProcType==ProcTypeOptions.Deviation || _ProcType==ProcTypeOptions.Background) && parentLink==null) { string tmpPath = _curDirectory + "\\" + _Location + "\\eop.lnk"; string line; try { StreamReader sr = new StreamReader(tmpPath); line = sr.ReadLine(); sr.Close(); parentLink=line; } catch (Exception) { parentLink=null; } } else if (_ProcType==ProcTypeOptions.Slave) { parentLink = GetMasterFromProcINI(); if (parentLink.Equals("")) parentLink = null; } if (parentLink != null) { if (parentLink[1] != ':') { // build full path string CurDirSave = Directory.GetCurrentDirectory(); if (parentLink.StartsWith(".") || parentLink.StartsWith("\\")) Directory.SetCurrentDirectory(_curDirectory + "\\" + _Location); else Directory.SetCurrentDirectory(_curDirectory); Directory.SetCurrentDirectory(parentLink); parentLink = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(CurDirSave); } } return parentLink; } public string GetGuideLink() { if(_ProcType==ProcTypeOptions.Deviation && guideLink==null) { string tmpPath = _curDirectory + "\\" + _Location + "\\erg.lnk"; string line; try { StreamReader sr = new StreamReader(tmpPath); line = sr.ReadLine(); sr.Close(); guideLink=line; } catch (Exception e) { MessageBox.Show(e.Message,"Error Finding ERG Path"); guideLink=null; } } return guideLink; } public bool CheckParentLink(string EOPSet, ProcTypeOptions linktype) { // Setup path to the linked EOP directory, if it's already set, don't allow change string tmpPath = EOPSet + LinkFiles[(linktype==ProcTypeOptions.Background?0:1)]; FileInfo fi = new FileInfo(tmpPath); if (fi.Exists == true && !isNew) return (false); return (true); } public bool SetParentLink(string EOPSet, ProcTypeOptions linktype) { return SetParentLink(EOPSet,linktype,false); } public bool SetParentLink(string EOPSet, ProcTypeOptions linktype, bool SelectionChange) { string enhSet=_curDirectory + "\\" + _Location; // If Slave procedure set, then update the PROC.INI with the // path to the master procedure set if (linktype == ProcTypeOptions.Slave) { INIFile prcini = new INIFile(); prcini.WriteINIKeyValueStr("Applicability","masterdir",EOPSet,"proc.ini"); } else { // Setup path to the linked EOP directory, if it's already set, don't allow change string tmpPath = EOPSet + LinkFiles[(linktype==ProcTypeOptions.Background?0:1)]; FileInfo fi = new FileInfo(tmpPath); if (fi.Exists == true && !SelectionChange) return (false); tmpPath = enhSet + "\\EOP.LNK"; DirectoryInfo di = new DirectoryInfo(enhSet); if (di.Exists == false) return false; // tmpPath = _Location + "\\eop.lnk"; // currently in the directory // fi = new FileInfo("eop.lnk"); fi = new FileInfo(tmpPath); if (fi.Exists) fi.Delete(); try { // StreamWriter sw = new StreamWriter("eop.lnk"); StreamWriter sw = new StreamWriter(tmpPath); sw.WriteLine(EOPSet); sw.Close(); } catch (Exception e) { MessageBox.Show(e.Message,"Error Creating EOP.LNK"); return false; } // Establish link file in EOP directory for use by "LinkTo" // string enhSet=_curDirectory + "\\" + _Location; tmpPath = EOPSet + LinkFiles[(linktype==ProcTypeOptions.Background?0:1)]; try { StreamWriter sw = new StreamWriter(tmpPath); sw.WriteLine(enhSet); sw.Close(); } catch (Exception e) { MessageBox.Show(e.Message,"Error Creating Background or Deviation LinkTO File"); return false; } } return (true); } public bool SetGuideLink(string ERGSet) //,bool full) { string enhSet=_curDirectory + "\\" + _Location; if (ERGSet == null || ERGSet=="") return false; //string tmpPath = _Location + "\\erg.lnk"; // Delete existing link file and write a new one. // FileInfo fi = new FileInfo("erg.lnk"); string tmpPath = enhSet + "\\erg.lnk"; // FileInfo fi = new FileInfo("erg.lnk"); DirectoryInfo di = new DirectoryInfo(enhSet); if (di.Exists == false) return false; FileInfo fi = new FileInfo(tmpPath); if (fi.Exists) fi.Delete(); try { // StreamWriter sw = new StreamWriter("erg.lnk"); StreamWriter sw = new StreamWriter(tmpPath); sw.WriteLine(ERGSet); sw.Close(); } catch (Exception e) { MessageBox.Show(e.Message,"Error Creating ERG.LNK File"); return false; } return true; } public bool Exists(string dname) { if(dname==null||dname=="") return false; string pname=null; // see if this is a pathname, it needs to be for the Exists check. if (dname.IndexOf("\\") < 0) // it's not a path, prepend the path pname = _curDirectory + "\\" + dname; else pname = dname; // loop through all subdirectories to see if this one exists. VEO_Plant plnt = (VEO_Plant) parentObj; int numsets = plnt.Children.Count; for (int i=0;i" argument if (!amILockedByMe()) { string UserTempDir = usrRunTime.TempDirPath; if (UserTempDir != null) myProcess.StartInfo.Arguments = " -dir" + Directory.GetCurrentDirectory() + "\\" + UserTempDir; } myProcess.Start(); myProcess.WaitForExit(); // reset the format title. GetFormatTitle(); return true; } public bool IsValid() { // name validity is checked in dialog. // check for none-empty data. if (_Location == null || _Location == "" || _Title == null || _Title == "") { MessageBox.Show("Need to fill in all data.", "General Error"); return false; } // check for correct linkage if this is a background or deviation. if (this._ProcType == VEObject.ProcTypeOptions.Background || this._ProcType == VEObject.ProcTypeOptions.Deviation) { // is the parent link already linked to a different document, if so. // can't do another. bool lnk = CheckParentLink(this.parentLink,this._ProcType); if (!lnk) { MessageBox.Show("This document has a link already","General Error"); return false; } } return true; } public bool CheckForValidPSName(string newdname) { bool rtnval = true; ErrorOnPSName = null; // get the new name for the procset & check that it ends with // the correct extension & does not already exist. // be sure the name doesn't exist. string newpath = _curDirectory + "\\" + newdname; if (Directory.Exists(newpath) == true) { ErrorOnPSName = "Location name for this set already exists."; rtnval = false; } // if standard type & procs - it's a valid name if (rtnval && (this._ProcType==VEObject.ProcTypeOptions.Standard&&newdname.ToUpper() == "PROCS"))return true; if (rtnval && (this._ProcType==VEObject.ProcTypeOptions.Standard&&newdname.ToUpper() == "PROCS2")) return true; if (rtnval && newdname.IndexOf(".") <0) { ErrorOnPSName = "Location (directory) name must have an extension."; rtnval = false; } if (rtnval) { int idx = newdname.LastIndexOf('.'); string ext = ""; if (idx > 0) { ext = newdname.Substring(idx+1); ext = ext.ToUpper(); } if (this._ProcType == VEObject.ProcTypeOptions.Standard) { if (!ext.Equals("PRC")) { ErrorOnPSName = "Standard procedure set location (directory) must end in .PRC"; rtnval = false; } } else if (this._ProcType == VEObject.ProcTypeOptions.Background) { if (!ext.Equals("BCK")) { ErrorOnPSName = "Background procedure set location (directory) must end in .BCK"; rtnval = false; } } else if (this._ProcType == VEObject.ProcTypeOptions.Deviation) { if (!ext.Equals("DVT")) { ErrorOnPSName = "Deviation procedure set location (directory) must end in .DVT"; rtnval = false; } } else if (this._ProcType == VEObject.ProcTypeOptions.Slave) { if (ext.Length != 3 || !((ext.Substring(0,2)).Equals("SL")) || !System.Char.IsDigit(ext[2])) { ErrorOnPSName = "Slave procedure set location (directory) must end in .SL#\n\n Where # is a number from 1 to 9."; rtnval = false; } } } if (!rtnval) { MessageBox.Show(ErrorOnPSName,"Check Directory Name..."); } return rtnval; } // write out the TITLE file. private void WriteTextLineToFile(string fname, string title) { StreamWriter myWriter = new StreamWriter(fname,false); //overwrite if exist myWriter.Write(title); myWriter.Close(); } private void WriteExtraRevNumber() { vdb_Set vdbSet=new vdb_Set(_curDirectory+"\\"+_Location+"\\set.dbf"); DataRow rw = vdbSet.DB_Data.Tables[0].Rows[0]; rw["TITLE"] = ExtraRevNumber; vdbSet.DB_Data = rw.Table.DataSet; vdbSet=null; } public override bool Write() { // only write out title. if (changeTitle) _Title=tmpTitle; changeTitle=false; if (RmChgBarOnApp!=tmpRmChgBarOnApp) // flags change. { RmChgBarOnApp = tmpRmChgBarOnApp; INIFile inifile = new INIFile(); if (RmChgBarOnApp) inifile.WriteINIKeyValueStr("Set Options","RemoveChangeBarOnApproval","TRUE",_curDirectory+"\\"+_Location+"\\PROC.INI"); else inifile.WriteINIKeyValueStr("Set Options","RemoveChangeBarOnApproval","FALSE",_curDirectory+"\\"+_Location+"\\PROC.INI"); inifile = null; } string pathTitle = _curDirectory + "\\" + _Location + "\\TITLE"; WriteTextLineToFile(pathTitle,_Title); // check if hasExtraRevNumber, and if changed, write it to set file. if (this.hasExtraRevNumber&&(origExtraRevNumber!=ExtraRevNumber)) WriteExtraRevNumber(); return true; } static bool AddApplicabilityToMaster(string masterpath) { bool bUpdateSlavePROCINI = false; INIFile ProcINIfile = new INIFile(); string MasterName, MasterProcFile; string rtnbuf = ""; MasterName = masterpath.Substring(masterpath.LastIndexOf('\\')+1); MasterProcFile = masterpath + "\\PROC.INI"; rtnbuf = ProcINIfile.GetINIKeyValueStr("Applicability","masterdir","",15,MasterProcFile); // If Applicability section not yet there, add it if (rtnbuf.Equals("")) { ProcINIfile.WriteINIKeyValueStr("Applicability","masterdir",MasterName,MasterProcFile); } rtnbuf = ProcINIfile.GetINIKeyValueStr("Unit","Number","",15,MasterProcFile); // If Unit section not yet there, add it if (rtnbuf.Equals("")) { ProcINIfile.WriteINIKeyValueStr("Unit","Number","1,2",MasterProcFile); ProcINIfile.WriteINIKeyValueStr("Unit","Name","Unit 1,Unit 2",MasterProcFile); ProcINIfile.WriteINIKeyValueStr("Unit","Other Number","2,1",MasterProcFile); ProcINIfile.WriteINIKeyValueStr("Unit","Other Name","Unit 2,Unit 1",MasterProcFile); bUpdateSlavePROCINI = true; } return bUpdateSlavePROCINI; } static void AddApplicabilityToSlave(string slavepath) { INIFile ProcINIfile = new INIFile(); string SlaveProcFile; SlaveProcFile = slavepath + "\\PROC.INI"; // Preset to Slave one ProcINIfile.WriteINIKeyValueStr("Unit","Number","1",SlaveProcFile); ProcINIfile.WriteINIKeyValueStr("Unit","Name","Unit 1",SlaveProcFile); ProcINIfile.WriteINIKeyValueStr("Unit","Other Number","2",SlaveProcFile); ProcINIfile.WriteINIKeyValueStr("Unit","Other Name","Unit 2",SlaveProcFile); } // Create a new procedure set. public override bool SaveNew(string dummy) { // Determine the type of set. Validity of links has already been // checked. VEObject.ProcTypeOptions type = this._ProcType; // make the directory string dname = _curDirectory + "\\" + Location; DirectoryInfo di = new DirectoryInfo(dname); if (di.Exists) { MessageBox.Show("Directory already exists, cannot create this set.","General Error"); return false; } Cursor.Current = Cursors.WaitCursor; di.Create(); string prevdir = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(dname); // do database files now vdb_Set newset = new vdb_Set(dname); // if a slave set, copy files from master set if (type == VEObject.ProcTypeOptions.Slave) { CopyFileFrom(parentLink,"set.dbf"); // Add Applicability section to Master's PROC.INI file if that // information does not yet exist bool UpdateSlaveUnits = AddApplicabilityToMaster(parentLink); // Copy needed files from the master set // Note that if user manually entered data in the Advanced tab // (for PROC.INI information, that info will be used instead // of what is being copied from the master procedure set CopyFileFrom(parentLink,"proc.ini"); // If the master uses Automatic Continuous Action Summary sections // copy the CONTACT.INI file CopyFileFrom(parentLink,"ContAct.ini"); blnCopiedProcINI = true; if (UpdateSlaveUnits) AddApplicabilityToSlave(this.CurDirectory + "\\" + this.Location); CopyFileFrom(parentLink,"curset.dat"); CopyFileFrom(parentLink,"Tran.dbf"); CopyFileFrom(parentLink,"Tranfrom.ndx"); CopyFileFrom(parentLink,"Tranto.ndx"); CopyFileFrom(parentLink,"Usagero.dbf"); CopyFileFrom(parentLink,"Usagero.ndx"); CopyFileFrom(parentLink,"Usagroid.ndx"); } // Bug fix: B2006-042 // copy the SET.DBF file from the parent EOP set into the Enhanced // Document folder else if (type == VEObject.ProcTypeOptions.Deviation || type == VEObject.ProcTypeOptions.Background) { CopyFileFrom(parentLink,"set.dbf"); } else { newset.CreateTable("set"); } // do the SET Ext stuff if(hasExtensions) { vdb_SetExt newsetext = new vdb_SetExt(dname); newsetext.CreateTable("setext"); } // title file WriteTextLineToFile("TITLE",Title); if (type != VEObject.ProcTypeOptions.Slave) { // trans & Ro usage files vdb_TransUsage newtranusage = new vdb_TransUsage(dname); newtranusage.CreateTable("TRAN"); vdb_ROUsage newrousage = new vdb_ROUsage(dname); newrousage.CreateTable("USAGERO"); } // if this set has an extra rev number, write it out in first record, TITLE field. if (this.hasExtraRevNumber&&(ExtraRevNumber!=null&&ExtraRevNumber!=""))WriteExtraRevNumber(); if (type != VEObject.ProcTypeOptions.Slave) { // create the PROC.INI file. FileInfo fi = new FileInfo("PROC.INI"); FileStream fs = fi.Create(); fs.Close(); // create the current settings file (which sets the format) CurSet curset = new CurSet(""); // create will set name. bool success=curset.Create(usrRunTime); if (success==false) MessageBox.Show("Could not create a current settings file.","General Error"); else curset.Read(); if (type == VEObject.ProcTypeOptions.Background) curset.DefaultPlantFmt = "EBCK"; else if (type == VEObject.ProcTypeOptions.Deviation)curset.DefaultPlantFmt = "ESFDEV"; success = ChgDefSettings(); // Set up the links if this is a deviation or background. if (type != VEObject.ProcTypeOptions.Standard) success = SetParentLink(parentLink,type); success = SetGuideLink(guideLink); } // end not slave set // set up the RO directory path. If it's an enhanced document directory, // copy the RO.FST file from the parent (EOP.LNK), otherwise, get user // profile info. if (type == VEObject.ProcTypeOptions.Standard) { if(getROPath()!=null) { updateROValues(); setROPath(ROPath,dname); } } else // slave or enhanced doc, copy RO.FST from parent. CopyFileFrom(parentLink,"ro.fst"); // if the not Removing change bars (as set on the properties page) then // save this to the proc.ini file. Default is TRUE, so don't bother unless // it was set to FALSE. if (!RmChgBarOnApp) { INIFile inifile = new INIFile(); inifile.WriteINIKeyValueStr("Set Options","RemoveChangeBarOnApproval","FALSE",_curDirectory+"\\"+_Location+"\\PROC.INI"); inifile=null; } tmpRmChgBarOnApp=RmChgBarOnApp; // used for mods on propery page. // add the dummy nodes for zip files, procedures & lib docs. VEO_DummyZip zp = new VEO_DummyZip(usrRunTime, "Zip Files", dname); zp.parentObj=this; Children.Add(zp); zp.IsEmpty = true; zp.icon = zp.iconStates[(int)VEO_IconStates.Empty]; VEO_DummySet prc = new VEO_DummySet(usrRunTime, "Procedures",dname); prc.parentObj=this; prc.vdbSet = newset; Children.Add(prc); prc.icon = prc.iconStates[(int)VEO_IconStates.Empty]; prc.IsEmpty = true; VEO_DummyLibDoc ld = new VEO_DummyLibDoc(usrRunTime, "Library Documents",dname); ld.parentObj=this; Children.Add(ld); ld.icon = ld.iconStates[(int)VEO_IconStates.Empty]; ld.IsEmpty = true; _Title=Title; _Location=Location; changeTitle=false; changeLocation=false; Cursor.Current = Cursors.Default; icon = iconStates[(int)VEO_IconStates.Normal]; // set a security flag for this. Cases could be that there is no security in vesam, // that it has security in vesam, though it didn't exist for this user until now, // or the user could be super user. accessFlags=0L; int plntsecindx = usrRunTime.sec.GetPlantSecurityIndex(_curDirectory); bool hasSec = usrRunTime.sec.ProcSetHasSecurity(plntsecindx, dname); if (hasSec) accessFlags = usrRunTime.sec.GetProcSecurity(dname); // reset directory after adding the new procedure set directory. if (prevdir != Directory.GetCurrentDirectory()) Directory.SetCurrentDirectory(prevdir); MessageBox.Show("The VE-PROMS Security Access Module (VESAM) may need to be used to set permissions to access the new procedure set.","VE-PROMS Security Note"); return true; } private string getROPath() { return getROPath(true); } private string getROPath(bool domessage) { PrivateProfile ppCfg; string ropath; if (this.ROPath!=null) return ROPath; ppCfg = new PrivateProfile("PROC.INI"); ropath=ppCfg.Attr("RO Defaults","ROPATH"); if (ropath == null || ropath == "") ropath = "..\\RO"; if (Directory.Exists(ropath)) { ROPath = ropath; return ROPath; } // did not find a valid RO Path. Start with the current directory, // back up a level at a time to see if an RO Directory could be found. StringBuilder testPath = new StringBuilder(); testPath.Append(_curDirectory); int slash = testPath.ToString().LastIndexOf("\\"); while (slash > -1) { testPath.Remove(slash,testPath.Length-slash); testPath.Append("\\RO"); if (Directory.Exists(testPath.ToString())) { ROPath=testPath.ToString(); break; } testPath.Remove(slash,3); // remove appended \RO slash = testPath.ToString().LastIndexOf("\\"); } // if an RO directory not found, display an information message if(ROPath==null && domessage)MessageBox.Show("No Referenced Object Database could be found.","Referenced Objects Path Error"); return ROPath; } private bool setROPath(string pth, string dstpth) { INIFile inifile = new INIFile(); if (dstpth != null) // add destination path to PROC.INI file. { StringBuilder DestPath = new StringBuilder(132); DestPath.Append(dstpth); DestPath.Append("\\PROC.INI"); inifile.WriteINIKeyValueStr("RO Defaults","ROPATH",pth,DestPath.ToString()); } else inifile.WriteINIKeyValueStr("RO Defaults","ROPATH",pth,"PROC.INI"); ROPath = pth; return true; } private void CopyFileFrom(string from, string filename) { string frmfile; if (from == null) return; // create path to ro.fst in from directory. // current working directory is the enhanced doc directory frmfile = from + "\\" + filename; if (File.Exists(frmfile) == true) File.Copy(frmfile,filename,true); } public override bool updateROValues() { bool status = false; if (ROPath != null) // clear it to find correct path. ROPath = null; // check PROC.INI for ROPath. if (getROPath() != null) { string ROFstFile = ROPath + "\\Ro.fst"; string ROFstFileLocal = "Ro.fst"; if (File.Exists(ROFstFile) != true) { MessageBox.Show("Ro.fst does not exist. Create from the ROEditor.","RO.FST File Error"); status = false; } else { // check to see if the fst file should be updated, i.e. the one // in the RO directory is more recent. FileInfo fstfile = new FileInfo(ROFstFile); FileInfo fstfilelocal = new FileInfo(ROFstFileLocal); bool cpy = true; if (fstfilelocal.Exists == false) cpy = true; else if (fstfilelocal.LastWriteTime >fstfile.LastWriteTime) { System.Windows.Forms.DialogResult rslt; rslt = MessageBox.Show("The Ro.fst in this procedure set is newer compared to the RO directory.\n\nCopy from the RO directory?","VE-PROMS",MessageBoxButtons.YesNo); if (rslt == DialogResult.No) cpy = false; } else if (fstfilelocal.LastWriteTime == fstfile.LastWriteTime) { MessageBox.Show("Referenced Object values are current.","VE-PROMS"); cpy = false; } if (cpy == true) { File.Copy(ROFstFile,ROFstFileLocal,true); MessageBox.Show("Referenced Object values have been updated.","VE-PROMS"); } if (File.Exists("ro.fst") == false) { MessageBox.Show("Referenced Object Values were not successfully updated.","VE-PROMS Error"); status = false; } else status = true; } } return status; } /* ** This function will from all of the backup files created from the ** Clean Referenced Objects And Transition Usages function (VECLEAN) */ public void RestoreUsageAndProcFilesFromBadVECLEAN() { string[] FromStr = {"*.DBO","*.NDO","*.DTO"}; string[] ToStr = {".DBF",".NDX",".DBT"}; for (int i=0; i< 3; i++) { string[] dbfiles = Directory.GetFiles(FromStr[i]); foreach (string dbfile in dbfiles) { string oldname = dbfile; int indx = dbfile.IndexOf("."); if (indx>-1) { string nname = dbfile.Substring(0,indx); string newname = nname + ToStr[i]; File.Delete(newname); File.Move(oldname,newname); } } } } public void CheckForFailedCleanFunction() { // check for failed clean by looking for DBO and NDO files if( File.Exists("*.dbo") || File.Exists("*.ndo") || File.Exists("*.dto")) { MessageBox.Show("An error has occurred running the clean function.\nThe database files will be restored from the backup.", "VE-PROMS",MessageBoxButtons.OK); RestoreUsageAndProcFilesFromBadVECLEAN(); // retores from the DBO and NDO backup files } } public override void CleanTransitionsAndROsUsages(int clntype,string ProcName) { bool wasOpen = isOpen; //change directory before doing the Clean function if(!isOpen)Open(); StringBuilder buf = new StringBuilder(); buf.Append("CLEAN -NOPASS"); // if clntype is 2, then we are doing the Clean Selected (single) function if (clntype == 2) { buf.Append(" SELECT"); // if a procedure number was passed in, append to clean command if (ProcName != null || ProcName != "")buf.Append(" \""+ProcName+"\""); } // create a process & wait until it exits. Process myProcess = new Process(); myProcess.StartInfo.FileName = this.usrRunTime.ExeAdjust("@Wapprv.exe"); myProcess.StartInfo.Arguments = buf.ToString(); myProcess.Start(); myProcess.WaitForExit(); // check for failed clean by looking for DBO and NDO files CheckForFailedCleanFunction(); if(!wasOpen)Close(); } public override void DataIntegrityCheck(string ProcName) { bool wasOpen = isOpen; //change directory before doing the DataCheck function if(!isOpen)Open(); StringBuilder buf = new StringBuilder(); buf.Append("DATACHK -NOPASS"); buf.Append(" SELECT"); // if a procedure number was passed in, append to DataCheck command if (ProcName != null || ProcName != "")buf.Append(" \""+ProcName+"\""); // create a process & wait until it exits. Process myProcess = new Process(); myProcess.StartInfo.FileName = this.usrRunTime.ExeAdjust("@Wapprv.exe"); myProcess.StartInfo.Arguments = buf.ToString(); myProcess.Start(); myProcess.WaitForExit(); if(!wasOpen)Close(); } private bool SetupDateTimeStamp() { string newdate=null; string tempinit = DTI.Initials; if (tempinit == "super") DTI.Initials=" "; DTI.UpdateDateTimeInit(0); DTI.Initials=tempinit; bool goodfmt = false; while (!goodfmt) { frmReadWord rwdlg = new frmReadWord(DTI.MakeDate(DTI.DateTimeInit,false,false),"Enter Revision Date:"); rwdlg.ShowDialog(); if (rwdlg.DialogResult == DialogResult.OK) { newdate = rwdlg.ReadWordText; goodfmt= Char.IsDigit(newdate[0]) && Char.IsDigit(newdate[1]) && ((newdate[2]=='/') || (newdate[2]=='-')) && Char.IsDigit(newdate[3]) && Char.IsDigit(newdate[4]) && ((newdate[5]=='/') || (newdate[5]=='-')) && Char.IsDigit(newdate[6]) && Char.IsDigit(newdate[7]) && Char.IsDigit(newdate[8]) && Char.IsDigit(newdate[9]); } else return false; } // note that from above validity check, the year must be 4 chars... // reset datetimeinit to have the input date if (newdate!=null) { // use temp variable, can't write to index of DateTimeInit StringBuilder tmpdt = new StringBuilder(DTI.DateTimeInit); for (int i=0;i<4;i++) tmpdt[i]=newdate[i+6]; for (int i=3;i<5;i++) tmpdt[i+3]=newdate[i]; for (int i=0;i<2;i++) tmpdt[i+4]=newdate[i]; DTI.DateTimeInit = tmpdt.ToString(); } return true; } public void CopyAnyFileToApproved(string name, string ApproveName, string ApprovedPath) { if (!File.Exists(name)) return; string ApprovedFileName=null; int lindx = name.LastIndexOf("//"); if(lindx<0)lindx=0; string justname = name.Substring(lindx<0?0:lindx,name.Length-lindx); string apname = (ApproveName==null)?justname:ApproveName; if (ApprovedPath==null) ApprovedFileName = GetApprovedDirectory("\\") + apname; else ApprovedFileName = ApprovedPath+"\\"+apname; File.Copy(name,ApprovedFileName,true); } public string GetApprovedDirectory(string ExtraData) { int indx; string curdir = System.Environment.CurrentDirectory; if ((indx = curdir.LastIndexOf("\\")) >= 0) { string tmp = curdir.Substring(indx,curdir.Length-indx); if (tmp.ToUpper().Equals("TMPCHG"))return (".."+ExtraData); } return("APPROVED"+ExtraData); } public void UpdateSetDTI(bool doAll, DataRow dr) // do single - figure out what to pass in { if(doAll) { // Loop thru the procset and update the date/time/init info VEO_DummySet ds = (VEO_DummySet) Children[1]; DataTable tbl = ds.vdbSet.DB_Data.Tables[0]; bool isfirst = true; string dtstr = DTI.MakeDate(DTI.DateTimeInit,false,true).Substring(0,8); string tmstr = DTI.DateTimeInit.Substring(8,5); foreach (DataRow row in tbl.Rows) { if (isfirst) isfirst = false; else { row["DATE"]=dtstr; row["TIME"]=tmstr; row["INITIALS"]=" "; // approve all clears the init field } } ds.vdbSet.DB_Data = tbl.DataSet; } else { // only set it, it gets written by caller. dr["DATE"]=DTI.MakeDate(DTI.DateTimeInit,false,true).Substring(0,8); dr["TIME"]=DTI.DateTimeInit.Substring(8,5); dr["INITIALS"]=DTI.DateTimeInit.Substring(13,5); } } private void MakeApprovedProcs(VlnStatusMessage StatMsgWindow) { string aprdir = GetApprovedDirectory(""); if (aprdir.Equals("APPROVED")&&(!Directory.Exists(aprdir))) Directory.CreateDirectory(aprdir); CopyAnyFileToApproved("set.dbf",null,null); if (usrRunTime.SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_PROCCOMMENT_ON)>0 && File.Exists("setext.dbf")) { /*if (ApprovedPath==null || ApprovedPath =="") apprfilepath=GetApprovedDirectory("\\"),dbname,".DBF",NULL); else strcmb(apprfilepath,BuildPath(ApprovedPath,"\\"),dbname,".DBF",NULL); * * for(j=0;j0) { rtfdir = GetApprovedDirectory("\\RTFFILES"); if (!Directory.Exists(rtfdir)) Directory.CreateDirectory(rtfdir); } // for all procedures, copy all of the files over.... VEO_DummySet ds = (VEO_DummySet) this.Children[1]; if (ds.Children.Count==0) ds.Read(false); foreach (object oproc in ds.Children) { VEO_Proc proc = (VEO_Proc) oproc; if (File.Exists(_curDirectory+"\\"+_Location+"\\"+proc._Location+".dbf")) { StatMsgWindow.StatusMessage = "Approving " + proc._Prcnum; proc.Copy(_curDirectory+"\\"+_Location,aprdir,proc._Prcnum,proc._Location); } } DTI.SetDateTimeInit=DTI.DateTimeInit; StatMsgWindow.StatusMessage = "Copying support files"; // we don't use Password.Dat anymore - VESAM handles the password stuff. // CopyAnyFileToApproved("password.dat",null,null); if (File.Exists("datapage.fm1")) CopyAnyFileToApproved("datapage.fm1",null,null); if (File.Exists("curset.dat") && !File.Exists(GetApprovedDirectory("\\curset.dat"))) CopyAnyFileToApproved("curset.dat",null,null); CopyAnyFileToApproved("proc.ini",null,null); CopyAnyFileToApproved("set.ini",null,null); VEO_DummyLibDoc lds = (VEO_DummyLibDoc) Children[2]; if (lds.Children.Count>0) { StatMsgWindow.StatusMessage = "Copying library documents"; lds.Approve(_curDirectory+"\\"+_Location,aprdir); } // If they are using Automatic Continuous Action Summary Sections // copy the the ini file over to the approved as well. if (File.Exists("ContAct.INI")) CopyAnyFileToApproved("ContAct.INI",null,null); } private void MoveOutsideTransitions(VlnStatusMessage StatMsgWindow) { StatMsgWindow.StatusMessage = "Saving Approved Outside Transition Data"; // old code did a pack, but these files don't have database support, just copy // them over. CopyAnyFileToApproved("xtsetid.dbf",null,null); CopyAnyFileToApproved("xtsetid.ndx",null,null); CopyAnyFileToApproved("xtprocid.dbf",null,null); CopyAnyFileToApproved("xtpidset.ndx",null,null); CopyAnyFileToApproved("xtpidsnp.ndx",null,null); } private void MoveTransitions(VlnStatusMessage StatMsgWindow) { StatMsgWindow.StatusMessage = "Approving transition usage files"; vdb_TransUsage transusg = new vdb_TransUsage(_curDirectory+"\\"+_Location+"\\tran.dbf"); transusg.Pack(); transusg = null; // close the transusage connection CopyAnyFileToApproved("tran.dbf",null,null); CopyAnyFileToApproved("tranfrom.ndx",null,null); CopyAnyFileToApproved("tranto.ndx",null,null); // Now cleanup the 'OLDTO' fields, i.e. make them = TranTo field, i.e. // working draft 'TONUMBER'+'TOSEQUENCE' fields. The first query if for non-libdocs. // The second does libdocs. transusg = new vdb_TransUsage(_curDirectory+"\\"+_Location+"\\tran.dbf"); StringBuilder qry = new StringBuilder(); qry.Append("UPDATE TRAN SET TRAN.OLDTO = [TONUMBER] & Space(20-Len([TONUMBER])) & [TOSEQUENCE] & Space(12-Len([TOSEQUENCE])) "); qry.Append("WHERE tran.TOSEQUENCE IS NOT NULL"); bool success = transusg.UpdateUsing(qry.ToString()); if (!success) MessageBox.Show("Error When Updating Old Transition To fields","Approve All"); qry.Length=0; qry.Append("UPDATE TRAN SET TRAN.OLDTO = [TONUMBER] & Space(20-Len([TONUMBER])) "); qry.Append("WHERE tran.TOSEQUENCE IS NULL"); success = transusg.UpdateUsing(qry.ToString()); if (!success) MessageBox.Show("Error When Updating Old Transition To fields for library documents","Approve All"); transusg=null; } private void MoveROs(VlnStatusMessage StatMsgWindow) { StatMsgWindow.StatusMessage = "Approving referenced object usage files"; vdb_ROUsage rousg = new vdb_ROUsage(_curDirectory+"\\"+_Location+"\\usagero.dbf"); rousg.Pack(); rousg = null; this.CopyAnyFileToApproved("usagero.dbf",null,null); this.CopyAnyFileToApproved("usagero.ndx",null,null); this.CopyAnyFileToApproved("usagroid.ndx",null,null); this.CopyAnyFileToApproved("ro.fst",null,null); } public void MoveUserFormats(VlnStatusMessage StatMsgWindow) { CurSet cs = new CurSet(_curDirectory+"\\"+_Location+"\\curset.dat"); cs.Read(); FmtFile ff = new FmtFile(cs.DefaultPlantFmt+".fmt"); string [] sfis = Directory.GetFiles(".\\",cs.DefaultPlantFmt+".*"); if (sfis.Length>0)StatMsgWindow.StatusMessage = "Approving user format files"; foreach (string sfi in sfis) { FileInfo fi = new FileInfo(sfi); fi.CopyTo(this.GetApprovedDirectory("\\"+fi.Name),true); } } private void UpdateGraphicFiles(VlnStatusMessage StatMsgWindow) { StatMsgWindow.StatusMessage = "Approving graphic files from RO directory"; // ROFST ro = new ROFST(Directory.GetCurrentDirectory() + "\\ro.fst", usrRunTime); ROFST ro = new ROFST(Directory.GetCurrentDirectory() + "\\ro.fst"); ro.CopyImagesToApproved(this.GetApprovedDirectory(null),StatMsgWindow); ro.Close(); } private void CopyTempChgFiles(string from, string to, string fpattern) { DirectoryInfo difrom = new DirectoryInfo(from); DirectoryInfo dito = new DirectoryInfo(to); if (!dito.Exists) dito.Create(); FileInfo[] fis = difrom.GetFiles(fpattern); foreach (FileInfo fi in fis) { if (fi.Extension.ToUpper()!="PIX"&&fi.Name.ToUpper()!="B4APRVAL.ZIP") { fi.CopyTo(to+"\\"+fi.Name,true); // if this is title file, then the version text should state // 'Temporary Change Version' (either append or change the // 'Current Approved Version'). if (fi.Name.ToUpper()=="TITLE") { StreamReader myReader = new StreamReader(to+"\\"+fi.Name); string chgtitle = myReader.ReadLine(); myReader.Close(); int indx = chgtitle.IndexOf(" - Current Approved Version"); if (indx>-1) WriteTextLineToFile(to+"\\"+fi.Name,chgtitle.Substring(0,indx) + " - Temporary Change Version"); else WriteTextLineToFile(to+"\\"+fi.Name,chgtitle + " - Temporary Change Version"); } FileInfo fi_tmpchg = new FileInfo(to+"\\"+fi.Name); fi_tmpchg.LastWriteTime = fi.LastWriteTime; } } } private void CopyTempChg(VlnStatusMessage StatMsgWindow) { if (usrRunTime.SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_TEMPCHANGE_ON)>0) { StatMsgWindow.StatusMessage = "Updating the Temporary change directory ..."; CopyTempChgFiles("approved","approved\\tmpchg","*.*"); if (Directory.Exists("rtffiles")) CopyTempChgFiles("approved\\rtffiles","approved\\tmpchg\\rtffiles","*.*"); } } private void UpdateProcedureSetTitleFile(string ApprvPath) { if (File.Exists("Title")) { string appath = null; if (ApprvPath == null || ApprvPath=="") appath = GetApprovedDirectory("\\Title"); else appath = ApprvPath+"\\Title"; File.Copy("Title",appath,true); // Tack on Current Approved Version to the title in the approved directory StreamReader myReader = new StreamReader(appath); string chgtitle = myReader.ReadLine(); myReader.Close(); WriteTextLineToFile(appath,chgtitle + " - Current Approved Version"); } } private void ZipThis(string path, string ZipName) { CDZipNET dz = new CDZipNET(); dz.ZIPFile = path + "\\" + ZipName + ".zip"; StringBuilder sb = new StringBuilder(); // Zip up the RTFFILES directory if it exists string RTFFilesPath = path + "\\RTFFILES"; if (Directory.Exists(RTFFilesPath)) { sb.Append(path); sb.Append("\\*.* "); sb.Append(path); sb.Append("\\RTFFILES\\*.*"); } else { sb.Append(path); sb.Append("\\*.*"); } dz.RecurseFlag = false; dz.ItemList = sb.ToString(); dz.CompressionFactor = 9; // maxium compression dz.ExcludeFollowingFlag = true; dz.ExcludeFollowing = "*.lck process.dat"; dz.ActionDZ = CDZipNET.DZACTION.ZIP_ADD; } // this can be used to archiving of clean or approval. Approval zips approval // and tmpchg directories if they exist. private void Archive(string ZipName, bool approving) { // get the path to the working draft directory string cwd = Directory.GetCurrentDirectory(); VlnStatusMessage StatMsgWindow = new VlnStatusMessage("File Archival"); // zip the working draft directory StatMsgWindow.StatusMessage = "Zipping " + cwd; ZipThis(cwd, ZipName); if (approving && Directory.Exists("Approved")) { string CurApPath = cwd + "\\APPROVED"; // Zip the Approved directory StatMsgWindow.StatusMessage = "Zipping " + CurApPath; ZipThis(CurApPath, ZipName); // Zip the Temporary Change directory if (Directory.Exists("Approved\\TMPCHG")) { string TchgPath = CurApPath+"\\TMPCHG"; StatMsgWindow.StatusMessage = "Zipping " + TchgPath; ZipThis(TchgPath, ZipName); } } StatMsgWindow.Dispose(); } private bool NewOrModifiedGraphicFile(string Afname,string Wfname, string defExt) { bool rtnval = false; StringBuilder Agr_pathname = new StringBuilder(Afname.Length+5); StringBuilder Wgr_pathname = new StringBuilder(Wfname.Length+5); Agr_pathname.Append(Afname); Wgr_pathname.Append(Wfname); // if the file has an extension, just use it, otherwise use // the passed in default extension. Note that the default // extension is automatically set up when the RO.FST file // is read into the ROFST class if ((Afname.Length<4) || Afname[Afname.Length-4] != '.') { if (defExt[0] != '.') Agr_pathname.Append("."); Agr_pathname.Append(defExt); } if ((Wfname.Length<4) || Wfname[Wfname.Length-4] != '.') { if (defExt[0] != '.') Wgr_pathname.Append("."); Wgr_pathname.Append(defExt); } string AgrName = Agr_pathname.ToString(); string WgrName = Wgr_pathname.ToString(); rtnval = (!File.Exists(AgrName)); if (!rtnval) { // The graphic file exists in Approved directory. // See if the RO directory has a newer graphics file. rtnval = (File.GetLastWriteTime(WgrName) > File.GetLastWriteTime(AgrName)); } return rtnval; } // private bool GraphicsFileNotInApproved(string fname, string defExt) // { // StringBuilder gr_pathname = new StringBuilder(fname.Length + 5); // gr_pathname.Append(fname); //// // if the file has an extension, just use it, otherwise get default //// // extension. This is in veproms.ini or default to .tif. //// int indx = fname.LastIndexOf("."); //// if (indx<0) // // // if the file has an extension, just use it, otherwise use // // the passed in default extension. Note that the default // // extension is automatically set up when the RO.FST file // // is read into the ROFST class // if ((fname.Length<4) || fname[fname.Length-4] != '.') // { //// PrivateProfile pINI; //// string fExt; //// pINI = new PrivateProfile(usrRunTime.ExeAdjust("~veproms.ini")); //// fExt=pINI.Attr("Graphics","defaultext"); //// if (fExt == null||fExt=="") fExt=".TIF"; //// pINI=null; //// if (fExt.Substring(0,1)!=".") gr_pathname.Append("."); //// gr_pathname.Append(fExt); // if (defExt[0] != '.') gr_pathname.Append("."); // gr_pathname.Append(defExt); // } // return (!File.Exists(gr_pathname.ToString())); // } // // Verify we have a valid RO directory path private bool CheckROPathForApprove() { bool rtnval = true; StringBuilder sbWarning = new StringBuilder(); // If Referenced Objects are being used, // then see if the RO directory exists B2005-038 vdb_ROUsage rousg=null; DataSet ROUsageDataSet=null; // Open the RO Usage file in the working draft and see if there // are any records in it. try { rousg = new vdb_ROUsage(_curDirectory+"\\"+_Location+"\\usagero.dbf"); ROUsageDataSet = rousg.GetSortedByROID(""); } catch (Exception e) { MessageBox.Show("Could not read RO Usages, cannot approve. " + e.Message,"Approval Error"); rousg=null; ROUsageDataSet=null; return false; // don't allow approval } DataTable roTbl = ROUsageDataSet.Tables[0]; rtnval = (roTbl.Rows.Count > 0); rousg=null; ROUsageDataSet=null; if (!rtnval) return true; // ROs are not used, no need to check for RO directory // At this point we know that we use RO's so now check to see if // the RO directory exists return CheckROpathAndFST(); } // This function is called after we verify that Referenced Objects are being // used in the working draft (there are records in the ROUSAGE.DBF file) private bool CheckROpathAndFST() { bool rtnval = true; bool wdROfstExists; bool doWarning; StringBuilder sbMsg = new StringBuilder(); string rpath = this.getROPath(false); if (rpath == null || rpath == "") { // Cannot find an RO Directory sbMsg.Append("Cannot find the Referenced Objects folder: "); sbMsg.Append(rpath); sbMsg.Append("\n\nReferenced Object usages cannot be validated without access to the RO database folder."); sbMsg.Append("\n\n * Verify the RO Path in the PROC.INI file."); sbMsg.Append("\n\n * Verify the RO folder does exist."); MessageBox.Show(sbMsg.ToString(),"Check Referenced Objects Settings"); return false; // cancel approval } // Check to see if RO.FST file exists in working draft wdROfstExists = File.Exists(_curDirectory+"\\"+_Location+"\\ro.fst"); // Check to see if the RO.FST file in the working draft is older or newer // than the one in the RO directory if (wdROfstExists) { DateTime WdDateTime = File.GetLastWriteTime(_curDirectory+"\\"+_Location+"\\ro.fst"); DateTime RoDateTime = File.GetLastWriteTime(rpath + "\\ro.fst"); switch (DateTime.Compare(WdDateTime,RoDateTime)) { case 1: doWarning = true; sbMsg.Append("The Working Draft RO.FST file is Newer than the one last generated"); sbMsg.Append("\nfrom the RO database."); break; case -1: doWarning = true; sbMsg.Append("The Working Draft RO.FST file is Older than the one last generated"); sbMsg.Append("\nfrom the RO database."); break; default: doWarning = false; break; } if (doWarning) { sbMsg.Append("\n\nPlease verify that \""); sbMsg.Append(rpath); sbMsg.Append("\" is the correct RO database folder and"); sbMsg.Append("\ncheck to see if the RO.FST needs updated in the Working Draft."); sbMsg.Append("\n\n\n\nDo You Want To Continue With The Approval Anyway?"); DialogResult yn = MessageBox.Show(sbMsg.ToString(),"Check Referenced Objects Settings",MessageBoxButtons.YesNo); rtnval = yn.Equals(DialogResult.Yes); return rtnval; } } if (!wdROfstExists) { //if the working draft does not have a RO.FST file, don't allow approve sbMsg.Append("The working draft does not have an RO.FST file."); sbMsg.Append("\n\nReferenced Object usages cannot be validated."); sbMsg.Append("\n\n * Verify the RO Path in the PROC.INI file."); sbMsg.Append("\n\n * Run the Update Referenced Objects tool"); MessageBox.Show(sbMsg.ToString(),"Check Referenced Objects Settings"); return false; // cancel approval } return true; // fell through the checks, assume it's O.K. to continue } // FindModifiedROs determines which ROs, if any, are different between the working // draft & the approved version of the ro.fst files. It only looks at those ROs // that are used in the working draft version of the document, i.e. it compares // the ro.fst data for those ROs listed in the usage file. private bool FindModifiedROs(ArrayList ModROs, VlnStatusMessage StatMsgWindow) { vdb_ROUsage rousg=null; DataSet ROUsageDataSet=null; //Loop through all of the usages. try { rousg = new vdb_ROUsage(_curDirectory+"\\"+_Location+"\\usagero.dbf"); ROUsageDataSet = rousg.GetSortedByROID(""); } catch (Exception e) { MessageBox.Show("Could not read RO Usages, cannot approve. " + e.Message,"Approval Error"); rousg=null; ROUsageDataSet=null; return false; } DataTable roTbl = ROUsageDataSet.Tables[0]; if (roTbl.Rows.Count == 0) return true; // no data // if (roTbl.Rows.Count>0) StatMsgWindow.StatusMessage = "Finding Modified Referenced Objects"; // See if the RO.FST file exists in the working draft. At this point // we have established that ROs are being used and there should be a // RO.FST file in the working draft. Also see if the RO folder exists. // It's needed to check changes to graphic files. // B2005-038 if (!CheckROpathAndFST()) return false; // Open the RO.FST files so that we can compare ro values ROFST WD_ROfst = new ROFST(_curDirectory+"\\"+_Location+"\\ro.fst"); ROFST App_ROfst = new ROFST(_curDirectory+"\\"+_Location+"\\approved\\ro.fst"); string lastROID = null; VlnStatusBar FndModROsStatWindow = new VlnStatusBar("Processing ROs"); FndModROsStatWindow.BarMax = roTbl.Rows.Count; FndModROsStatWindow.BarStepValue = 1; FndModROsStatWindow.BarValue = 0; FndModROsStatWindow.StatMsg = "Finding Modified Referenced Objects"; foreach (DataRow row in roTbl.Rows) { FndModROsStatWindow.PerformStep(); string thisROID = row["ROID"].ToString(); // we want to always have "0000" at the end of the ROID // so that we get all possible return options for // conditional RO's thisROID = thisROID.Substring(0,12)+"0000"; // byte ff = 0xff; // string instance = row["INSTANCE"].ToString(); // if(System.Char.IsWhiteSpace(instance[0])) if(thisROID==null || thisROID=="" || System.Char.IsWhiteSpace(thisROID[0])) { continue; } if (thisROID != lastROID) { lastROID = thisROID; string usagePnum = row["NUMBER"].ToString(); string wd_val = WD_ROfst.GetRO(thisROID,usagePnum); string a_val = App_ROfst.GetRO(thisROID,usagePnum); ROFST.ROTypes rotype = WD_ROfst.GetROType(thisROID); if (rotype == ROFST.ROTypes.Figure) // image { int nline = wd_val.IndexOf("\n"); if (nline>0) { string gr_fname = this._curDirectory + "\\" + this._Location + "\\" + GetApprovedDirectory("\\") + wd_val.Substring(0,nline); string wd_fname = this.getROPath() + "\\" + wd_val.Substring(0,nline); if (wd_val!=a_val || NewOrModifiedGraphicFile(gr_fname,wd_fname,WD_ROfst.DefaultGraphicFileExt)) // if (wd_val!=a_val || GraphicsFileNotInApproved(gr_fname,WD_ROfst.DefaultGraphicFileExt)) { ModRO mro = new ModRO(thisROID,true,gr_fname,null); ModROs.Add(mro); } } } else { if (wd_val != a_val) { ModRO mro = null; if (rotype == ROFST.ROTypes.Table) mro = new ModRO(thisROID, false, "TABLE", "TABLE"); else mro = new ModRO(thisROID, false, wd_val, a_val); ModROs.Add(mro); } } } } FndModROsStatWindow.Dispose(); rousg=null; ROUsageDataSet=null; WD_ROfst.Close(); App_ROfst.Close(); return true; } // determine if the input library document has any Modified Ro references private bool RoRef(string libname, ArrayList ModROs, ArrayList al) { int roref=0; int i = libname.IndexOf("."); string fname; if (i>0) fname = libname.Substring(0,i); else fname = libname; if ((roref=Usages.CheckRoReferences(this, _curDirectory+"\\"+_Location, al, ModROs, fname))<=0) { return false; } return true; } // Determine, based on date/time stamp, whether the Library Document // file was modified between the working draft & approved. private void LookForModifiedLibraryDoc(ArrayList ModLibDocs, ArrayList ModROs, ArrayList al, string libname) { // Use status codes for later file copying of library documents. // Stat 0 - No Change // Stat 1 - Copy working draft file to approved // Stat 2 - Copy RTFFILES file to approved // Stat 3 - Copy working draft file to approved and RTF int stat=0; DateTime wd=DateTime.Now; // default to now, but reset if file exists. DateTime wd_rtfdir=DateTime.Now; DateTime ap=DateTime.Now; DateTime ap_rtfdir=DateTime.Now; if (File.Exists(libname))wd = File.GetLastWriteTime(libname); if (File.Exists("RTFFILES\\"+libname))wd_rtfdir = File.GetLastWriteTime("RTFFILES\\"+libname); string apdir = GetApprovedDirectory(""); if (File.Exists(apdir+"\\"+libname))ap = File.GetLastWriteTime(apdir+"\\"+libname); if (File.Exists(apdir+"\\RTFFILES\\"+libname))ap_rtfdir = File.GetLastWriteTime(apdir+"\\RTFFILES\\"+libname); // now see if there are any referenced objects in this library document // that have a modified RO - if so, copy those too. bool roStat = RoRef(libname, ModROs, al); // if approved directory has RTFFILES subdirectory with this libdoc... if (File.Exists(apdir+"\\RTFFILES\\"+libname)) { // if working draft has RTFFiles subdirectory with this libdoc if (File.Exists("RTFFILES\\"+libname)) { // if working draft is newer or contains a modified RO if (roStat || (wd_rtfdir>ap_rtfdir)) stat=2; } else // if working draft does NOT have libdoc file stat = 3; } // the approved directory does not have RTFFILES directory, but has the // library document in the APPROVED directory. else if (File.Exists(apdir+"\\"+libname)) { // if the working draft has the library document in the RTFFILES directory if (File.Exists("RTFFILES\\"+libname)) { // if working draft library document is newer or contains modified ro if (roStat || (wd_rtfdir > ap)) stat=2; // if the working draft version is newer or contains a modified RO } else { if (roStat || (File.Exists(libname) && wd>ap)) stat = 1; } } // else there is no library document in approved at all, add it. else { if (File.Exists("RTFFILES\\"+libname)) stat=2; else stat=1; } if (stat!=0) { // see if filename is in the list. If not add it, otherwise it's a duplicate. for (int i=0;i 0) { App_ROfst.processAppUpdFile(AppUpdtmp,WD_ROfst.numDatabases>App_ROfst.numDatabases?WD_ROfst.numDatabases:App_ROfst.numDatabases); App_ROfst.CreateMergedFSTFile(NewFST); if (File.Exists(NewFST)) { string ROFST = this.GetApprovedDirectory("\\RO.FST"); string ROFSTbck = this.GetApprovedDirectory("\\RO.BAK"); File.Copy(ROFST,ROFSTbck,true); File.Copy(NewFST,ROFST,true); File.Delete(NewFST); } } if (File.Exists(AppUpdtmp))File.Delete(AppUpdtmp); WD_ROfst.Close(); App_ROfst.Close(); } private bool SetupProcessInd(ArrayList ModROs, ArrayList ModLibDocs, ArrayList al, VlnStatusMessage StatMsgWindow) { bool success; success = FindModifiedROs(ModROs, StatMsgWindow); if (!success)return false; success = FindModifiedLibDocs(ModLibDocs, ModROs, al, StatMsgWindow); if (!success) return false; return true; } public bool ProcessInd(ArrayList al, int indx, ArrayList ModROs, ArrayList ModLibDocs) { bool success=true; // process the procedure in the list at 'indx'. First mark it as checked. Then // see if it has any RO References that have changed & if so, add any other // procedures to the list that use the changed ROs. Then do the same for // library documents & transitions (to/from). AppIndItem appitm = (AppIndItem) al[indx]; if ( ModROs.Count>0) { int roref = Usages.CheckRoReferences(this, _curDirectory+"\\"+_Location, al, ModROs,appitm.Proc._Prcnum); success=roref>-1; } if (!success) return false; if (ModLibDocs.Count>0)success = appitm.Proc.CheckLibraryDocReferences(al, indx, ModLibDocs, ModROs); if (!success)return false; success=appitm.Proc.CheckTransitionReferences(al); return success; } private bool ApproveInd(ArrayList Procs) { string tempinit = DTI.Initials; if (tempinit == "super") DTI.Initials=" "; DTI.UpdateDateTimeInit(0); DTI.Initials=tempinit; // Don't allow approval unless we have a valid path to the RO directory /** BUG FIX B2005-038 if (!CheckROPathForApprove()) - done in FindModifiedROs() new return false; **/ VlnStatusMessage StatMsgWindow = new VlnStatusMessage("Approving Selected Procedures"); StatMsgWindow.StatusMessage = "Preparing for Approval"; // if children are not loaded, load them here... VEO_DummySet ds = (VEO_DummySet) this.Children[1]; if (ds.Children.Count==0) ds.Read(false); // find dependencies for those initially selected. ArrayList ModROs = new ArrayList(); ArrayList ModLibDocs = new ArrayList(); ArrayList AppProcess = new ArrayList(); if (!SetupProcessInd(ModROs,ModLibDocs,AppProcess,StatMsgWindow)) { StatMsgWindow.Dispose(); return false; } // The selected procedures in the passed in list should be put in the // processing list of AppIndItems. Then for each item in this list, // check to see if conflicts require other procedures to be approved. // If a conflict is found, it is added the list of conflicts for the item // and the procedure found with the conflict is added to the AppIndItems // list, so that it getes checked too. After all items in the AppIndItems // list are processed, bring up the dialog with the list of procedures that // must be approved. Allow the user to add other procedures, to resolve/edit // conflicts, etc. StatMsgWindow.StatusMessage = "Looking for Dependencies..."; foreach (Object obj in Procs) { AppIndItem aii= new AppIndItem((VEO_Proc)obj); AppProcess.Add(aii); } // while there are items in the list to check, keep looking // for conflicts. Assume that there is at least one item in the // list that hasn't been checked or it wouldn't have gotten to here. int indx=0; if (AppProcess.Count<1) indx=-1; while (indx>=0) { AppIndItem CurItem = (AppIndItem) AppProcess[indx]; StatMsgWindow.StatusMessage = "Checking " + CurItem.Proc._Prcnum; ProcessInd(AppProcess, indx, ModROs, ModLibDocs); CurItem.Checked=true; indx = -1; for (int i=0;i0) { string rtfdir = ApprovedPath + "\\RTFFILES"; if (!Directory.Exists(rtfdir)) Directory.CreateDirectory(rtfdir); } fis=null; } string appath=null; if (ApprovedPath==null||ApprovedPath=="") appath = GetApprovedDirectory(""); else appath = ApprovedPath + ""; // If the PROC.INI file in the working draft is newer or older than the // approved, ask the user if this file should be copied to the approved. INIfileApproveCheck("PROC.INI",appath,"Proc.ini"); // If the Continuous Action Summary ini (CONTACT.INI) file in the working // draft is newer or older than the approved, ask the user if this file // should be copied to the approved. INIfileApproveCheck("CONTACT.INI",appath,"Continuous Action Summary ini"); // See if this set has long procedure titles. This was a format flag, but // format flags are temporarily being stored in the proc.ini file. This is // used in the UpdateSetFile method, but just read it once & reuse. using (StreamWriter sw = new StreamWriter("Approval.log", true)) { sw.Write("APPROVE SELECTED: Approving selected procedures on "); sw.Write(DateTime.Now); sw.WriteLine(" performed by " + DTI.Initials); sw.WriteLine(" "); foreach (AppIndItem ai in AppProcess) { StatMsgWindow.StatusMessage = "Approving Procedure to " + appath + "\\" +ai.Proc._Prcnum; // For the procedure number, see if it exists in the approved set. If // not, there is either a new procedure or a modified procedure number. // Both cases require a new procedure database fileset to be created. string ApProcFile = null; string ApProcNum = null; ai.Proc.GetApProcNumAndFile(appath, ref ApProcFile, ref ApProcNum); sw.WriteLine(" Approved " + ApProcNum); ai.Proc.Copy(Directory.GetCurrentDirectory(), appath, ApProcNum, ApProcFile); ai.Proc.UpdateSetFile(appath, ApProcNum, ApProcFile); StatMsgWindow.StatusMessage = "Fixing Transition References for "+ai.Proc._Prcnum; ai.Proc.FixTransitionReferences(appath, ApProcNum); StatMsgWindow.StatusMessage = "Fixing RO Usages for "+ai.Proc._Prcnum; Usages.FixROUsages(Directory.GetCurrentDirectory(), appath, ApProcNum, ai.Proc._Prcnum); } sw.WriteLine(" "); } UpdateProcedureSetTitleFile(ApprovedPath); } private void CopyLibDocToApproved(string fname, string ApprovedPath, int stat) { string buff=fname; if (stat==2) { // Create approved rtf directory. if (!Directory.Exists(ApprovedPath+"\\RTFFILES"))Directory.CreateDirectory(ApprovedPath+"\\RTFFILES"); // create rtf files name buff = "RTFFILES\\" + fname; } else if (stat==3) { // approved rtf version. if (Exists(ApprovedPath+"\\RTFFILES\\"+fname))File.Delete(ApprovedPath+"\\RTFFILES\\"+fname); buff=fname; } CopyAnyFileToApproved(buff, null, ApprovedPath); } private void MoveChangedDocuments(string ApprovedPath, ArrayList ModLibDocs, VlnStatusMessage StatMsgWindow) { int cnt = ModLibDocs.Count; for (int i = ModLibDocs.Count;i>0;i--) { ModLibDoc ld = (ModLibDoc) ModLibDocs[i-1]; if (ld.DocPages!=0) { StatMsgWindow.StatusMessage = "Moving Library Document "+ld.LibFile; CopyLibDocToApproved(ld.LibFile,ApprovedPath,ld.status); string lbname = ld.LibFile.Substring(0,8); // don't need extension, i.e. .LIB Usages.FixROUsages(Directory.GetCurrentDirectory(), ApprovedPath, lbname, lbname); } } } public void DoTheApproval(ArrayList AppProcess, ArrayList ModROs, ArrayList ModLibDocs) { bool hasTempChange = (Directory.Exists("APPROVED\\TMPCHG") && (usrRunTime.SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_TEMPCHANGE_ON)>0) && (GetApprovedDirectory("")=="APPROVED")); string ApprovedPath = GetApprovedDirectory(""); VlnStatusMessage StatMsgWindow = new VlnStatusMessage("Do The Approval"); MoveApprovedProcedures(AppProcess, ApprovedPath, StatMsgWindow); if (hasTempChange) MoveApprovedProcedures(AppProcess, "APPROVED\\TMPCHG", StatMsgWindow); SaveModifiedROs(ApprovedPath, ModROs, StatMsgWindow); if (hasTempChange) SaveModifiedROs("APPROVED\\TMPCHG", ModROs, StatMsgWindow); MoveChangedDocuments(ApprovedPath, ModLibDocs, StatMsgWindow); if (hasTempChange) MoveChangedDocuments("APPROVED\\TMPCHG", ModLibDocs, StatMsgWindow); // If the temporary change directory does not exist and not in the // temporary change directory, create the temporary change directory // and copy the files to it from the approved directory if (ApprovedPath == "APPROVED" && hasTempChange && !Directory.Exists("APPROVED\\TMPCHG")) CopyTempChg(StatMsgWindow); StatMsgWindow.Dispose(); MessageBox.Show("Procedure(s) has been approved.","Approval Complete"); } private void ApproveAll() { bool approveflag = false; string tempinit = DTI.Initials; if (tempinit == "super") DTI.Initials=" "; DTI.UpdateDateTimeInit(0); DTI.Initials=tempinit; // Don't allow approval unless we have a valid path to the RO directory if (!CheckROPathForApprove()) return; DialogResult rslt = MessageBox.Show("About to Approve All of the Procedures in This Set. Continue With The Approval?","Approve All Procedures",MessageBoxButtons.YesNo); if (rslt == DialogResult.No) return; rslt = MessageBox.Show("Do you want to save the current data to an archive file before proceeding with the Approval?","Archive Data",MessageBoxButtons.YesNo); if (rslt == DialogResult.Yes) { string tmp = "B4APRVAL" + DateTime.Now.ToString("s").Replace(":","-"); Archive(tmp,true); } if (RmChgBarOnApp) { rslt = MessageBox.Show("Remove Change Bars from Working Draft?","Approve All Procedures",MessageBoxButtons.YesNo); if (rslt==DialogResult.No) RmChgBarOnApp=tmpRmChgBarOnApp=false; } else { rslt = MessageBox.Show("Keep Change Bars in Working Draft?","Approve All Procedures",MessageBoxButtons.YesNo); if (rslt==DialogResult.No) RmChgBarOnApp=tmpRmChgBarOnApp=true; } if (!RmChgBarOnApp || SetupDateTimeStamp()) { long spfree = DirSpace.Free(); if( File.Exists(GetApprovedDirectory("\\set.dbf")) && (spfree > 200000L) ) approveflag = true; long tmp = DirSpace.Get(Environment.CurrentDirectory); if( !approveflag && !(spfree > DirSpace.Get(Environment.CurrentDirectory)) ) { MessageBox.Show("Insufficient Disk Space for Approval!","General Approval Error"); return; } VlnStatusMessage StatMsgWindow = new VlnStatusMessage("Approving All Procedures"); StatMsgWindow.StatusMessage = "Preparing for Approval"; using (StreamWriter sw = new StreamWriter("Approval.log", true)) { sw.Write("APPROVE ALL: on "); sw.Write(DateTime.Now); sw.WriteLine(" performed by " + DTI.Initials); sw.WriteLine(" "); } MakeApprovedProcs(StatMsgWindow); if(File.Exists("xtsetid.dbf"))MoveOutsideTransitions(StatMsgWindow); MoveTransitions(StatMsgWindow); MoveROs(StatMsgWindow); UpdateGraphicFiles(StatMsgWindow); MoveUserFormats(StatMsgWindow); UpdateProcedureSetTitleFile(null); CopyTempChg(StatMsgWindow); StatMsgWindow.Dispose(); MessageBox.Show("Procedure Set has been approved.","Approval Complete"); } } public override void ApproveProcedures(int ApproveType, ArrayList procs) { // before doing anything - verify that no one is 'connected' to the // approved directory. do this by getting approved directory & // using its object, see if there is an open connection. Make a lock // in the approved set. If this cannot be done - then can't approve. bool needtoUnlock = false; bool needtoDisConnect = false; VEO_ProcSet lckapp=null; if (isSetApproved && usrRunTime.InMultiUserMode) { bool proceed = true; VEO_ProcSet ps = null; VEO_Plant pl = (VEO_Plant) this.parentObj; for (int i=0; i< pl.Children.Count; i++) { VEO_ProcSet aps = (VEO_ProcSet) pl.Children[i]; string dir = aps._curDirectory.ToUpper()+"\\"+aps._Location.ToUpper(); if (dir==_curDirectory.ToUpper()+"\\"+_Location.ToUpper()+"\\APPROVED") { ps = aps; break; } } if (ps!=null) { // if there are active users in the approved directory approval // cannot continue, put up message and return. Otherwise lock // the approved directory. if (ps.Connection == null) { needtoDisConnect=true; ps.LoadLockInfo(); ps.Connection = new VEConnection(ps.Lock, ps.usrRunTime); if (ps.Lock.LockStatus==VENetwork.Status.LockedByOther)proceed=false; } if (proceed)ps.Connection.Enter(false); if (proceed && ps.Connection.HasActiveUsers())proceed=false; if (proceed && !ps.amILockedByMe()) { bool success = ps.Lock.CreateLock(ps.Connection, false); if (!success) proceed=false; else { needtoUnlock=true; lckapp = ps; } } } if (ps==null||!proceed) { MessageBox.Show("Could not connect/lock the associated approval directory.\n Either another user is viewing the data or has a lock on the data.","VE-PROMS"); if (ps != null) ps.Connection.MonitorUsers((int)ps.Lock.LockType-1); ps.Connection.Exit(); if (needtoDisConnect)ps.Connection=null; return; } } bool wasOpen = isOpen; // change directory before doing functions if (!isOpen)Open(); switch (ApproveType) { case 0: // approve the entire set ApproveAll(); break; case 1: ApproveInd(procs); break; } if(!wasOpen)Close(); if (needtoUnlock)lckapp.Lock.UnLock(false); // if (needtoDisConnect) // Bug Fix: B2006-033 // Had a lock at VEplant level, thus lckapp was never set if (needtoDisConnect && lckapp != null) { lckapp.Connection.Exit(); lckapp.Connection=null; } } public override bool Delete() { try { bool tst=false; if ((tst=Open())!=true) return false; // if this is an enhanced document, remove the bck.lnk or dvt.lnk // and erg.lnk for dev, files in the parentLink directory. if (_ProcType == VEObject.ProcTypeOptions.Background || _ProcType == VEObject.ProcTypeOptions.Deviation) { if (parentLink==null) // load in the link. GetParentLink(); string lnk = parentLink; if (lnk != null || lnk != "") { string dellnk; if(this._ProcType != VEObject.ProcTypeOptions.Background) dellnk = lnk+"\\DVT.LNK"; else dellnk = lnk+"\\BCK.LNK"; File.Delete(dellnk); } string tmppath = CurDirectory+"\\"+_Location+"\\eop.lnk"; if (File.Exists(tmppath)) File.Delete(tmppath); if (_ProcType == VEObject.ProcTypeOptions.Deviation) { if (guideLink==null) GetGuideLink(); tmppath = this.CurDirectory+"\\"+_Location+"\\ERG.LNK"; File.Delete(tmppath); } } // Now delete the document directory. Close first, which closes // any open multi-user connections. Close(); this.Children.Clear(); string cwd = Directory.GetCurrentDirectory(); Directory.Delete(CurDirectory+"\\"+_Location,true); } catch (Exception e) { // string cwd = Directory.GetCurrentDirectory(); MessageBox.Show(e.Message,"Error Deleting"); DirectoryInfo di = new DirectoryInfo(CurDirectory+"\\"+_Location); di.Delete(true); return false; } if (Directory.Exists(CurDirectory+"\\"+_Location)) return false; VEO_Plant plnt = (VEO_Plant) parentObj; if (plnt.Children.Count <=1) { plnt.icon = plnt.iconStates[(int)VEO_IconStates.Empty]; plnt.IsEmpty=true; } return true; } public override bool Read(bool ChkForChldOnly) { if (Lock.LockStatus == VENetwork.Status.LockedByOther) return false; string path = _curDirectory + "\\" + _Location; // for each procset, get its contents, i.e. zip files, whether there's // a set.dbf (shows that there ar]e procedure files), StringBuilder fname = new StringBuilder(); fname.Append(path); fname.Append("\\SOURCE.ZIP"); FileInfo source = new FileInfo(fname.ToString()); if (source.Exists) isArchived=true; VEO_DummyZip zp = new VEO_DummyZip(usrRunTime,"Zip Files", _curDirectory+"\\"+_Location); zp.parentObj=this; Children.Add(zp); // if !isArchived, check for any other zip files, or make the icon empty DirectoryInfo di = new DirectoryInfo(path); FileInfo [] fi = di.GetFiles("*.ZIP"); if (fi.Length<=0) { zp.IsEmpty = true; zp.icon=zp.iconStates[(int)VEO_IconStates.Empty]; } di = null; fi = null; // now check for procedures in the set fname.Remove(fname.Length-11,11); fname.Append("\\SET.DBF"); source = new FileInfo(fname.ToString()); if (source.Exists) { IsEmpty=false; setExists = true; if (this.hasExtraRevNumber) { vdb_Set vdbSet=new vdb_Set(_curDirectory+"\\"+_Location+"\\set.dbf"); DataRow rw = vdbSet.DB_Data.Tables[0].Rows[0]; ExtraRevNumber = rw["TITLE"].ToString(); origExtraRevNumber=ExtraRevNumber; vdbSet=null; } } else IsEmpty=true; VEO_DummySet prc = new VEO_DummySet(usrRunTime,"Procedures",_curDirectory+"\\"+_Location); if (IsEmpty) prc.icon = prc.iconStates[(int)VEO_IconStates.Empty]; prc.parentObj=this; // Update Enhanced and Slave Set files if (!ChkForChldOnly) prc.SyncSetFile(); // Update the Slave's Continue Actions Summary ini (ContAct.INI) file if (!ChkForChldOnly) prc.UpdateContActINI(); Children.Add(prc); // check both rtffiles & procs directory for library documents di = new DirectoryInfo(path+"\\RTFFILES"); if (di.Exists) { FileInfo[] fiArr = di.GetFiles("DOC_*.LIB"); if (fiArr.Length>0) hasLibDocs = true; } if (!hasLibDocs) { di = new DirectoryInfo(path); FileInfo[] fiArr = di.GetFiles("DOC_*.LIB"); if (fiArr.Length>0) hasLibDocs = true; } VEO_DummyLibDoc ld = new VEO_DummyLibDoc(usrRunTime,"Library Documents",_curDirectory+"\\"+_Location); ld.parentObj=this; if (!hasLibDocs) { ld.icon = ld.iconStates[(int)VEO_IconStates.Empty]; ld.IsEmpty=true; } Children.Add(ld); return true; } public override bool CollapseSibling() { if (!usrRunTime.InMultiUserMode) return false; return true; } public override bool mnuAllowLckDB() { if (!usrRunTime.InMultiUserMode) return false; //if (amILockedByMe()) return false; // if I'm already locked, don't allow it if ((accessFlags&Security.LOCKPROC)==Security.LOCKPROC && Lock.LockStatus==VENetwork.Status.NoLock) return true; return false; } public override bool mnuAllowUnlckDB() { if (!usrRunTime.InMultiUserMode) return false; if ((accessFlags&Security.LOCKPROC)==Security.LOCKPROC&&(Lock.LockStatus==VENetwork.Status.Locked|| Lock.LockStatus==VENetwork.Status.LockPending)) return true; return false; } public override bool mnuAllowUpdRO() { if (isApproved||IsEmpty||isTempChange) return false; if (amILockedByMe()==false) return false; return true; } public override bool mnuAllowClean() { if (isApproved||IsEmpty) return false; if (Lock.LockStatus!=VENetwork.Status.Locked)return false; if (amILockedByMe()==false) return false; if ((accessFlags&Security.CLEAN)==Security.CLEAN) return true; return false; } public override bool mnuAllowDataCheck() { if (isApproved||IsEmpty) return false; if (Lock.LockStatus!=VENetwork.Status.Locked)return false; if (amILockedByMe()==false) return false; if ((accessFlags&Security.CLEAN)==Security.CLEAN) return true; return false; } public override bool mnuAllowChgDef() { if(IsEmpty) return false; if (amILockedByMe()==false) return false; return true; } public override bool mnuAllowApprove() { if (isApproved || IsEmpty || isTempChange) return false; if (amILockedByMe()==false) return false; return true; } public override bool mnuAllowApproveAll() { bool allowit=false; bool allowonlyonce=false; if (isApproved || IsEmpty || isTempChange) return false; if (amILockedByMe()==false) return false; if ((accessFlags&Security.APPROVE)==Security.APPROVE) allowit = true; // also check if there is a serial number option which allows only one // approve-all, i.e. if an approved version exists, cannot approve all. if (usrRunTime.SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_ONLYAPPROVEONCE_ON)>0) allowonlyonce=true; if (allowonlyonce && this.isSetApproved) return false; if (allowit) return true; return false; } public override bool mnuAllowApproveSel() { if (isApproved || IsEmpty || isTempChange) return false; if (amILockedByMe()==false) return false; if (isSetApproved && ((accessFlags&Security.APPROVESINGLE)==Security.APPROVESINGLE)) return true; return false; } public override bool mnuAllowNew() { return false; } public override bool mnuAllowDelete() { if (amILockedByMe()==false) return false; if(usrRunTime.sec.PermissionToManageFlag) return true; return false; } public override bool canEdit() { if (amILockedByMe()==false) return false; if(usrRunTime.sec.PermissionToManageFlag) return true; return false; } public override void DoListView(ListView veoListView) { ListViewItem item=null; veoListView.Columns.Add("Type", 120, HorizontalAlignment.Left); for (int i=0; i= 10)) break; // get the largest values from the first record's number field if (isfirst) { isfirst = false; string nm = row["NUMBER"].ToString(); if (nm != null && nm !="") { try { LargestNumber = System.Convert.ToInt32(nm.Substring(0,2)); LargestNumberForMenu=System.Convert.ToInt32(nm.Substring(3,2)); LargestTitleForMenu=System.Convert.ToInt32(nm.Substring(6,2)); } catch (Exception) { MessageBox.Show("Invalid data in procedure set.dbf file. Contact Volian!", "set.dbf Error"); return false; } } } else { string mytitle = row["TITLE"].ToString(); string mynum = row["NUMBER"].ToString(); string mypth = row["ENTRY"].ToString(); string recid = row["RECID"].ToString(); string tmpcol = row["FORMAT"].ToString(); string proccode = row["PROCCODE"].ToString(); int itmpcol; if (tmpcol==null||tmpcol=="") itmpcol=1; else { try { itmpcol = System.Convert.ToInt32(tmpcol)-1; } catch { itmpcol = 1; } } if (itmpcol < 0) itmpcol = 1; // if 0 in database, default to 2 col VEO_Base.ProcColumnOptions format = (VEO_Base.ProcColumnOptions) itmpcol; VEO_Proc prc = new VEO_Proc(mytitle,mypth,mynum,recid,format,proccode,row,this,false); Children.Add(prc); } } if (ps.hasExtensions) { // if not new and we have extensions, check for a setext file. if it doesn't // exist, notify user & set the flag to false. Just return, if we got to // this point, no errors were caught. string setextname = ps._curDirectory+"\\"+ps._Location+"\\setext.dbf"; if (!isNew) { FileInfo fi = new FileInfo(setextname); if (fi.Exists == false) { MessageBox.Show("Procedure comment file (setext.dbf) does not exist.\nThis data will not be available.","Set Extension Error"); ps.hasExtensions=false; return true; } } // the numeric data of the set extension file was not read correctly (an underlying // driver problem. So, change the data type from numeric (N) to character (C) // in the file at the 171th byte in the file, if it hasn't been changed. try { FileStream fs = new FileStream(setextname,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite); fs.Seek(171,SeekOrigin.Begin); int by = fs.ReadByte(); if ((byte)by != (byte)'C') // rewrite it. { fs.Seek(171,SeekOrigin.Begin); fs.WriteByte((byte)'C'); } fs.Close(); } catch (Exception e) { MessageBox.Show(e.Message,"Set Extension Error"); } int chldindx=0; isfirst=true; vdbSetExt=new vdb_SetExt(_Location+"\\setext.dbf"); // Loop thru the procset (process like a dataset) tbl = vdbSetExt.DB_Data.Tables[0]; foreach (DataRow row in tbl.Rows) { // if in demo mode, only allow 10 procedures in set if (usrRunTime.sec.isDemoMode && (chldindx >= 10)) break; // skip the first one if (isfirst) isfirst = false; else { VEO_Proc prc = (VEO_Proc) Children[chldindx]; string comment = row["COMMENT"].ToString(); string rev = row["REV"].ToString(); string pc = row["PC"].ToString(); string recid = row["RECID"].ToString(); string std = row["APPROVEDDATE"].ToString(); prc.procExt = new VEO_ProcExt(comment, rev, pc, recid, std, row); chldindx++; } } } } catch (Exception e) { MessageBox.Show(e.Message,"Error reading procedure set"); return false; } return true; } ~ VEO_DummySet() { if (vdbtmpSet!=null)vdbtmpSet.Clear(); vdbtmpSet=null; vdbSet=null; vdbSetExt= null; } // This method clears the vdbset, and vdbsetext if used, and reloads from // database. It then sync's up the datarows to the dummyset's children. // It is used for moving procedures within the set & on the pack operation. // Both of these required rewriting of a new database file. private bool ReLoadRows(int skip) { VEO_ProcSet ps = (VEO_ProcSet) parentObj; try { // now reopen a vdbset & vdbsetext & reassign the datarows. this.vdbSet = null; this.vdbSetExt = null; vdbSet=new vdb_Set(_Location+"\\set.dbf"); // Loop thru the procset (process like a dataset) DataTable tbl = vdbSet.DB_Data.Tables[0]; int rec = 1; for (int i=0;i=11, first // record is not a procedure) if (usrRunTime.sec.isDemoMode && (rec >= 11)) break; // if not skipping this child (on a delete), sync the database // row eith the internal proc row if (skip<0||i!=skip) { VEO_Proc prc = (VEO_Proc) Children[i]; prc.pdatarow = tbl.Rows[rec]; // first table row is blank rec++; } } if (ps.hasExtensions) { this.vdbSetExt=null; vdbSetExt=new vdb_SetExt(_Location+"\\setext.dbf"); // Loop thru the procset extensions file DataTable xtbl = vdbSetExt.DB_Data.Tables[0]; rec=1; for (int i=0;i= 11)) break; if (skip<0||i!=skip) { VEO_Proc prc = (VEO_Proc) Children[i]; VEO_ProcExt pe = prc.procExt; pe.drow = xtbl.Rows[rec]; rec++; } } } return true; } catch (Exception e) { MessageBox.Show(e.Message, "Problem saving procedure data"); return false; } } // When a procedure has been moved within the set, save the new order. public bool SaveOrder() { int rowcount; VEO_ProcSet ps = (VEO_ProcSet) this.parentObj; if(!ps.isOpen)ps.Open(); string tempName = ps._curDirectory + "\\" + ps.Location + "\\NEWSET.DBF"; if (File.Exists(tempName))File.Delete(tempName); string name = ps._curDirectory + "\\" + ps.Location + "\\SET.DBF"; string tempNameEx = null; string nameEx = null; if(ps.hasExtensions) { tempNameEx = ps._curDirectory + "\\" + ps.Location + "\\NEWEXT.DBF"; if (File.Exists(tempNameEx))File.Delete(tempNameEx); nameEx = ps._curDirectory + "\\" + ps.Location + "\\SETEXT.DBF"; } // do set database files now try { vdb_Set newset = new vdb_Set(ps._curDirectory + "\\" + ps.Location); newset.CreateTable("newset"); DataTable pdatatable = newset.DB_Data.Tables[0]; DataTable origtable = vdbSet.DB_Data.Tables[0]; DataRow recidrow = pdatatable.Rows[0]; DataRow firstrow = origtable.Rows[0]; recidrow.ItemArray=firstrow.ItemArray; rowcount = 1; foreach (VEO_Proc prc in Children) { DataRow pdatarow = pdatatable.NewRow(); DataRow curold = prc.pdatarow; pdatarow.ItemArray=curold.ItemArray; rowcount++; pdatatable.Rows.Add(pdatarow); prc.pdatarow = pdatarow; } newset.DB_Data = recidrow.Table.DataSet; } catch (Exception e) { MessageBox.Show(e.Message,"Error Saving Procedure Set Order"); if (File.Exists(tempName))File.Delete(tempName); if (File.Exists(tempNameEx))File.Delete(tempNameEx); return false; } // if has setextensions, do the setext file now. if (ps.hasExtensions) { try { vdb_SetExt newext = new vdb_SetExt(ps._curDirectory + "\\" + ps.Location); newext.CreateTable("newext"); DataTable exttbl = newext.DB_Data.Tables[0]; DataRow firstdelrow = exttbl.Rows[0]; // first row was made with a recid of 0001. We want to use the // first row from the original setext file. firstdelrow.Delete(); DataRow firstrow = exttbl.NewRow(); DataRow orig = vdbSetExt.DB_Data.Tables[0].Rows[0]; firstrow.ItemArray = orig.ItemArray; exttbl.Rows.Add(firstrow); rowcount=1; foreach (VEO_Proc prc in Children) { DataRow pdatarow = exttbl.NewRow(); DataRow origr = prc.procExt.drow; pdatarow.ItemArray=origr.ItemArray; exttbl.Rows.Add(pdatarow); rowcount++; prc.procExt.drow = pdatarow; } newext.DB_Data = firstrow.Table.DataSet; } catch (Exception e) { MessageBox.Show(e.Message,"Error Saving Procedure Set Order"); if (File.Exists(tempName))File.Delete(tempName); if (File.Exists(tempNameEx))File.Delete(tempNameEx); return false; } } // rename files & then reload the data (to sync up with internal tree) File.Delete(name); File.Move(tempName,name); if (ps.hasExtensions) { File.Delete(nameEx); File.Move(tempNameEx,nameEx); } return (ReLoadRows(-1)); } // back this database, pass in an integer to show the i'th child which was removed // so that this one is sync'd back up in the reload code. public bool PackDB(int i) { //call the database method for this dataset to pack. It will close the dataset //and will require a reopen of dataset. this.vdbSet.Pack(); VEO_ProcSet ps = (VEO_ProcSet) this.parentObj; if (ps.hasExtensions) this.vdbSetExt.Pack(); return (ReLoadRows(i)); } // create a new document object (procedure child for this set) public override Object MakeNewChild() { // if in demo mode, only allow 10 procedures in set if (usrRunTime.sec.isDemoMode && (Children.Count >= 10)) { MessageBox.Show("No more than 10 procedures while in Demo Mode.", "VE-PROMS Demo"); return null; } // for this 'dummy' procedure list node, loop through its // children to get a unique procnumber. int i=0; bool newdc = false; string newdoc=null; while(!newdc) { if (i==0) newdoc = "NewDoc"; else newdoc = "NewDoc"+(i-1).ToString(); bool inlist = false; foreach (VEO_Proc chld in this.Children) { if (chld.Procedure_Number == newdoc) { inlist=true; break; } } if(inlist)i++; else newdc=true; } // now get a unique file name VEO_Proc prc = new VEO_Proc("New Document",this._Location,newdoc,null,VEO_Base.ProcColumnOptions.TwoColumn, null, null, this, true); VEO_ProcSet ps = (VEO_ProcSet) parentObj; if (ps.hasExtensions) { prc.procExt = new VEO_ProcExt(null, null, null, null, null, null); } return prc; } public override bool SaveChild(Object obj) { VEO_Proc proc = (VEO_Proc)obj; bool succeed = proc.SaveNew(null); if (succeed == true) proc.parentObj = this; return succeed; } public override void DoListView(ListView veoListView) { ListViewItem item=null; veoListView.Columns.Add("ProcNumber", 120, HorizontalAlignment.Left); veoListView.Columns.Add("Title", 200, HorizontalAlignment.Left); veoListView.Columns.Add("ProcColumn", 100, HorizontalAlignment.Left); veoListView.Columns.Add("ModInfo", 150, HorizontalAlignment.Left); veoListView.Columns.Add("Location", 100, HorizontalAlignment.Left); for (int i=0; i0)) { // Enhanced Background Documents if (File.Exists(_Location+"\\SET.DBF")) UpdateEnhancedSetFile(); else { // no set file, copy from EOPs // VEO_ProcSet ps = (VEO_ProcSet) this.parentObj; File.Copy(ps.GetParentLink()+"\\SET.DBF",_Location+"\\SET.DBF"); } } // else if (LOC.EndsWith(".DVT") && else if (!ps.isApproved && !ps.isTempChange && ps._ProcType.Equals(VEObject.ProcTypeOptions.Deviation) && (usrRunTime.SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_DEVIATION_ON)>0)) { // Enhanced Deviation Documents if (File.Exists(_Location+"\\SET.DBF")) UpdateEnhancedSetFile(); else { // no set file, copy from EOPs // VEO_ProcSet ps = (VEO_ProcSet) this.parentObj; File.Copy(ps.GetParentLink()+"\\SET.DBF",_Location+"\\SET.DBF"); } } // else if (LOC.IndexOf(".SL") > 0) else if (!ps.isApproved && !ps.isTempChange && ps._ProcType.Equals(VEObject.ProcTypeOptions.Slave)) { // Slave Procedure Set UpdateSlaveSetFile(); } else return; // not a enhanced or slave set } private void UpdateEnhancedSetFile() { VEO_ProcSet ps = (VEO_ProcSet) parentObj; int EnhIdx=1,PrcIdx=1,TmpIdx; // int EnhExtIdx=0; int EnhCnt=0, PrcCnt=0, NewCnt=0; // int EnhExtCnt=0, NewEnhExtCnt=0; int LargestRecID = 0; bool NeedToIncLargestRecID = false; string strEnhRecID, strPrcRecID, strLargestRecID,strNewRecID; // string NewEnhExtRecID; int EnhRecID, PrcRecID, NewRecID; DataRow EnhRow, PrcRow, NewRow; // DataRow EnhExtRow; string ParentPath = ps.GetParentLink(); if (!Directory.Exists(ParentPath)) { string cwd = Directory.GetCurrentDirectory(); MessageBox.Show("Cannot update enhanced set " + ParentPath + ". It does not exist. Check your lnk file setting.", "Enhanced Document Error"); return; } // compare the date/times of the two set files DateTime bcksetdt = File.GetLastWriteTimeUtc(_Location+"\\set.dbf"); DateTime eopsetdt = File.GetLastWriteTimeUtc(ParentPath+"\\set.dbf"); // if ( bcksetdt.ToUniversalTime() >= eopsetdt.ToUniversalTime()) if (bcksetdt >= eopsetdt) return; // Enhanced Set file is up to date ArrayList EnhSetList = new ArrayList(); ArrayList PrcSetList = new ArrayList(); ArrayList NewEnhSetList = new ArrayList(); // Array Lists for Set Extension databases // ArrayList EnhSetExtList = new ArrayList(); // ArrayList NewEnhSetExtList = new ArrayList(); // populate the array lists EnhCnt = PopulateSetArrayList(_Location,EnhSetList); PrcCnt = PopulateSetArrayList(ParentPath,PrcSetList); // if (ps.hasExtensions) // EnhExtCnt = PopulateSetExtArrayList(_Location,EnhSetExtList); // copy the first record from the Enhanced Set file // - we might modify this later EnhRow = (DataRow)EnhSetList[0]; strEnhRecID = EnhRow["RECID"].ToString(); EnhRecID = Convert.ToInt32(strEnhRecID.Substring(2)); NewCnt = AddToArrayList(NewEnhSetList,EnhRow,NewCnt,strEnhRecID); strLargestRecID = strEnhRecID; LargestRecID = EnhRecID; // if (ps.hasExtensions) // { // // copy the first record from the setext // EnhExtRow = (DataRow)EnhSetExtList[0]; // NewEnhExtRecID = EnhExtRow["RECID"].ToString(); // NewEnhExtCnt = AddToArrayList(NewEnhSetExtList,EnhExtRow,NewEnhExtCnt,NewEnhExtRecID); // } while (EnhIdx < EnhCnt && PrcIdx < PrcCnt) { EnhRow = (DataRow)EnhSetList[EnhIdx]; PrcRow = (DataRow)PrcSetList[PrcIdx]; strEnhRecID = EnhRow["RECID"].ToString(); strPrcRecID = PrcRow["RECID"].ToString(); EnhRecID = Convert.ToInt32(strEnhRecID.Substring(2)); PrcRecID = Convert.ToInt32(strPrcRecID.Substring(2)); if (!(EnhRecID == PrcRecID)) { if ((InThisArrayList(strEnhRecID,PrcSetList,PrcIdx,PrcCnt)) == -1) { // The EOP probable was deleted. Keep the Background // procedure around in case user needs to copy info // from it. if (EnhRecID > LargestRecID) { strLargestRecID = strEnhRecID; LargestRecID = EnhRecID; NeedToIncLargestRecID = true; } NewCnt = AddToArrayList(NewEnhSetList,EnhRow,NewCnt,strEnhRecID); } } // Copy the Date, Time, and Initials from the old Enhanced Set file TmpIdx = InThisArrayList(strPrcRecID,EnhSetList,1,EnhCnt); if (TmpIdx > -1) { DataRow TmpRow = (DataRow)EnhSetList[TmpIdx]; PrcRow["DATE"] = TmpRow["DATE"]; PrcRow["TIME"] = TmpRow["TIME"]; PrcRow["INITIALS"] = TmpRow["INITIALS"]; } if (PrcRecID > LargestRecID) { strLargestRecID = strPrcRecID; LargestRecID = PrcRecID; NeedToIncLargestRecID = true; } NewCnt = AddToArrayList(NewEnhSetList,PrcRow,NewCnt,strPrcRecID); // if (ps.hasExtensions) // { // // Add Set Extension info. // EnhExtIdx = InThisArrayList(strEnhRecID,EnhSetExtList,1,EnhExtCnt); // if (EnhExtIdx > -1) // { // EnhExtRow = (DataRow)EnhSetExtList[EnhExtIdx]; // NewEnhExtRecID = EnhExtRow["RECID"].ToString(); // NewEnhExtCnt = AddToArrayList(NewEnhSetExtList,EnhExtRow,NewEnhExtCnt,NewEnhExtRecID); // } // } EnhIdx++; PrcIdx++; } // add any BCK Records that are remaining while (EnhIdx < EnhCnt) { EnhRow = (DataRow)EnhSetList[EnhIdx]; strEnhRecID = EnhRow["RECID"].ToString(); EnhRecID = Convert.ToInt32(strEnhRecID.Substring(2)); if (EnhRecID > LargestRecID) { strLargestRecID = strEnhRecID; LargestRecID = EnhRecID; NeedToIncLargestRecID = true; } NewCnt = AddToArrayList(NewEnhSetList,EnhRow,NewCnt,strEnhRecID); EnhIdx++; // if (ps.hasExtensions) // { // // Add Set Extension info. // EnhExtIdx = InThisArrayList(strEnhRecID,EnhSetExtList,1,EnhExtCnt); // if (EnhExtIdx > -1) // { // EnhExtRow = (DataRow)EnhSetExtList[EnhExtIdx]; // NewEnhExtRecID = EnhExtRow["RECID"].ToString(); // NewEnhExtCnt = AddToArrayList(NewEnhSetExtList,EnhExtRow,NewEnhExtCnt,NewEnhExtRecID); // } // } } // add any PRC Records that are remaining while (PrcIdx < PrcCnt) { PrcRow = (DataRow)PrcSetList[PrcIdx]; strPrcRecID = PrcRow["RECID"].ToString(); PrcRecID = Convert.ToInt32(strPrcRecID.Substring(2)); if (PrcRecID > LargestRecID) { strLargestRecID = strPrcRecID; LargestRecID = PrcRecID; NeedToIncLargestRecID = true; } // Copy the Date, Time, and Initials from the old Enhanced Set file TmpIdx = InThisArrayList(strPrcRecID,EnhSetList,1,EnhCnt); if (TmpIdx > -1) { DataRow TmpRow = (DataRow)EnhSetList[TmpIdx]; PrcRow["DATE"] = TmpRow["DATE"]; PrcRow["TIME"] = TmpRow["TIME"]; PrcRow["INITIALS"] = TmpRow["INITIALS"]; } NewCnt = AddToArrayList(NewEnhSetList,PrcRow,NewCnt,strPrcRecID); PrcIdx++; // if (ps.hasExtensions) // { // // Add Set Extension info. // EnhExtIdx = InThisArrayList(strPrcRecID,EnhSetExtList,1,EnhExtCnt); // if (EnhExtIdx > -1) // { // EnhExtRow = (DataRow)EnhSetExtList[EnhExtIdx]; // NewEnhExtRecID = EnhExtRow["RECID"].ToString(); // NewEnhExtCnt = AddToArrayList(NewEnhSetExtList,EnhExtRow,NewEnhExtCnt,NewEnhExtRecID); // } // } } // Update Record zero's RECID if needed NewRow = (DataRow)NewEnhSetList[0]; strNewRecID = NewRow["RECID"].ToString(); NewRecID = Convert.ToInt32(strNewRecID.Substring(2)); if (LargestRecID > NewRecID) { if (NeedToIncLargestRecID) LargestRecID++; strLargestRecID = strLargestRecID.Substring(0,2)+LargestRecID.ToString("d6"); NewRow["RECID"] = strLargestRecID; NewEnhSetList[0] = NewRow; // if (ps.hasExtensions) // { // EnhExtRow = (DataRow)EnhSetExtList[0]; // EnhExtRow["RECID"] = strLargestRecID; // EnhSetExtList[0] = EnhExtRow; // } } // Write out new SET.DBF file // WriteUpdatedSetFile(_Location,NewEnhSetList,EnhSetExtList,ps.hasExtensions); WriteUpdatedSetFile(_Location,NewEnhSetList,null,false); } static int PopulateSetArrayList(string Loc,ArrayList AryLst) { int cnt =0; string SetFilePath = Loc+"\\set.dbf"; if (File.Exists(SetFilePath)) { try { vdb_Set TheSetFile = new vdb_Set(SetFilePath); // Loop thru the procset (process like a dataset) DataTable tbl = TheSetFile.DB_Data.Tables[0]; foreach (DataRow row in tbl.Rows) { AryLst.Add(row); cnt++; } } catch (Exception e) { MessageBox.Show(e.Message,"Error populating Set Array Lists"); return 0; } } return cnt; } static int PopulateSetExtArrayList(string Loc,ArrayList AryLst) { int cnt =0; string SetExtPath = Loc+"\\setext.dbf"; if (File.Exists(SetExtPath)) { try { vdb_SetExt TheSetExtFile = new vdb_SetExt(SetExtPath); // Loop thru the procset (process like a dataset) DataTable tbl = TheSetExtFile.DB_Data.Tables[0]; foreach (DataRow row in tbl.Rows) { AryLst.Add(row); cnt++; } } catch (Exception e) { MessageBox.Show(e.Message,"Error populating SetExt Array Lists"); return 0; } } return cnt; } static int AddToArrayList(ArrayList AryLst,DataRow RowToAdd, int cnt, string AddRecID) { bool found=false; // Bug fix: B2006-043 // skip the first record (record zero) int i=1; //0; while (!found && (i= 0) { extTbl.Rows.Add((DataRow)ExtAryLst[ExtAryLstIdx]); } else { // Create empty set extension record DataRow newdatarow = extTbl.NewRow(); newdatarow["RECID"] = AryLstRecID; newdatarow["COMMENT"] = System.DBNull.Value; // (Comment!=null)&&(Comment!="")?Comment:System.DBNull.Value; newdatarow["REV"] = System.DBNull.Value; newdatarow["PC"] = System.DBNull.Value; newdatarow["TDSTAMP"] = System.DBNull.Value; extTbl.Rows.Add(newdatarow); } } } TheSetFile.DB_Data = tbl.DataSet; if (hasextensions) { TheSetExtFile.DB_Data = extTbl.DataSet; } } catch (Exception e) { MessageBox.Show(e.Message,"Error writing Enhanced Procedures' Set File"); return; } return; } void UpdateSlaveSetFile() { VEO_ProcSet ps = (VEO_ProcSet) parentObj; bool updateDTS = true; string MasterDir = ""; string PathToMaster = ""; string PathToSlave = ps._curDirectory + "\\" + ps._Location; // InMaster() will return the MasterSetPath // if (InApproved() || InMaster(MasterDir)) return; if (ps.isApproved || ps.InMaster(ref MasterDir)) return; // For Updating the SET.DBF file in Slave procedure sets... // If the user had approved the slave procedure set: // - don't copy the Date/Time field from the master // Else // - copy the Date/Time field from the master if (File.Exists(PathToSlave + "\\APPROVED\\SET.DBF")) updateDTS = false; PathToMaster = ps.CurDirectory + "\\" + MasterDir; if (SlaveSetFileUpToDate(PathToMaster,PathToSlave)) return; // Set file is up to date ArrayList SlaveSetList = new ArrayList(); ArrayList MasterSetList = new ArrayList(); ArrayList NewSlaveSetList = new ArrayList(); int SlaveIdx = 0, MasterIdx = 0; //, NewSlaveIdx=0; int SlaveCnt, MasterCnt; //, NewCnt; DataRow SlaveRow, MasterRow; //, NewRow; string strMasterRecID; //,strSlaveRecID,strNewRecID; SlaveCnt = PopulateSetArrayList(PathToSlave,SlaveSetList); MasterCnt = PopulateSetArrayList(PathToMaster,MasterSetList); // if (ps.hasExtensions) // SlvExtCnt = PopulateSetExtArrayList(PathToSlave,SlvSetExtList); // Update the first record MasterRow = (DataRow)MasterSetList[0]; strMasterRecID = MasterRow["RECID"].ToString(); if ((InThisArrayList(strMasterRecID,SlaveSetList,0,SlaveCnt)) == 0) { //Update the first record SlaveRow = (DataRow)SlaveSetList[0]; string MasterNumberField = MasterRow["NUMBER"].ToString(); string SlaveNumberField = SlaveRow["NUMBER"].ToString(); SlaveRow["NUMBER"] = MasterNumberField; NewSlaveSetList.Add(SlaveRow); } else { //Copy first record from master NewSlaveSetList.Add(MasterRow); } for(MasterIdx = 1; MasterIdx < MasterCnt; MasterIdx++) { MasterRow = (DataRow)MasterSetList[MasterIdx]; strMasterRecID = MasterRow["RECID"].ToString(); SlaveIdx = InThisArrayList(strMasterRecID,SlaveSetList,1,SlaveCnt); if (SlaveIdx > -1) { // Update Slave set record SlaveRow = (DataRow)SlaveSetList[SlaveIdx]; SlaveRow["TITLE"] = MasterRow["TITLE"]; SlaveRow["NUMBER"] = MasterRow["NUMBER"]; SlaveRow["FORMAT"] = MasterRow["FORMAT"]; if (updateDTS) { SlaveRow["DATE"] = MasterRow["DATE"]; SlaveRow["TIME"] = MasterRow["TIME"]; } NewSlaveSetList.Add(SlaveRow); // remove this item from the Slave list SlaveSetList.RemoveAt(SlaveIdx); SlaveCnt--; } else { // save new entry NewSlaveSetList.Add(MasterRow); } } // remove the deleted slave procedures for (SlaveIdx=1; SlaveIdx < SlaveCnt; SlaveIdx++) { SlaveRow = (DataRow)SlaveSetList[SlaveIdx]; string filename = SlaveRow["ENTRY"].ToString(); // Remove the data files for this procedure RemoveProcedureFiles(PathToSlave,filename); // Remove the transitions references vdb_TransUsage Tusage = new vdb_TransUsage(PathToSlave); string procnum = SlaveRow["NUMBER"].ToString(); string WhereStr = "WHERE [FROMNUMBER] = \'" + procnum.Replace("'","''") + "\' OR [TONUMBER] = \'"+ procnum.Replace("'","''") + "\'"; // string WhereStr = "WHERE [FROMNUMBER] = \'" + procnum + "\'"; DataSet TransDataSet = Tusage.GetNotSorted(WhereStr); DataTable tbl = TransDataSet.Tables[0]; int numrows = tbl.Rows.Count; foreach (DataRow row in tbl.Rows) { row.Delete(); } // remove the deleted Trans Usage records if (tbl.Rows.Count > 0) Tusage.DB_Data = tbl.DataSet; // Remove the RO references vdb_ROUsage ROusage = new vdb_ROUsage(PathToSlave); WhereStr = "WHERE NUMBER = '" + procnum.Replace("'","''") + "'"; DataSet RODataSet = ROusage.GetNotSorted(WhereStr); DataTable roTbl = RODataSet.Tables[0]; foreach (DataRow row in roTbl.Rows) { row.Delete(); } // remove the deleted RO usage records if (roTbl.Rows.Count >0) ROusage.DB_Data = roTbl.DataSet; } // Write the new SET.DBF file WriteUpdatedSetFile(PathToSlave,NewSlaveSetList,null,false); } static bool SlaveSetFileUpToDate(string MasterPath, string SlavePath) { bool rtnval = true; string MasterSetFile = MasterPath+"\\set.dbf"; string SlaveSetFile = SlavePath+"\\set.dbf"; if (File.Exists(MasterSetFile)) { if (File.Exists(SlaveSetFile)) { rtnval = (File.GetLastWriteTimeUtc(MasterSetFile) <= File.GetLastWriteTimeUtc(SlaveSetFile)); } else rtnval = false; } return rtnval; } static void RemoveProcedureFiles(string SlavePath, string FileName) { FileInfo[] fiArr; DirectoryInfo cur = new DirectoryInfo(SlavePath); // check for RTFFILES directory, skip this part if it doesn't exist. DirectoryInfo tstrtf = new DirectoryInfo(SlavePath+"\\RTFFILES"); if (tstrtf.Exists) { fiArr = tstrtf.GetFiles(FileName+".*"); // print out the names of the directories foreach (FileInfo fi in fiArr) { fi.Delete(); } } fiArr = cur.GetFiles(FileName+".*"); foreach (FileInfo fi in fiArr) { fi.Delete(); } } public VEO_Proc GetProcFromNum(string procnum) { foreach (Object obj in Children) { VEO_Proc prc = (VEO_Proc) obj; if (prc._Prcnum.ToUpper() == procnum.ToUpper()) return prc; } return null; //not found } public string GetSectionNumAndTitle(string procnum, string stp) { // get to the list of procedures and find the procedure for the input // procedure number. string retstr = null; VEO_Proc prc = GetProcFromNum(procnum); vdb_Proc dbprc=null; // using the database name, do a select to get the section number & title. try { dbprc = new vdb_Proc(prc._Location+".dbf"); string wherestr = "STEP LIKE '" + stp.Substring(0,1) + "%' AND SEQUENCE LIKE ' %'"; DataSet accSet = dbprc.GetNotSorted(wherestr); DataTable tbl = accSet.Tables[0]; if (tbl.Rows.Count<1) return null; DataRow dr = tbl.Rows[0]; string txt = dr["TEXT"].ToString(); string title = txt.Substring(0,(txt.LengthSECTITLEBUFSZ+15) { int len = (txt.Length-85 0) { // create the lib doc to get it's title, then loop through those // that already are in the list to see if this title is already // there. VEO_LibDoc tmp = new VEO_LibDoc(fi.FullName, this, false); bool inlist = false; foreach (Object obj in Children) { VEO_LibDoc ld = (VEO_LibDoc) obj; //create the lib doc to get it's title, but only add it to the // children list if it's unique. if (ld._Title == tmp._Title) { inlist = true; break; } } if (inlist == false) Children.Add(tmp); } } if (Children.Count==0)IsEmpty=true; return true; } public override Object MakeNewChild() { string comment = null; VEO_LibDoc ld = null; int MAXLIBDOCS=10000; VEO_ProcSet ps = (VEO_ProcSet) parentObj; ps.Open(); // now get a unique file name OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.InitialDirectory = Directory.GetCurrentDirectory(); openFileDialog1.Filter = "rtf files (*.rtf)|*.rtf|All files (*.*)|*.*" ; openFileDialog1.FilterIndex = 0 ; openFileDialog1.RestoreDirectory = true ; string rtffile=null; if(openFileDialog1.ShowDialog() == DialogResult.OK) { rtffile = openFileDialog1.FileName; //currentpath = rtffile.Substring(0,rtffile.LastIndexOf("\\")); // first open & read to verify that it is an rtf file. StreamReader myReader = new StreamReader(rtffile);// Open file int nbytes; char [] tbuf = new char[17]; if((nbytes = myReader.Read(tbuf,0,16))<11) // read some { myReader.Close(); MessageBox.Show("File must be an RTF file","Library Document Error"); } else { myReader.Close(); string str = new string(tbuf); if (str.IndexOf("{\\rtf1\\ansi",0)<0) { MessageBox.Show("File must be an RTF file","Library Document Error"); return null; } } // Make a unique title name int i=0; bool used=true; string newlibtitle = null; while(used) { newlibtitle = "NewLibDoc" + i.ToString(); bool found=false; foreach (Object obj in Children) { VEO_LibDoc lld = (VEO_LibDoc) obj; if (lld._Title == newlibtitle) { found=true; break; } } if(!found) used=false; else i++; } comment = "New Library Document"; // if the 'RTFFILES directory doesn't exist, create it here. if (Directory.Exists("RTFFILES")!=true) Directory.CreateDirectory("RTFFILES"); // now find a unique file name. i=0; string buf1 = "DOC_" + i.ToString("D4") + ".lib"; string buf2 = "RTFFILES\\DOC_" + i.ToString("D4") + ".lib"; bool fexists=true; while(fexists) { if ((File.Exists(buf1) || File.Exists(buf2)) && i0) { xbuf = new char[comment.Length]; xbuf = comment.ToCharArray(); bw.Write(xbuf); bw.Write((byte)0); } //now append the selected file to the new lib file FileStream fsorig = new FileStream(rtffile,FileMode.Open,FileAccess.Read); using (BinaryReader br = new BinaryReader(fsorig,Encoding.ASCII)) { byte ac; bool done = false; while(done==false) { if (br.PeekChar() >0) { ac = br.ReadByte(); bw.Write(ac); } else done=true; } } bw.Close(); fsorig.Close(); fsnew.Close(); if (!File.Exists(pthname)) { MessageBox.Show("Could not create rtf file","Library Document Error"); return null; } ld = new VEO_LibDoc(Directory.GetCurrentDirectory() + "\\"+pthname,this,true); } return ld; } public void Approve(string src, string dst) { string[] fis = Directory.GetFiles(src,"DOC_*.LIB"); foreach (string sfi in fis) { FileInfo fi = new FileInfo(sfi); if (!File.Exists(dst+"\\"+fi.Name)) fi.CopyTo(dst+"\\"+fi.Name,true); } string rtfsrc = src + "\\rtffiles\\"; string rtfdst = dst + "\\rtffiles\\"; fis = Directory.GetFiles(rtfsrc,"DOC_*.LIB"); foreach (string sfi in fis) { FileInfo fi = new FileInfo(sfi); fi.CopyTo(rtfdst+"\\"+fi.Name,true); } } public override bool SaveChild(Object obj) { VEO_LibDoc ld = (VEO_LibDoc)obj; bool succeed = ld.SaveNew(null); if (succeed == true) ld.parentObj = this; return succeed; } public override void DoListView(ListView veoListView) { ListViewItem item=null; veoListView.Columns.Add("Location", 120, HorizontalAlignment.Left); veoListView.Columns.Add("Title", 300, HorizontalAlignment.Left); for (int i=0; i