From ec8e4c36a4edac5f8277f16443c4ad40298acf0c Mon Sep 17 00:00:00 2001 From: mschill Date: Fri, 11 Jul 2025 15:26:22 -0400 Subject: [PATCH] C2025-024 Electronic Procedures - Phase 2 (PROMS XML output) RO image resolution for Annotations --- PROMS/Formats/fmtall/EPTST1all.xml | Bin 62412 -> 62450 bytes .../dlgExportImportEP.cs | 273 ++++++++++++------ .../VEPROMS.CSLA.Library/Extension/ItemExt.cs | 240 +++++++-------- .../Format/EPFormatFile.cs | 12 + 4 files changed, 325 insertions(+), 200 deletions(-) diff --git a/PROMS/Formats/fmtall/EPTST1all.xml b/PROMS/Formats/fmtall/EPTST1all.xml index 0c3557429df9140891079c371b19bba5178b941e..148469dde4b4730181ff02c6960ffb2d10d9f3eb 100644 GIT binary patch delta 46 zcmX@}ocYsp<_#`P(y0s;3-]+-[^<>]+[>]"); @@ -66,11 +69,16 @@ namespace VEPROMS 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 @@ -79,110 +87,143 @@ namespace VEPROMS 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? - //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) + //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)) { - string val = EPAnnotationConfig.GetValue("EP", EP.name); + var EPAnnotationConfig = new AnnotationConfig(EPAnnotation.Config); - XmlElement xindivid = xe.OwnerDocument.CreateElement(EP.name); + XmlElement xepdetails = xe.OwnerDocument.CreateElement("Details"); + //include the annotation ID for reference + xepdetails.Attributes.SetNamedItem(AddAttribute(xepdetails.OwnerDocument, "AnnotationID", EPAnnotation.AnnotationID.ToString())); - //need to resolve ROs ROSingle, ROMulti, in text - //get values - //should we export blank? - // - switch (EP.type.ToLower()) + //loop through each EP Field - name the xml elements the EP.name + foreach (EPField EP in myEPFields) { - case "text": + string val = EPAnnotationConfig.GetValue("EP", EP.name); - //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) + if (epexportblank || !string.IsNullOrEmpty(val)) + { + XmlElement xindivid = xe.OwnerDocument.CreateElement(EP.name); + + //need to resolve ROs ROSingle, ROMulti, in text + //get values + switch (EP.type.ToLower()) { - 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); + case "text": - - if (roc.type == 8) // Exclude replacing Images since are binary - for those, add a sub item + //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) { - XmlElement xroid = xindivid.OwnerDocument.CreateElement(m.Groups[1].Value); - xroid.InnerText = roc.value; - xindivid.AppendChild(xroid); + xindivid.InnerText = val; } - else if (!string.IsNullOrEmpty(roc.value)) + else { - bool convertCaretToDeltaSymbol = (ii.ActiveSection != null) && ii.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta; + //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); - 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); + // 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[1].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[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)); + + //add values specified in EP input list + List 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)); - xindivid.InnerText = val; + //add values specified in EP input list + List 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; } - 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); + } } - xepdetails.AppendChild(xindivid); + xepinfo.AppendChild(xepdetails); } - xepinfo.AppendChild(xepdetails); } xe.AppendChild(xepinfo); @@ -190,6 +231,68 @@ namespace VEPROMS } + //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) + { + return $"{((FolderInfo)ii.MyDocVersion.ActiveParent).Name}:{ii.DBSequence}"; + } + + //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) + { + XmlElement xroid = xindivid.OwnerDocument.CreateElement(Name); + 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 xroid; + 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); + 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; + } + //clear objects to release memory private void OnClose(object sender, EventArgs e) { diff --git a/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs b/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs index b0649cc6..1f1e9a7c 100644 --- a/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs +++ b/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs @@ -346,21 +346,21 @@ namespace VEPROMS.CSLA.Library { var ii = _CacheByPrimaryKey.FirstOrDefault(); - while (ii.Value.Count > 0) - { - if (ii.Value[0]?.MyContent?.ContentParts != null) - { foreach (PartInfo pi in ii.Value[0]?.MyContent?.ContentParts) pi.Dispose(); } - ii.Value[0].Dispose(); - } + while (ii.Value.Count > 0) + { + if (ii.Value[0]?.MyContent?.ContentParts != null) + { foreach (PartInfo pi in ii.Value[0]?.MyContent?.ContentParts) pi.Dispose(); } + ii.Value[0].Dispose(); + } _CacheByPrimaryKey.Remove(ii.Key); } while (_CacheList.Count > 0) - { - if (_CacheList[0]?.MyContent?.ContentParts != null) - {foreach (PartInfo pi in _CacheList[0]?.MyContent?.ContentParts) pi.Dispose(); } - _CacheList[0].Dispose(); - } + { + if (_CacheList[0]?.MyContent?.ContentParts != null) + {foreach (PartInfo pi in _CacheList[0]?.MyContent?.ContentParts) pi.Dispose(); } + _CacheList[0].Dispose(); + } } private bool _PrintAllAtOnce = false; @@ -450,86 +450,86 @@ namespace VEPROMS.CSLA.Library StringBuilder sret = new StringBuilder(); ItemInfo pitem = this; while (!pitem.IsSection && !pitem.IsHigh) - { + { using (StepInfo stpinfo = StepInfo.Get(pitem.ItemID)) - { - string thisTab = stpinfo.MyTab.CleanText; + { + string thisTab = stpinfo.MyTab.CleanText; - string typeName = stpinfo.FormatStepData.StepEditData.TypeMenu.MenuItem; + string typeName = stpinfo.FormatStepData.StepEditData.TypeMenu.MenuItem; - if (!string.IsNullOrEmpty(thisTab)) - { - thisTab = thisTab.Trim(); - } + if (!string.IsNullOrEmpty(thisTab)) + { + thisTab = thisTab.Trim(); + } - // if the tab is null or - // if the the tab is not a letter or number OR - // the tab is an AND or OR type and is the letter "o" - // then reset the tab an empty string so that the type name along with the count of that type - // (ex. "AND 2", "OR 3") - if (string.IsNullOrEmpty(thisTab) || (thisTab != string.Empty && (!(char.IsLetterOrDigit(thisTab[0])) || ((pitem.IsAnd || pitem.IsOr || pitem.IsCaution || pitem.IsNote) && thisTab.Contains("o"))))) - { - thisTab = string.Empty; - } + // if the tab is null or + // if the the tab is not a letter or number OR + // the tab is an AND or OR type and is the letter "o" + // then reset the tab an empty string so that the type name along with the count of that type + // (ex. "AND 2", "OR 3") + if (string.IsNullOrEmpty(thisTab) || (thisTab != string.Empty && (!(char.IsLetterOrDigit(thisTab[0])) || ((pitem.IsAnd || pitem.IsOr || pitem.IsCaution || pitem.IsNote) && thisTab.Contains("o"))))) + { + thisTab = string.Empty; + } - if (pitem.IsRNOPart) - { - if (string.IsNullOrEmpty(thisTab)) - { - sret.Insert(0, "RNO."); - } - else - { - thisTab = thisTab.Trim(); + if (pitem.IsRNOPart) + { + if (string.IsNullOrEmpty(thisTab)) + { + sret.Insert(0, "RNO."); + } + else + { + thisTab = thisTab.Trim(); - if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) - { - thisTab += "."; - } + if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) + { + thisTab += "."; + } - sret.Insert(0, "RNO." + thisTab); - } - } - else if (pitem.IsCaution || pitem.IsNote) - { - // add the Caution or Note count to the tab (ex "Caution 1", "Note 2") - if (string.IsNullOrEmpty(thisTab)) - { - sret.Append("{" + typeName + " " + pitem.Ordinal.ToString() + "}"); - } - else - { - thisTab = thisTab.Trim(" ".ToCharArray()); - sret.Append(thisTab + " " + pitem.Ordinal.ToString() + sret); - } - } - else - { - if (!string.IsNullOrEmpty(thisTab)) - { - thisTab = thisTab.Trim(" ".ToCharArray()); + sret.Insert(0, "RNO." + thisTab); + } + } + else if (pitem.IsCaution || pitem.IsNote) + { + // add the Caution or Note count to the tab (ex "Caution 1", "Note 2") + if (string.IsNullOrEmpty(thisTab)) + { + sret.Append("{" + typeName + " " + pitem.Ordinal.ToString() + "}"); + } + else + { + thisTab = thisTab.Trim(" ".ToCharArray()); + sret.Append(thisTab + " " + pitem.Ordinal.ToString() + sret); + } + } + else + { + if (!string.IsNullOrEmpty(thisTab)) + { + thisTab = thisTab.Trim(" ".ToCharArray()); - if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) - { - thisTab += "."; - } - } - else - { - thisTab = "{" + typeName + " " + pitem.Ordinal.ToString() + "}."; - } + if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) + { + thisTab += "."; + } + } + else + { + thisTab = "{" + typeName + " " + pitem.Ordinal.ToString() + "}."; + } - sret.Insert(0, thisTab); - } - } + sret.Insert(0, thisTab); + } + } - pitem = pitem.ActiveParent as ItemInfo; + pitem = pitem.ActiveParent as ItemInfo; - if (pitem == null) - break; - } + if (pitem == null) + break; + } - return sret.ToString().Trim(" .)".ToCharArray()); + return sret.ToString().Trim(" .)".ToCharArray()); } public void SetHeader(VE_Font myFont, string myText) @@ -574,11 +574,11 @@ namespace VEPROMS.CSLA.Library } _MyPrevious = null; // Reset list so that the next line gets a new list if (MyPrevious != null) MyPrevious.RefreshNextItems(); // Update List for new value - //if (_ContentID != tmp.ContentID) - //{ + //if (_ContentID != tmp.ContentID) + //{ if (MyContent != null) MyContent.RefreshContentItems(); // Update List for old value _ContentID = tmp.ContentID; // Update the value - //} + //} _MyContent = null; // Reset list so that the next line gets a new list if (MyContent != null) MyContent.RefreshContentItems(); // Update List for new value _DTS = tmp.DTS; @@ -674,12 +674,12 @@ namespace VEPROMS.CSLA.Library } } } - + internal static void SetParentSectionAndDocVersion(ItemInfo itemInfo, IVEDrillDownReadOnly itemParent, SectionInfo sectionInfo, ProcedureInfo procInfo, DocVersionInfo docVersionInfo, bool isAutomatic = false) { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Optional Parameter "bool isAutomatic = false" to disable the RofstLoadingStatus pop-up screen when printing baselines - + if (itemInfo == null) return; itemInfo.LoadAllAtOnce = true; itemInfo.ActiveParent = itemParent; @@ -721,7 +721,7 @@ namespace VEPROMS.CSLA.Library } } } - + /// /// The following method is used only in print because the 'printed' data is loaded into /// memory before printing. Find the next item from memory (do not go out to database). @@ -784,7 +784,7 @@ namespace VEPROMS.CSLA.Library { bool forceConvertToText = false; TranCheckCount++; - + if (!forceConvertToText) { if (traninfo.MyItemToID.ActiveSection != null) @@ -802,7 +802,7 @@ namespace VEPROMS.CSLA.Library content.FixTransitionText(traninfo, true); content.Save(); } - } + } } // B2025-020 Null Reference fix. Added check for valid index into the TransitionTypeList if (!forceConvertToText) @@ -812,7 +812,7 @@ namespace VEPROMS.CSLA.Library forceConvertToText = true; TranFixCount++; itemInfo.MyContent.FixTransitionText(traninfo, itemInfo, "Reason for Change: Transition type is not available"); - using (Content content = Content.Get(itemInfo.MyContent.ContentID)) + using (Content content = Content.Get(itemInfo.MyContent.ContentID)) { content.FixTransitionText(traninfo, true); content.Save(); @@ -835,14 +835,14 @@ namespace VEPROMS.CSLA.Library content.FixTransitionText(traninfo, true); content.Save(); } - } + } } } } if (!forceConvertToText) { - if (itemInfo.MyDocVersion != null && traninfo.MyItemToID.MyDocVersion != null && itemInfo.MyDocVersion.VersionID != traninfo.MyItemToID.MyDocVersion.VersionID) //different doc version + if (itemInfo.MyDocVersion != null && traninfo.MyItemToID.MyDocVersion != null && itemInfo.MyDocVersion.VersionID != traninfo.MyItemToID.MyDocVersion.VersionID) //different doc version { if (!itemInfo.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[traninfo.TranType].TransMenu.Contains("Proc")) //internal format { @@ -903,7 +903,7 @@ namespace VEPROMS.CSLA.Library if (itemInfo.MyContent.Text.Contains("Link:Transition")) { Content content = Content.Get(itemInfo.MyContent.ContentID); - + if (itemInfo.MyContent.ContentTransitions != null) { foreach (TransitionInfo ct in itemInfo.MyContent.ContentTransitions) @@ -913,7 +913,7 @@ namespace VEPROMS.CSLA.Library } itemInfo.MyContent.RefreshContentTransitions(); - + while (content.Text.Contains("Link:Transition")) { TranCheckCount++; @@ -931,7 +931,7 @@ namespace VEPROMS.CSLA.Library else // B2018-043 Eliminate infinite loop for invalid transition structure { // Add annotation for Invalid Transition - AddInvalidTransitionAnnotation(itemInfo,"Invalid Transition Format"); + AddInvalidTransitionAnnotation(itemInfo, "Invalid Transition Format"); break; } } @@ -984,16 +984,16 @@ namespace VEPROMS.CSLA.Library ContentInfo myContent = itemInfo.MyContent; string txt = myContent.Text; string regDelete = @"(\\v |)\(\\v0 |)"; - string txt2=txt; + string txt2 = txt; - do{ + do { txt = txt2; txt2 = Regex.Replace(txt, regDelete, ""); - } while(txt2 != txt); + } while (txt2 != txt); - if(txt2 != myContent.Text) + if (txt2 != myContent.Text) { - using(Content tmp = myContent.Get()) + using (Content tmp = myContent.Get()) { tmp.Text = txt2; tmp.Save(); @@ -1001,7 +1001,7 @@ namespace VEPROMS.CSLA.Library AddInvalidTransitionAnnotation(itemInfo, "Removed Empty Transition Text"); } } - + private static bool IsTransitionToNonEditable(TransitionInfo ti) { foreach (TransitionInfo til in TransitionsToNonEditable) @@ -1032,7 +1032,7 @@ namespace VEPROMS.CSLA.Library public static int ROCheckCount = 0; public static int ROFixCount = 0; private static AnnotationType _VolianCommentType = null; // Using this to flag ro value issues with byron to braidwood - + public static AnnotationType VolianCommentType { get @@ -1065,7 +1065,7 @@ namespace VEPROMS.CSLA.Library string roval = lookup.GetTranslatedRoValue(rousage.ROID, this.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, this.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, false, this); ROFSTLookup.rochild roch = lookup.GetRoChild(rousage.ROID); - + this.MyContent.FixContentText(rousage, roval, roch.type, rofstinfo, this); string newText = this.MyContent.Text; @@ -1263,7 +1263,7 @@ namespace VEPROMS.CSLA.Library } } } - + public static string GetCombinedTab(ItemInfo itemInfo, string parTab) { string pTab = parTab == null ? "" : parTab; @@ -1276,7 +1276,7 @@ namespace VEPROMS.CSLA.Library // for supplemental information, bulleted tabs need to be included in the tab. The 'isletterordigit' should not occur for supinfo items - // and this includes the parent of the supinfo since that is the tab used for supinfo concatenated with its parent. (B2017-120) // // B2020-154: Added check for the tab to start with '(', tabs that started with this were not included in the combined tab - if (thisTab != null && thisTab != "" && (!char.IsLetterOrDigit(thisTab[0]) && thisTab[0] != '(') && !vcbHeaderCheck && !itemInfo.IsInSupInfo && (itemInfo.SupInfos == null || itemInfo.SupInfos.Count <= 0 )) return pTab; + if (thisTab != null && thisTab != "" && (!char.IsLetterOrDigit(thisTab[0]) && thisTab[0] != '(') && !vcbHeaderCheck && !itemInfo.IsInSupInfo && (itemInfo.SupInfos == null || itemInfo.SupInfos.Count <= 0)) return pTab; if (itemInfo.FormatStepData.NumberWithLevel) pTab = itemInfo.MyHLS.MyTab.CleanText.Trim(); // if the parent tab ends with a alphanumeric and this tab is alphanumeric, add a '.' to separate them // also, include use the separator for bullets if doing the supplemental information tab (B2017-120) @@ -1285,7 +1285,7 @@ namespace VEPROMS.CSLA.Library if (ms && mn) pTab = pTab.TrimEnd() + "."; // remove ending '.' (if this is a hls, don't remove the '.') if (!itemInfo.IsHigh && thisTab.EndsWith(".")) thisTab = thisTab.Substring(0, thisTab.Length - 1); - if (itemInfo.HasParentTab) return thisTab.Trim(); // F2020-023: if tab includes parent tab already, don't concatenate it + if (itemInfo.HasParentTab) return thisTab.Trim(); // F2020-023: if tab includes parent tab already, don't concatenate it return pTab + thisTab.Trim(); } @@ -1341,8 +1341,8 @@ namespace VEPROMS.CSLA.Library // B2023-037: loading print text, resolve the RO symbols bool GTLT = !itemInfo.IsTable && sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertGTELTEPMinROValue; - bool GLTArrows = !itemInfo.IsTable && sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseDashGreaterLessThenForArrowsInROValue; - string roval = lookup.GetTranslatedRoValue(rousage.ROID, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, GTLT || GLTArrows, itemInfo); + bool GLTArrows = !itemInfo.IsTable && sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseDashGreaterLessThenForArrowsInROValue; + string roval = lookup.GetTranslatedRoValue(rousage.ROID, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, GTLT || GLTArrows, itemInfo); ROFSTLookup.rochild roch = lookup.GetRoChild(rousage.ROID); itemInfo.MyContent.FixContentText(rousage, roval, roch.type, rofstinfo, itemInfo); } @@ -1367,7 +1367,7 @@ namespace VEPROMS.CSLA.Library } } } - + if (itemInfo.MyContent.ContentTransitionCount > 0) { foreach (TransitionInfo traninfo in itemInfo.MyContent.ContentTransitions) @@ -1440,14 +1440,14 @@ namespace VEPROMS.CSLA.Library private float _MSWordPageCount = 0; public float MSWordPageCount { - get { + get { if (_MSWordPageCount == 0) // C2018-011 Get the proper word page count from the saved pdf attachment if (MyContent.MyEntry != null && MyContent.MyEntry.MyDocument != null) { PdfInfo pi = PdfInfo.Get(this, false); - if(pi != null) _MSWordPageCount = (float)pi.PageCount;// B2018-071 Don't crash on invalid MS Word section + if (pi != null) _MSWordPageCount = (float)pi.PageCount;// B2018-071 Don't crash on invalid MS Word section } - return _MSWordPageCount; + return _MSWordPageCount; } set { _MSWordPageCount = value; } } @@ -1649,7 +1649,7 @@ namespace VEPROMS.CSLA.Library // the addition of the parent.IsNote, the note was breaking between 2 ANDs (the 1st AND was a // steplevel of 5, but the 2nd was a steplevel of 4). If something similar is seen with Cautions, // that check could be added. - if (!item.IsRNOPart && !item.IsHigh && (item.MyPrevious == null || (((item.ActiveFormat.PlantFormat.FormatData.PurchaseOptions & E_PurchaseOptions.EnhancedBackgrounds) != E_PurchaseOptions.EnhancedBackgrounds) + if (!item.IsRNOPart && !item.IsHigh && (item.MyPrevious == null || (((item.ActiveFormat.PlantFormat.FormatData.PurchaseOptions & E_PurchaseOptions.EnhancedBackgrounds) != E_PurchaseOptions.EnhancedBackgrounds) && item.MyParent != null && item.MyParent.IsNote))) level += firstInc; else @@ -1716,7 +1716,7 @@ namespace VEPROMS.CSLA.Library } return maxRNOLevel; } - + } private bool ParentAndOr { @@ -1767,7 +1767,7 @@ namespace VEPROMS.CSLA.Library RemoveEnhancedFromConfig(false); } - public void RemoveEnhancedFromConfig(bool doOneStepOnly) + public void RemoveEnhancedFromConfig(bool doOneStepOnly) { XmlDocument xd = new XmlDocument(); if (this.MyContent.Config == null || this.MyContent.Config == "") return; // B2017-164 & B2017-172 check for null or empty config @@ -1782,7 +1782,7 @@ namespace VEPROMS.CSLA.Library ctmp.Config = config; ctmp.Save(); ContentInfo.Refresh(ctmp); - _MyConfig = null; // refresh the memory value + _MyConfig = null; // refresh the memory value } } if (doOneStepOnly) return; @@ -2071,7 +2071,7 @@ namespace VEPROMS.CSLA.Library { bool rval = false; ItemInfo itm = this; - while (itm != null &&!itm.IsHigh && !rval) + while (itm != null && !itm.IsHigh && !rval) { rval = itm.IsCautionOrNotePart; if (!rval) itm = itm.MyParent; @@ -2111,6 +2111,16 @@ namespace VEPROMS.CSLA.Library return (sd.Type == type); } + // C2025-024 - Electronic Procedures - Export + //return if should export blanks + public bool EPexportblank(int AnnTypeID) + { + if (ActiveFormat.PlantFormat.EPFormatFiles.Count == 0 || !ActiveFormat.PlantFormat.EPFormatFiles.Exists(x => x.AnnotationTypeID == AnnTypeID)) + return true; + else + return ActiveFormat.PlantFormat.EPFormatFiles.Find(x => x.AnnotationTypeID == AnnTypeID).exportblank; + } + // C2025-023 - Electronic Procedures - Modifications to PROMS //return EPFields that match this step type or a parent step type public EPFields GetValidEPFields(int AnnTypeID) diff --git a/PROMS/VEPROMS.CSLA.Library/Format/EPFormatFile.cs b/PROMS/VEPROMS.CSLA.Library/Format/EPFormatFile.cs index 0d2253d2..84b71cc6 100644 --- a/PROMS/VEPROMS.CSLA.Library/Format/EPFormatFile.cs +++ b/PROMS/VEPROMS.CSLA.Library/Format/EPFormatFile.cs @@ -61,6 +61,18 @@ namespace VEPROMS.CSLA.Library return LazyLoad(ref _AnnotationTypeID, "@AnnotationTypeID"); } } + //if xml value is blank, should element export? + //defaults to true + private LazyLoad _exportblank; + [DisplayName("exportblank")] + [Description("if xml value is blank, should element export?")] + public bool exportblank + { + get + { + return LazyLoad(ref _exportblank, "@exportblank"); + } + } // returns a list of fields that are defined in the EP format's structure private EPFields _FieldList; public EPFields FieldList