/********************************************************************************************* * Copyright 2004 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE * ------------------------------------------------------------------------------ * $Workfile: Plant.cs $ $Revision: 10 $ * $Author: Jsj $ $Date: 10/20/06 9:34a $ * * $History: Plant.cs $ * * ***************** Version 10 ***************** * User: Jsj Date: 10/20/06 Time: 9:34a * Updated in $/LibSource/VEObject * long name fix * * ***************** Version 9 ***************** * User: Jsj Date: 9/26/06 Time: 9:38a * Updated in $/LibSource/VEObject * check for a siingle quote in directory name * * ***************** Version 8 ***************** * User: Kathy Date: 6/06/05 Time: 12:35p * Updated in $/LibSource/VEObject * Allow lock set even if system lock set * * ***************** Version 7 ***************** * User: Kathy Date: 4/12/05 Time: 1:01p * Updated in $/LibSource/VEObject * * ***************** Version 6 ***************** * User: Kathy Date: 2/02/05 Time: 10:13a * Updated in $/LibSource/VEObject * B2005-006: fix missing proc sets under plant * * ***************** Version 5 ***************** * User: Kathy Date: 1/31/05 Time: 11:06a * Updated in $/LibSource/VEObject * Fix B2005-005 (connection & delete directory errors). also, fix icon * usage & security for new * * ***************** Version 4 ***************** * User: Kathy Date: 1/24/05 Time: 2:45p * Updated in $/LibSource/VEObject * B2005-004 fixes * * ***************** Version 3 ***************** * User: Kathy Date: 1/14/05 Time: 10:38a * Updated in $/LibSource/VEObject * B2004-061: Fix security optoins * * ***************** Version 2 ***************** * User: Kathy Date: 1/10/05 Time: 12:58p * Updated in $/LibSource/VEObject * B2004-063 fix * * ***************** 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.Windows.Forms; using System.IO; using System.Xml; using System.ComponentModel; using Utils; using VENetwork; namespace VEObject { /// /// This defines the VEO_Plant class which handles plant data. This contains /// support for the vexxx layer. /// public class VEO_Plant : VEO_Base { public long accessFlags; protected string tmpTitle; protected string tmpLocation; protected bool changeLocation; protected bool changeTitle; private string PrevDirectory; public VEO_Plant(UserRunTime iusrRunTime, string ititle, string ipath) { // iconStates are the imagelist indexes for the tree view (imglist1) // the states are Nolock, LockedByMe, LockedByOther, LockPending, Empty. iconStates = new int[5] {3,21,5,22,4}; _Title = ititle; _Location = ipath; usrRunTime = iusrRunTime; changeLocation=false; changeTitle=false; IsEmpty=false; VEObjectType=(int)VEObjectTypesDefs.Plant; isNew=false; LoadLockInfo(); icon = iconStates[(int)Lock.LockStatus]; if (Lock.LockStatus != VENetwork.Status.LockedByOther) { if (ipath != null) { string[] dirs = new string[40]; dirs = Directory.GetDirectories(ipath); if (dirs.Length == 0) { IsEmpty=true; //only reset the icon to empty if there is no lock icon. //if a lock, show the lock icon if (Lock.LockStatus == VENetwork.Status.NoLock) icon = iconStates[(int)VEO_IconStates.Empty]; } } } } public override void LoadLockInfo() { Lock = new VELock(_Location, usrRunTime.myUserData, usrRunTime.InMultiUserMode?VENetwork.LockTypes.Plant:VENetwork.LockTypes.None); } // Properties used for modify of 'Properties' from File menu. [Description("Location"),Category("Plant"),ReadOnly(true)]public string Location { get{return _Location;} set{_Location=value;} } [Description("Title"),Category("Plant")]public string Title { get { if (!changeTitle) return _Title; else return tmpTitle; } set { changeTitle=true; tmpTitle=value; } } // The open method checks for multi-user settings at the plant level. It // also positions into the plant directory. public override bool Open() { isOpen = true; PrevDirectory = Directory.GetCurrentDirectory(); if(_Location!=null)Directory.SetCurrentDirectory(_Location); if (Connection!=null)Connection.Enter(false); return true; } // The close method resets, if necessary from any multi-user settings and // positions back to the datapath 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 override void Restore() { changeTitle=false; } public override bool Delete() { DialogResult result = MessageBox.Show("Are you sure you want to delete the entire plant directory " + this._Location,"Confirm Delete Again",MessageBoxButtons.YesNoCancel); if (result == DialogResult.Yes) { // delete the entire directory if (Directory.Exists(this._Location)) { if(isOpen)Close(); try { Directory.Delete(this._Location,true); } catch (Exception e) { MessageBox.Show("Could not delete directory - manually delete " + this._Location + ". Cause: " + e.Message); } if (Directory.Exists(this._Location)) { MessageBox.Show("Unable to delete the plant directory."); return false; } return true; } } return false; } private void CreateProcSet(string dirpath, XmlElement nm, string dirname, long flags) { // see if there is a title file in the directory and use // it if there is, otherwise use menuname & if there's no menu // name, use the directory name. VEO_ProcSet procset = null; string titlepath = dirpath + "\\" + "Title"; FileInfo fi = new FileInfo(titlepath); if (File.Exists(titlepath)) { StreamReader myReader = new StreamReader(titlepath); titlepath = myReader.ReadLine(); myReader.Close(); procset = new VEO_ProcSet(usrRunTime, titlepath.Trim(), dirpath, flags); } else { if (nm != null) procset = new VEO_ProcSet(usrRunTime, nm.InnerText, dirpath, flags); else { string tmpdirnm = dirname; int indx=0; // if this is temp change directory, tack on text to recognize it if ((indx=dirpath.ToUpper().IndexOf("TMPCHG"))>-1) tmpdirnm = dirname + " - Temporary Change Version"; // if this is approved, tack on Current Approved Version to the title else if ((indx=dirpath.ToUpper().IndexOf("APPROVED"))>-1) tmpdirnm = dirname + " - Current Approved Version"; procset = new VEO_ProcSet(usrRunTime, tmpdirnm, dirpath,flags); } } procset.parentObj = this; Children.Add(procset); } // private method, used below, to add a directory to the child list // (list contains proc sets) private bool ProcessDirName(XmlElement par, string dirname, int plntsecindx) { XmlNodeList nodeList = par.SelectNodes("ProcFile"); if (nodeList == null) return false; foreach (XmlNode dirnd in nodeList) { XmlElement dele=(XmlElement)dirnd; string dirpath = _Location + "\\" + dirname; if (File.Exists(dirpath+"\\"+dirnd.InnerText)) { // // see if there's an exception or a requirement, i.e. use // the Working Draft if there's no proc2 directory (Except) // or use the Working Draft Unit 1 if there's a proc2 // directory (Require) bool excpt = false; bool req = true; string path1=null; XmlElement except = (XmlElement) par.SelectSingleNode("Exception"); if (except != null) { // if this exception directory exists, don't add this to // the set. path1 = dirpath + "\\" + except.InnerText; if (Directory.Exists(path1)) excpt = true; } XmlElement require = (XmlElement) par.SelectSingleNode("Require"); if (require != null) { // if this require directory exists, add this to set only // if this exists. path1 = dirpath + "\\" + require.InnerText; if (Directory.Exists(path1) == false) req = false; } if (excpt == false && req == true) { XmlElement nm = (XmlElement) par.SelectSingleNode("MenuName"); long flags=0L; // bug fix B2006-045 // need to convert long folder/file names to short (8.3) ShortName sname = new ShortName(dirpath); bool hasSec = usrRunTime.sec.ProcSetHasSecurity(plntsecindx, Path.GetFileName(sname.ShortFileName)); // bool hasSec = usrRunTime.sec.ProcSetHasSecurity(plntsecindx, dirname); if (this.usrRunTime.sec==null) flags=Security.SUPERACCESS; else if (hasSec) flags = usrRunTime.sec.GetProcSecurity(sname.ShortFileName); // else if (hasSec) flags = usrRunTime.sec.GetProcSecurity(dirpath); if((hasSec && flags!=0L) || (!hasSec&&!usrRunTime.sec.BlockAccess())) { CreateProcSet(dirpath, nm, dirname, flags); return true; } } } } return false; } // This method processes through the SubDirSearch xmlelement tree in // menuwin2.xml to see if the input procedure set directory has valid // procedure set subdirectories. Arguments are: // subtop is xmlelement for the SubDirSearch in menuwin2.xml, dir is actual // procset directory name (for example, procs, proc000.dvt, etc) and // dname is the name to be used for the directory name in the menuwin2.xml // file under the SubDirSearch xmlelement tree (for example, procs, *.dvt, etc) private bool ProcessSubDir(XmlElement subtop, string dri, string dname, int plntsecindx) { XmlNodeList nodeList; string xp = "descendant::ProcSet[Dir = \'" + dname + "\']"; try { nodeList = subtop.SelectNodes(xp); // for each possible subdirectory for this directory, see if it // exists. foreach (XmlNode subdirname in nodeList) { XmlElement subdele=(XmlElement)subdirname; XmlNodeList FnodeList = subdirname.SelectNodes("ProcFile"); // see if the files listed exist, if so, add them to the // plant procset list. foreach (XmlNode dirnd in FnodeList) { XmlElement dele=(XmlElement)dirnd; string dirpath = _Location + "\\" + dri; if (File.Exists(dirpath+"\\"+dirnd.InnerText)) { XmlElement nm = (XmlElement) subdirname.SelectSingleNode("MenuName"); string subdir = dirnd.InnerText.Substring(0,dirnd.InnerText.LastIndexOf("\\")); long flags=0L; bool hasSec = usrRunTime.sec.ProcSetHasSecurity(plntsecindx, dri+"\\"+subdir); if (this.usrRunTime.sec==null) flags=Security.SUPERACCESS; else if (hasSec) flags = usrRunTime.sec.GetProcSecurity(dirpath + "\\" + subdir); if((hasSec && flags!=0L) || (!hasSec&&!usrRunTime.sec.BlockAccess())) CreateProcSet(dirpath+"\\"+subdir, nm, dri, flags); } break; // out of file check foreach } } } catch (Exception e) { MessageBox.Show(e.Message); return false; } return true; } // Using the menuwin2.xml file, read in child list by seeing which // directories (proc sets) are contained in this vexxx directory. public override bool Read(bool ChkForChldOnly) { bool didone; Cursor.Current = Cursors.WaitCursor; // using the . Then do exist tests to see if they // exist on this datapath. usrRunTime.LoadMenuWin2(); XmlDocument xmldoc = usrRunTime.menuwin2XML.GetXmlDoc(); XmlElement top = (XmlElement) xmldoc.FirstChild; XmlElement sys = (XmlElement) top.SelectSingleNode("PlantAttach"); XmlElement subtop = (XmlElement) top.SelectSingleNode("SubDirSearch"); DirectoryInfo cur = new DirectoryInfo(_Location); DirectoryInfo[] diArr = cur.GetDirectories(); int plntsecindx = usrRunTime.sec.GetPlantSecurityIndex(_Location); foreach (DirectoryInfo dri in diArr) { XmlNodeList nodeList; string dname = null; int indx; if ((indx=dri.Name.IndexOf("."))>-1) { //must be *.prc, *.bck, *.dvt, *.sl? if (indx+4<=dri.Name.Length) { dname = "*." + dri.Name.Substring(indx+1,3).ToLower(); if (dname.StartsWith("*.sl")) dname = dname.Substring(0,4) + "?"; } else dname = null; } else if ((indx=dri.Name.IndexOf("'"))>-1) { // bug fix B2006-047 // if not a .PRC folder, then we get an error looking up // the directory name in XML (if it has an ' in the name) dname = null; } else { dname = dri.Name.ToLower(); } if (dname!=null) { string xp = "descendant::ProcSet[Dir = \'" + dname + "\']"; try { nodeList = sys.SelectNodes(xp); foreach (XmlNode dirname in nodeList) { XmlElement dele=(XmlElement)dirname; didone = ProcessDirName(dele, dri.Name, plntsecindx); if (Children.Count > 0 && ChkForChldOnly) { Cursor.Current = Cursors.Default; return true; } // if a directory was found, see if any // subdirectories exist that need added too. bool didsub = false; if (didone) didsub = ProcessSubDir(subtop, dri.Name, dname, plntsecindx); } } catch (Exception e) { MessageBox.Show(e.Message.ToString()); Cursor.Current = Cursors.Default; return false; } } } // if no children, change icon to empty (unless it has a lock icon) if (Children.Count <=0 && Lock.LockStatus == VENetwork.Status.NoLock) icon = iconStates[(int)VEO_IconStates.Empty]; Cursor.Current = Cursors.Default; return true; } // write out change (modification of title for plant) for plant to // the menuwin.xml file public override bool Write() { string newtitle=null; if (changeTitle) { newtitle = tmpTitle; bool success = usrRunTime.ModMenuWin(newtitle, this._Title); if (success==false) { MessageBox.Show("Could not modify title for the plant."); return false; } MessageBox.Show("Please send \\ve-proms\\menuwin & \\ve-proms\\menuwin.xml files to Volian."); _Title=newtitle; changeTitle=false; } return true; } // create a new proc set object (child for this plant) public override Object MakeNewChild() { if (!isOpen)Open(); VEO_ProcSet ps = new VEO_ProcSetN(usrRunTime,null,_Location); return ps; } // save a new proc set (child for this plant) public override bool SaveChild(Object obj) { VEO_ProcSetN ps = (VEO_ProcSetN) obj; // check for valid child bool valid = ps.IsValid(); if (valid == false) return false; valid = ps.SaveNew("dummy"); if (valid == true) { // add this item to this plants list of children. Children.Add((VEO_ProcSet)obj); ps.parentObj=this; ps._Location = this._Location + "\\" + ps._Location; ps.icon=iconStates[0]; // if this plant's icon is 'empty', change it to either lock (if locked), // or to not empty. icon = iconStates[(int)Lock.LockStatus]; IsEmpty=false; } return valid; } // save a new plant directory public override bool SaveNew(string pth) { // check for non-empty data. if (tmpLocation == null || tmpLocation == "" || tmpTitle == null || tmpTitle == "") { MessageBox.Show("Need to fill in all data."); return false; } // for this new plant, make the directory and write out // to the menuwin & menuwin.xml files. // if using the file browser dialog, the drive may be included, if so // check that the directory matches the datapath. int slash = tmpLocation.LastIndexOf("\\"); if (slash>0) { string drvtmp = tmpLocation.Substring(0,slash+1); ShortName sname = new ShortName(drvtmp); string drv=sname.ShortFileName; sname = null; if (drv.ToUpper() != pth.ToUpper()) { MessageBox.Show("Invalid path, directory must match datapath"); return false; } // remove the drive part of the path, it's added back later. tmpLocation = tmpLocation.Substring(slash+1,tmpLocation.Length-(slash+1)); } // check for ve* if (tmpLocation.Substring(0,2).ToUpper() != "VE") { MessageBox.Show("First two characters must be 'VE' for new plant directory name."); return false; } // also check that the name is not greater than 8 characters (an old 16-bit hangover) if (tmpLocation.Length>8) { MessageBox.Show("Directory/plant name must be 8 characters or less."); return false; } // make path to new directory & check for existence. string curpath=null; curpath = pth + "\\" + this.tmpLocation; DirectoryInfo cur = new DirectoryInfo(curpath); if (cur.Exists ) { DirectoryInfo[] di = cur.GetDirectories("*"); FileInfo[] fi = cur.GetFiles("*"); if (di.Length>0 || fi.Length>0) { MessageBox.Show("The plant directory you specified already exists & has contents. Enter a different name."); return false; } } // if the directory exists & it is already in the menu file, it didn't succeed // in adding the new item. if (cur.Exists && (usrRunTime.IsInMenuWin(this.tmpLocation)!=0)) { MessageBox.Show("The plant directory you specified already exists and the plant name exists in the menu files."); return false; } try { if (cur.Exists == false)cur.Create(); } catch (Exception e) { MessageBox.Show("Error creating directory: " + e.Message); return false; } // now add to end of menuwin & menuwin.xml. bool success = usrRunTime.AddToMenuWin(this.tmpTitle,this.tmpLocation); if (success==false) { MessageBox.Show("Could not add directory to ve-proms menuing files. Could not create plant directory."); cur.Delete(); return false; } MessageBox.Show("The VE-PROMS Security Access Module (VESAM) may need to be used to set permissions to access the new plant."); _Title=tmpTitle; _Location=tmpLocation; changeTitle=false; changeLocation=false; // 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 idx = usrRunTime.sec.GetPlantSecurityIndex(curpath); accessFlags = usrRunTime.sec.GetPlantSecurity(idx); return true; } 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