using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; 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 public partial class dlgExportImportEP : dlgExportImport { private readonly AnnotationTypeInfo _AnnotationType; private string multiseparator = ","; private static Regex _ROAccPageTokenPattern = new Regex("[<][^<>-]+-[^<>]+[>]"); public dlgExportImportEP(string mode, FolderInfo folderInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId) : base(mode, folderInfo, myFrmVEPROMS, (E_UCFImportOptions) 0) { _AnnotationType = AnnotationTypeInfo.Get(annotationTypeId); _ExportBothConvertedandNot = true; DocReplace = new Dictionary(); FormClosed += OnClose; Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {folderInfo.Name}"; } public dlgExportImportEP(string mode, DocVersionInfo docVersionInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId) : base(mode, docVersionInfo, myFrmVEPROMS, (E_UCFImportOptions)0) { _AnnotationType = AnnotationTypeInfo.Get(annotationTypeId); _ExportBothConvertedandNot = true; DocReplace = new Dictionary(); 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) : base(mode, procedureInfo, myFrmVEPROMS, (E_UCFImportOptions)0) { _AnnotationType = AnnotationTypeInfo.Get(annotationTypeId); _ExportBothConvertedandNot = true; DocReplace = new Dictionary(); 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) { //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; } } //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)); //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())); } //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); //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); XmlElement xindivid = xe.OwnerDocument.CreateElement(EP.name); //need to resolve ROs ROSingle, ROMulti, in text //get values //should we export blank? // 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[1].Value); if (roc.type == 8) // Exclude replacing Images since are binary - for those, add a sub item { XmlElement xroid = xindivid.OwnerDocument.CreateElement(m.Groups[1].Value); xroid.InnerText = roc.value; 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[1].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)); List ro_single_tmp = EP.getROValuesList(EPAnnotation, val); xindivid_rosingle.InnerText = String.Join(multiseparator, ro_single_tmp.ToArray()); 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)); List ro_multi_tmp = EP.getROValuesList(EPAnnotation, ival); xindivid_romulti.InnerText = String.Join(multiseparator, ro_multi_tmp.ToArray()); 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); } } //clear objects to release memory private void OnClose(object sender, EventArgs e) { DocReplace.Clear(); DocReplace = null; } } }