348 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			348 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.IO;
 | 
						|
using System.Linq;
 | 
						|
using System.Text;
 | 
						|
using System.Text.RegularExpressions;
 | 
						|
using System.Xml;
 | 
						|
using VEPROMS.CSLA.Library;
 | 
						|
 | 
						|
namespace VEPROMS
 | 
						|
{
 | 
						|
    //C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
 | 
						|
    //class inherits from normal import/export form
 | 
						|
    //then adds additional functionality
 | 
						|
#pragma warning disable S101 // Types should be named in PascalCase
 | 
						|
    public partial class dlgExportImportEP : dlgExportImport
 | 
						|
#pragma warning restore S101 // Types should be named in PascalCase
 | 
						|
	{
 | 
						|
		private readonly AnnotationTypeInfo _AnnotationType;
 | 
						|
        private readonly string multiseparator = ",";
 | 
						|
 | 
						|
		private static Regex _ROAccPageTokenPattern = new Regex("[<][^<>-]+-[^<>]+[>]");
 | 
						|
 | 
						|
        public dlgExportImportEP(string mode, FolderInfo folderInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId, int unitIndex = 0) : base(mode, folderInfo, myFrmVEPROMS, ( unitIndex))
 | 
						|
        {
 | 
						|
            _AnnotationType = AnnotationTypeInfo.Get(annotationTypeId);
 | 
						|
            _ExportBothConvertedandNot = true;
 | 
						|
            DocReplace = new Dictionary<int, byte[]>();
 | 
						|
            FormClosed += OnClose;
 | 
						|
            Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {folderInfo.Name}";
 | 
						|
		}
 | 
						|
        public dlgExportImportEP(string mode, DocVersionInfo docVersionInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId, int unitIndex = 0) : base(mode, docVersionInfo, myFrmVEPROMS, (unitIndex))
 | 
						|
        {
 | 
						|
            _AnnotationType = AnnotationTypeInfo.Get(annotationTypeId);
 | 
						|
            _ExportBothConvertedandNot = true;
 | 
						|
            DocReplace = new Dictionary<int, byte[]>();
 | 
						|
            FormClosed += OnClose;
 | 
						|
            Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {docVersionInfo.Name} of {docVersionInfo.MyFolder.Name}";
 | 
						|
		}
 | 
						|
        public dlgExportImportEP(string mode, ProcedureInfo procedureInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId, int unitIndex = 0) : base(mode, procedureInfo, myFrmVEPROMS, (unitIndex))
 | 
						|
		{
 | 
						|
			_AnnotationType = AnnotationTypeInfo.Get(annotationTypeId);
 | 
						|
			_ExportBothConvertedandNot = true;
 | 
						|
			DocReplace = new Dictionary<int, byte[]>();
 | 
						|
			FormClosed += OnClose;
 | 
						|
			Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {procedureInfo.DisplayNumber}";
 | 
						|
		}
 | 
						|
 | 
						|
		//Overridden function to handle export of EP data
 | 
						|
		protected override void ExportEPAnnotationInfo(XmlElement xe, ItemInfo ii)
 | 
						|
		{
 | 
						|
			if (_UnitIndex > 0)
 | 
						|
            {
 | 
						|
				ii.MyDocVersion.DocVersionConfig.SelectedSlave = _UnitIndex;
 | 
						|
				ii.MyProcedure.MyDocVersion.DocVersionConfig.SelectedSlave = _UnitIndex;
 | 
						|
            }
 | 
						|
 | 
						|
            //switch to handle customizations for different formats
 | 
						|
            switch (ii.ActiveFormat.PlantFormat.EPFormatFiles.Find(x => x.AnnotationTypeID == _AnnotationType.TypeID)?.Name)
 | 
						|
			{
 | 
						|
				default:
 | 
						|
					ExportEPAnnotationInfo_Default(xe, ii);
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			ii.MyDocVersion.DocVersionConfig.SelectedSlave = 0;
 | 
						|
			ii.MyProcedure.MyDocVersion.DocVersionConfig.SelectedSlave = 0;
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
		//default export of EP Data
 | 
						|
		private void ExportEPAnnotationInfo_Default(XmlElement xe, ItemInfo ii)
 | 
						|
		{
 | 
						|
			//Add tab text to item
 | 
						|
			string steptab = Volian.Print.Library.PDFReport.BuildStepTab(ii);
 | 
						|
			xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "StepTab", steptab));
 | 
						|
 | 
						|
			//Add db sequence to item
 | 
						|
			string dbsequence = dbSeq(ii);
 | 
						|
			xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "dbsequence", dbsequence));
 | 
						|
 | 
						|
			//get first transition in item and add it as an xml element
 | 
						|
			if (ii.MyContent.ContentTransitionCount > 0)
 | 
						|
			{
 | 
						|
				TransitionInfo ct = ii.MyContent.ContentTransitions[0];
 | 
						|
				xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "TransitionToItemID", ct.ToID.ToString()));
 | 
						|
				xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "TransitionTodbsequence", dbSeq(ct.ToID)));
 | 
						|
			}
 | 
						|
 | 
						|
			//export EP annotation details under an EPInfo node
 | 
						|
			if (ii.ItemAnnotations != null)
 | 
						|
			{
 | 
						|
				XmlElement xepinfo = xe.OwnerDocument.CreateElement("EPInfo");
 | 
						|
 | 
						|
				EPFields myEPFields = ii.GetValidEPFields(_AnnotationType.TypeID);
 | 
						|
				ROFSTLookup lookup = ii.MyDocVersion.DocVersionAssociations[0].MyROFst.GetROFSTLookup(ii.MyDocVersion);
 | 
						|
				bool epexportblank = ii.EPexportblank(_AnnotationType.TypeID); //should blank xml elements export?
 | 
						|
 | 
						|
				//grab the current RO db so will know location of RO files and default graphics ext.
 | 
						|
                using (RODbInfo myRODB = (RODbInfoList.Get()).FirstOrDefault(x => x.RODbID == ii.MyDocVersion.DocVersionAssociations[0].MyROFst.RODbID))
 | 
						|
                {
 | 
						|
					//For each annotation in the item that is of the current EP Annotation type
 | 
						|
					foreach (var EPAnnotation in ii.ItemAnnotations.Where(x => x.TypeID == _AnnotationType.TypeID))
 | 
						|
					{
 | 
						|
						var EPAnnotationConfig = new AnnotationConfig(EPAnnotation.Config);
 | 
						|
 | 
						|
						XmlElement xepdetails = xe.OwnerDocument.CreateElement("Details");
 | 
						|
						//include the annotation ID for reference
 | 
						|
						xepdetails.Attributes.SetNamedItem(AddAttribute(xepdetails.OwnerDocument, "AnnotationID", EPAnnotation.AnnotationID.ToString()));
 | 
						|
 | 
						|
						//loop through each EP Field - name the xml elements the EP.name
 | 
						|
						foreach (EPField EP in myEPFields)
 | 
						|
						{
 | 
						|
							string val = EPAnnotationConfig.GetValue("EP", EP.name);
 | 
						|
 | 
						|
							if (epexportblank || !string.IsNullOrEmpty(val))
 | 
						|
							{
 | 
						|
 | 
						|
								if (_UnitIndex != 0)
 | 
						|
								{
 | 
						|
									val = DisplayText.ResolveUnitSpecific(ii.MyDocVersion, val);
 | 
						|
								}
 | 
						|
 | 
						|
								XmlElement xindivid = xe.OwnerDocument.CreateElement(EP.name);
 | 
						|
 | 
						|
								//need to resolve ROs ROSingle, ROMulti, in text
 | 
						|
								//get values
 | 
						|
								switch (EP.type.ToLower())
 | 
						|
								{
 | 
						|
									case "text":
 | 
						|
 | 
						|
										//for text, check if any embedded ROs
 | 
						|
										//if none, set the xml element to the text
 | 
						|
										//otherwise resolve the ROs
 | 
						|
										MatchCollection matches = _ROAccPageTokenPattern.Matches(val);
 | 
						|
										if (matches.Count == 0)
 | 
						|
										{
 | 
						|
											xindivid.InnerText = val;
 | 
						|
										}
 | 
						|
										else
 | 
						|
										{
 | 
						|
											//resolve ROs
 | 
						|
											//text ROs will replace the AccID key in the text
 | 
						|
											//for binary objects like images,
 | 
						|
											//we will keep the AccID in the text and output the binary as a separate child
 | 
						|
											//XML element with the same xml name as the AccID
 | 
						|
											foreach (Match m in matches)
 | 
						|
											{
 | 
						|
												ROFSTLookup.rochild roc = lookup.GetROChildByAccPageID(m.Groups[0].Value);
 | 
						|
 | 
						|
												// Exclude replacing Images since are binary - for those, add a sub item
 | 
						|
												if (Enumerable.Range(8, 15).Contains(roc.type))
 | 
						|
												{
 | 
						|
													xindivid.InnerText = val;
 | 
						|
 | 
						|
													XmlElement xroid = AddGraphic(xindivid, m.Groups[0].Value, roc, myRODB, roc.type != 8);
 | 
						|
 | 
						|
													xindivid.AppendChild(xroid);
 | 
						|
												}
 | 
						|
												else if (!string.IsNullOrEmpty(roc.value))
 | 
						|
												{
 | 
						|
													bool convertCaretToDeltaSymbol = (ii.ActiveSection != null) && ii.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta;
 | 
						|
 | 
						|
													string rocvalue = roc.value.Replace("`", "\xB0");
 | 
						|
													rocvalue = rocvalue.Replace("\xF8", "\xB0");
 | 
						|
													rocvalue = rocvalue.Replace("\x7F", "\x394"); //delta
 | 
						|
													if (convertCaretToDeltaSymbol) rocvalue = rocvalue.Replace("^", "\x394"); // delta
 | 
						|
													val = val.Replace($"{m.Groups[0].Value}", rocvalue);
 | 
						|
													xindivid.InnerText = val;
 | 
						|
												}
 | 
						|
											}
 | 
						|
										}
 | 
						|
										break;
 | 
						|
									case "rosingle":
 | 
						|
										//Get the output columns from the EPFormatFile
 | 
						|
										//set the "Item" nodes value = to those resolved items
 | 
						|
										//separated by multiseparator
 | 
						|
										XmlElement xindivid_rosingle = xindivid.OwnerDocument.CreateElement("Item");
 | 
						|
										xindivid_rosingle.Attributes.SetNamedItem(AddAttribute(xindivid_rosingle.OwnerDocument, "ROID", val));
 | 
						|
 | 
						|
										//add values specified in EP input list
 | 
						|
										List<string> ro_single_tmp = EP.getROValuesList(EPAnnotation, val);
 | 
						|
										xindivid_rosingle.InnerText = String.Join(multiseparator, ro_single_tmp.ToArray());
 | 
						|
 | 
						|
										//if image, add location and binary of image
 | 
						|
										// - images are type 8
 | 
						|
										//   but if multiple return values could combine
 | 
						|
										//   for example an text (1) + image (8) would be 9
 | 
						|
										ROFSTLookup.rochild roc_single = lookup.GetRoChild(val);
 | 
						|
										if (Enumerable.Range(8, 15).Contains(roc_single.type))
 | 
						|
										{
 | 
						|
											XmlElement xroid = AddGraphic(xindivid, val, roc_single, myRODB, roc_single.type != 8);
 | 
						|
											xindivid_rosingle.AppendChild(xroid);
 | 
						|
										}
 | 
						|
 | 
						|
										xindivid.AppendChild(xindivid_rosingle);
 | 
						|
										break;
 | 
						|
									case "romulti":
 | 
						|
										//Get the output columns from the EPFormatFile
 | 
						|
										//create an "Item" subnode for each selected RO
 | 
						|
										//set the nodes value = to those resolved items
 | 
						|
										//separated by multiseparator
 | 
						|
										foreach (string ival in val.Split(multiseparator.ToCharArray()))
 | 
						|
										{
 | 
						|
											XmlElement xindivid_romulti = xindivid.OwnerDocument.CreateElement("Item");
 | 
						|
											xindivid_romulti.Attributes.SetNamedItem(AddAttribute(xindivid_romulti.OwnerDocument, "ROID", ival));
 | 
						|
 | 
						|
											//add values specified in EP input list
 | 
						|
											List<string> ro_multi_tmp = EP.getROValuesList(EPAnnotation, ival);
 | 
						|
											xindivid_romulti.InnerText = String.Join(multiseparator, ro_multi_tmp.ToArray());
 | 
						|
 | 
						|
											//if image, add location and binary of image
 | 
						|
											// - images are type 8
 | 
						|
											//   but if multiple return values could combine
 | 
						|
											//   for example an text (1) + image (8) would be 9
 | 
						|
											ROFSTLookup.rochild roc_multi = lookup.GetRoChild(ival);
 | 
						|
											if (Enumerable.Range(8, 15).Contains(roc_multi.type))
 | 
						|
											{
 | 
						|
												XmlElement xroid = AddGraphic(xindivid, ival, roc_multi, myRODB, roc_multi.type != 8);
 | 
						|
												xindivid_romulti.AppendChild(xroid);
 | 
						|
											}
 | 
						|
 | 
						|
											xindivid.AppendChild(xindivid_romulti);
 | 
						|
										}
 | 
						|
										break;
 | 
						|
									case "tableinput":
 | 
						|
										xindivid.InnerText = val;
 | 
						|
										break;
 | 
						|
									default:
 | 
						|
										xindivid.InnerText = val;
 | 
						|
										break;
 | 
						|
								}
 | 
						|
								xepdetails.AppendChild(xindivid);
 | 
						|
							}
 | 
						|
						}
 | 
						|
						xepinfo.AppendChild(xepdetails);
 | 
						|
					}
 | 
						|
 | 
						|
				}
 | 
						|
 | 
						|
				xe.AppendChild(xepinfo);
 | 
						|
			}
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
		//return a db sequence string from an Item ID
 | 
						|
		private string dbSeq(int itemID)
 | 
						|
		{
 | 
						|
			using (ItemInfo ii = ItemInfo.Get(itemID))
 | 
						|
            {
 | 
						|
				return dbSeq(ii);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
        //return a db sequence string from an ItemInfo
 | 
						|
        private string dbSeq(ItemInfo ii) => $"{((FolderInfo)ii.MyDocVersion.ActiveParent).Name}:{ii.MyProcedure.DisplayNumber} {ii.MyProcedure.DisplayText}:{ii.DBSequence}";
 | 
						|
 | 
						|
        //For Exporting an RO that is an image
 | 
						|
        //returns the Location and FileName of the RO Image
 | 
						|
        private string GetROImageFileLocation(ROFSTLookup.rochild roc, RODbInfo rodb, bool isMulti)
 | 
						|
		{
 | 
						|
			string rodbpath = rodb.FolderPath;
 | 
						|
 | 
						|
			string rocval = roc.value;
 | 
						|
			if (rocval == null) rocval = Array.Find(roc.children, x => x.value.Contains('.')).value;
 | 
						|
 | 
						|
			if (rocval == null) return "";
 | 
						|
			string imgname;
 | 
						|
			if (isMulti)
 | 
						|
			{
 | 
						|
				imgname = rocval.Substring(rocval.IndexOf(' ') + 1, rocval.IndexOf("\r\n") - rocval.IndexOf(' ') - 1);
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				imgname = rocval.Substring(0, rocval.IndexOf('\n'));
 | 
						|
			}
 | 
						|
			int thedot = imgname.LastIndexOf('.');
 | 
						|
			string fname = imgname;
 | 
						|
			if (thedot == -1 || (thedot != (imgname.Length - 4)))
 | 
						|
			{
 | 
						|
				RODbConfig roDbCfg = new RODbConfig(rodb.Config);
 | 
						|
				fname += string.Format(".{0}", roDbCfg.GetDefaultGraphicExtension());
 | 
						|
			}
 | 
						|
 | 
						|
			string imgfile = Path.Combine(rodbpath, fname);
 | 
						|
			return imgfile;
 | 
						|
		}
 | 
						|
 | 
						|
		//For Exporting an RO that is an image
 | 
						|
		//returns an xmlElement
 | 
						|
		// - that is a child to xindivid
 | 
						|
		// - that has a name of Name
 | 
						|
		// - that has a value of the binary representation of the image
 | 
						|
		// - that has an attribute designating the location of the image file
 | 
						|
		private XmlElement AddGraphic(XmlElement xindivid, string Name, ROFSTLookup.rochild roc, RODbInfo rodb, bool isMulti)
 | 
						|
		{
 | 
						|
            Name = Name.Replace("<", "").Replace(">", "");
 | 
						|
 | 
						|
			XmlElement xroid = xindivid.OwnerDocument.CreateElement(Name);
 | 
						|
 | 
						|
			string imgfile = GetROImageFileLocation(roc, rodb, isMulti);
 | 
						|
			if (string.IsNullOrEmpty(imgfile)) return xroid;
 | 
						|
			xroid.Attributes.SetNamedItem(AddAttribute(xroid.OwnerDocument, "Location", imgfile));
 | 
						|
 | 
						|
			if (File.Exists(imgfile))
 | 
						|
			{
 | 
						|
				using (FileStream fsIn = new FileStream(imgfile, FileMode.Open, FileAccess.Read, FileShare.Read))
 | 
						|
				{
 | 
						|
					// Create an instance of StreamReader that can read characters from the FileStream.
 | 
						|
					using (BinaryReader r = new BinaryReader(fsIn))
 | 
						|
						xroid.InnerText = Encoding.Default.GetString(r.ReadBytes((int)fsIn.Length));
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			return xroid;
 | 
						|
		}
 | 
						|
 | 
						|
		//overridden - used to set the RO location for RO Images that are not in annotations
 | 
						|
		protected override void SetROLocation(ref XmlElement xindivid, ROFSTLookup.rochild roc, RODbInfo rodb, bool isMulti)
 | 
						|
		{
 | 
						|
			string imgfile = GetROImageFileLocation(roc, rodb, isMulti);
 | 
						|
			if (!string.IsNullOrEmpty(imgfile)) xindivid.Attributes.SetNamedItem(AddAttribute(xindivid.OwnerDocument, "Location", imgfile));
 | 
						|
		}
 | 
						|
 | 
						|
		//overridden - used to set specific enhanced doc info
 | 
						|
		protected override void SetEPEnhancedDocLinks(ref XmlElement xe, ItemInfo ii)
 | 
						|
		{
 | 
						|
			EnhancedDocuments eds = ii.GetMyEnhancedDocuments();
 | 
						|
 | 
						|
			if (eds != null && eds.Count == 1)
 | 
						|
			{
 | 
						|
				xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "EnhancedDocType", eds[0].Type.ToString()));
 | 
						|
				xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "EnhancedDocToItemID", eds[0].ItemID.ToString()));
 | 
						|
				xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "EnhancedDocToDbSeq", dbSeq(eds[0].ItemID)));
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		//clear objects to release memory
 | 
						|
		private void OnClose(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			DocReplace.Clear();
 | 
						|
			DocReplace = null;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
	}
 | 
						|
}
 |