using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Xml; using System.IO; using System.Windows.Forms; using VEPROMS.CSLA.Library; using System.Text.RegularExpressions; using System.Xml.Xsl; namespace VEPROMS { // frmUCF is the main form for User Control of Format. It is accessible by Administrator & Set Administrator from the V button Administration // menu. It uses the FormatConfig structure whose data is stored in the Config field of the Formats table. It uses XmlSerialization to // store/retrieve the data from the database field and uses a Windows Property Grid to present the data, the data is tied to the // Property Grid by setting the SelectedObject of the Property Grid to the FormatConfig. FormatConfig objects use TypeConverter(typeof(ExpandableObjectConverter)) on the // fields to allow for accessing the data structures below the FormatConfig level (by default, fields are shown in the grid, Browsable(false) does // not show the fields. NOTE that collection data uses the PropGridCollEditor, see that file for further information (in Volian.Base.Library) // public partial class frmUCF : Form { private bool _UcfForRepWords = false; public bool UcfForRepWords // flags that UCF has changes to replace words - use for Reset button enabling { get { return _UcfForRepWords; } set { _UcfForRepWords = value; } } private FormatConfig MyFormatConfig = new FormatConfig(); private PlantFormat OriginalPlantFormat; private FormatInfo OriginalFormatInfo; public frmUCF() { InitializeComponent(); } private bool _Initializing = false; private void frmUCF_Load(object sender, EventArgs e) { _Initializing = true; PlantFormat.DoingUCFCheckOffs = true; PlantFormat.DoingUCFCheckOffsUse = MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF ?? false; cbxFormatList.DataSource = null; cbxFormatList.DisplayMember = "FullName"; cbxFormatList.ValueMember = "FullName"; cbxFormatList.DataSource = FormatInfoList.GetFormatInfoListUsed(); cbxFormatList.SelectedIndex = -1; MyFormatConfig = new FormatConfig(); PG.SelectedObject = MyFormatConfig; PG.Enabled = false; PG.SelectedGridItemChanged += PG_SelectedGridItemChanged; PG.PropertyValueChanged += PG_PropertyValueChanged; btnSaveAs.Enabled = false; btnSaveClose.Enabled = false; btnSave.Enabled = false; btnReset.Enabled = false; btnDelete.Enabled = false; _Initializing = false; } void PG_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { if (SelectedGridField.EndsWith("Flags:UCF CheckOffs")) { // when changing whether the UCF format has the UCF checkoffs (there is a list of checkoffs/headers in the base format, when this // flag is true, they get added to the list from the starting format), refresh the checkoff header & checkoff lists if ((bool)e.OldValue != MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF) { // refresh the checkoff data in myformatconfig. Need to clear the checkoff header list & checkoff list before // getting new data. PlantFormat.DoingUCFCheckOffsUse = (bool)MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF; GetUCFCheckOffDataForUCFGrid((bool)MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF); PG.Refresh(); } } else if (SelectedGridField.EndsWith(" Name")) // B2019-012: don't allow removal of '_UCF' from name. { if ((string)e.OldValue != MyFormatConfig.Name) { if (((string)e.OldValue).EndsWith("_UCF") && !MyFormatConfig.Name.EndsWith("_UCF")) { MessageBox.Show(this, "Cannot remove '_UCF' from User Controlled Format name", "UCF Name", MessageBoxButtons.OK); MyFormatConfig.Name = MyFormatConfig.Name + ("_UCF"); PG.Refresh(); } } } } private string SelectedGridField = "Identification: Name"; // first field sectioned upon creation of form void PG_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e) { if (_Initializing || _formatListIndexChanging) return; // refresh the summary data textbox data to show summary of what is in this UCF. This occurs when move off of a field which // actually 'stores' the change. FormatConfig tmpfc = GetChangesUCFForSave(); string scf = tmpfc.ConvertToString(); scf = Regex.Replace(scf, " *<[a-zA-Z ]+/>\r\n", ""); SetUCFSummary(scf); // see if data has changed, and if so, enable the Reset button. // Upon selection of a grid item, see if the grid item has data associated with it & if so, see if there has been // a change. Code needs added here for any value listed on the main property grid, i.e. not part of a collection, or // if the collection is reset in its entirety (replace words is an example of this). bool enabled = false; btnReset.Text = "Reset"; string previousSelectedGridField = SelectedGridField; SelectedGridField = LabelPath(PG.SelectedGridItem); // remove the following line before release: lblPGItem.Text = SelectedGridField; if (previousSelectedGridField.EndsWith("Identification: Name") && !SelectedGridField.EndsWith("Identification: Name")) SetButtonSaveAsEnabled(); if (previousSelectedGridField.EndsWith("Data:Plant Format:Step Settings:Replace Words List")) { // if moving off of the replace words, see if any changes exist so that Reset List button is enabled: FormatConfig.ReplaceStrData rps = GetChangedReplaceListForSave(); UcfForRepWords = (rps != null && rps.Count > 0); } if (SelectedGridField.EndsWith("Identification: Name")) enabled = false; else if (SelectedGridField.EndsWith("Data:Plant Format")) enabled = false; else if (SelectedGridField.EndsWith("Data:Plant Format:Section Type Settings")) enabled = false; else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings")) enabled = false; else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags")) enabled = false; else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags:Compress Steps")) { if (MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps != null && MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps != OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CompressSteps) { btnReset.Text = "Reset to " + OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CompressSteps; enabled = true; } } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags:Partial Step Compression")) { if (MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression != null && MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression != OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PartialStepCompression) { btnReset.Text = "Reset to " + OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PartialStepCompression; enabled = true; } } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags:UCF CheckOffs")) { if (MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF != null && MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF != OriginalPlantFormat.FormatData.ProcData.CheckOffUCF) { btnReset.Text = "Reset to " + OriginalPlantFormat.FormatData.ProcData.CheckOffUCF; enabled = true; } } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Replace Words List")) { if (UcfForRepWords) // flags that ucf data exists for replace words. { btnReset.Text = "Reset List"; enabled = true; } } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:CheckOff XOffset")) { if (MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj != null && MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj != 0) // flags that ucf data exists for replace words. { btnReset.Text = "Reset to 0"; enabled = true; } } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Step List")) enabled = false; else enabled = false; btnReset.Enabled = enabled; } // remove the following method for release: private string LabelPath(GridItem gi) { return (gi.Parent == null ? "" : LabelPath(gi.Parent) + ":" + gi.Label); } private void btnSaveClose_Click(object sender, EventArgs e) { // get a FormatConfig structure that only has differences from the original format. This is what gets saved. FormatConfig tmpForSave = GetChangesUCFForSave(); string scf = tmpForSave.ConvertToString(); scf = Regex.Replace(scf, " *<[a-zA-Z ]+/>\r\n", ""); int fmtid = OriginalPlantFormat.MyFormat is Format ? (OriginalPlantFormat.MyFormat as Format).FormatID : (OriginalPlantFormat.MyFormat as FormatInfo).FormatID; // for now, tell the user that changes don't take affect until reentry. This was done since the 'refresh' of FormatConfig was not // working. using (Format fmt = Format.Get(fmtid)) { FormatInfo fi = FormatInfo.GetFormatNoUCFByFormatID(OriginalFormatInfo.FormatID); if (fi.Data == "") { fmt.Data = ""; fmt.GenMac = ""; } fmt.Config = scf; fmt.Name = MyFormatConfig.Name; fmt.Description = MyFormatConfig.Description; fmt.Save(true); MessageBox.Show(this, "Restart PROMS to have format changes take effect.", "", MessageBoxButtons.OK); } OriginalPlantFormat.FormatData.ProcData.CheckOffData.ClearCheckOffAndHeaderLists(); PlantFormat.IgnoreUCF = false; PlantFormat.DoingUCFCheckOffs = false; } private void btnCancel_Click(object sender, EventArgs e) { if (OriginalPlantFormat != null) OriginalPlantFormat.FormatData.ProcData.CheckOffData.ClearCheckOffAndHeaderLists(); PlantFormat.IgnoreUCF = false; PlantFormat.DoingUCFCheckOffs = false; } private bool _formatListIndexChanging = false; // don't change other selections when changing this index private void cbxFormatList_SelectedIndexChanged(object sender, EventArgs e) { if (_Initializing) return; if (cbxFormatList.SelectedIndex > -1) { _formatListIndexChanging = true; FormatInfoList fl = FormatInfoList.GetFormatInfoListUsed(); // Get the format data, the query in GetFormatInfoListUsed may have null for data/genmac which causes a // problem when reading the 'parent' data for UCF saved as formats. int i = -1; FormatInfo finfo = cbxFormatList.SelectedItem as FormatInfo; if (finfo == null) finfo = fl[cbxFormatList.SelectedIndex]; OriginalFormatInfo = FormatInfo.Get(finfo.FormatID); OriginalPlantFormat = OriginalFormatInfo.PlantFormat; // get original data when accessing the plant format data (not UCF because it UCF data is being modified): PlantFormat.IgnoreUCF = true; int formatid = OriginalPlantFormat.MyFormat is Format ? (OriginalPlantFormat.MyFormat as Format).FormatID : (OriginalPlantFormat.MyFormat as FormatInfo).FormatID; FormatInfo fi = FormatInfo.Get(formatid); // if this has config data it is a UCF format, the MyFormatConfig has the config data & see if doing additional checkoffs. // Also, put out the summary of the changes if it is a 'UCF' and if no differences just state that. btnDetails.Visible = true; lblSummary.Visible = true; tbUCFSummary.Visible = true; if (fi.Config != null && fi.Config != "") { MyFormatConfig = FormatConfig.Get(fi.Config); PlantFormat.DoingUCFCheckOffsUse = MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF ?? false; btnSaveClose.Enabled = true; // UCF formats can be modified and saved. btnSave.Enabled = true; SetUCFSummary(fi.Config); } else { MyFormatConfig = new FormatConfig(); btnSaveClose.Enabled = false; btnSave.Enabled = false; tbUCFSummary.Text = "No differences from original"; } // initialize the data based on the selected format with any changes from the FormatConfig. GetUCFDataForUCFGrid(); PG.Enabled = true; PG.SelectedObject = MyFormatConfig; btnSaveAs.Enabled = false; SetDeleteOrResetAllButton(); // set derived from if there is a parent: if (OriginalFormatInfo.MyParent.FormatID == 1) { lblDerFrom.Visible = false; lblDerivedFrom.Visible = false; } else { // get to top parent format: FormatInfo p = OriginalFormatInfo; while (p.MyParent.FormatID != 1) p = p.MyParent; lblDerFrom.Visible = true; lblDerivedFrom.Visible = true; lblDerivedFrom.Text = p.Name.Replace("_UCF", "") + "->" + OriginalFormatInfo.MyParent.Name.Replace("_UCF", "") + ":" + OriginalFormatInfo.MyParent.Description; } _formatListIndexChanging = false; } } private void SetUCFSummary(string formatConfig) { try { string sXSLSummary = System.IO.File.ReadAllText(Application.StartupPath + "\\" + "UCFSummary.xsl"); StringWriter sw = new StringWriter(); using (XmlReader xrt = XmlReader.Create(new StringReader(sXSLSummary))) { using (XmlReader xri = XmlReader.Create(new StringReader(formatConfig))) { using (XmlWriter xwo = XmlWriter.Create(sw)) { XslCompiledTransform xsl = new XslCompiledTransform(); xsl.Load(xrt); xsl.Transform(xri, null, sw); } if (sw == null || sw.ToString() == "") tbUCFSummary.Text = "No differences from original"; else tbUCFSummary.Text = sw.ToString(); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error getting summary for UCF differences", MessageBoxButtons.OK); } } // The SaveAs Button should only be enabled if the user has given this format change a unique 'Name'. private void SetButtonSaveAsEnabled() { btnSaveAs.Enabled = false; if (MyFormatConfig.Name == null || MyFormatConfig.Name == "") return; // See if Name has been changed: if (MyFormatConfig.Name == OriginalFormatInfo.Name) return; // See if the Name is unique foreach (FormatInfo fi in FormatInfoList.SortedFormatInfoList) { if (MyFormatConfig.Name == fi.Name && MyFormatConfig.Name != savDBFormatConfig.Name) { MessageBox.Show("A format with Name " + MyFormatConfig.Name + " already exists. Name must be unique. Change the name before a Save As can be done."); } } btnSaveAs.Enabled = true; return; } // If the selected format is a UCF 'Save As', then possibly allow delete (if not used). Otherwise, if selected format // has Config data, i.e. UCF data, then change button text to 'Revert to Original'. In both cases, enable button, otherwise it is disabled. private void SetDeleteOrResetAllButton() { btnDelete.Enabled = false; // See if UCF Save As, i.e. Data/Genmac are null and that the format is not used. FormatInfo fi = FormatInfo.GetFormatNoUCFByFormatID(OriginalFormatInfo.FormatID); if (fi.Data == "") { if (OriginalFormatInfo.ChildFormatCount == 0 && OriginalFormatInfo.FormatContentCount == 0 && OriginalFormatInfo.FormatDocVersionCount == 0 && OriginalFormatInfo.FormatFolderCount == 0) { btnDelete.Enabled = true; btnDelete.Text = "Delete"; } } else { if (OriginalFormatInfo.Config != null && OriginalFormatInfo.Config != "") { btnDelete.Enabled = true; btnDelete.Text = "Revert to Original"; } } } // GetChangeUCFForSave compares UCF data in FormatConfig to the original PlantFormat data to see if there // are changes that need to be saved to the database. private FormatConfig savDBFormatConfig; private FormatConfig GetChangesUCFForSave() { FormatConfig changesOnly = new FormatConfig(); // Flags if (MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps != null && MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps != OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CompressSteps) changesOnly.PlantFormat.FormatData.Flags.CompressSteps = MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps; if (MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression != null && MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression != OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PartialStepCompression) changesOnly.PlantFormat.FormatData.Flags.PartialStepCompression = MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression; if (MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF != null && MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF == true) // save if true (original format is always false) changesOnly.PlantFormat.FormatData.Flags.CheckOffUCF = MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF; // CheckOff Headers if (MyFormatConfig.PlantFormat.FormatData.CheckOffHeaderList != null) changesOnly.PlantFormat.FormatData.CheckOffHeaderList = GetChangeCheckOffHeaderListForSave(); // CheckOffs if (MyFormatConfig.PlantFormat.FormatData.CheckOffList != null) changesOnly.PlantFormat.FormatData.CheckOffList = GetChangeCheckOffListForSave(); // Checkoff xoffset adjustment if (MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj != null && MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj != 0) // save if not zero (original format is always zero) changesOnly.PlantFormat.FormatData.CheckOffXOffAdj = MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj; // steps if (MyFormatConfig.PlantFormat.FormatData.StepData != null) changesOnly.PlantFormat.FormatData.StepData = GetChangeStepListForSave(); // replace words - just store them all, if there are differences... can't handle deleted unless doing this. if (MyFormatConfig.PlantFormat.FormatData.ReplaceStrData != null) changesOnly.PlantFormat.FormatData.ReplaceStrData = GetChangedReplaceListForSave(); // docstyles FormatConfig.DocStyles retds = new FormatConfig.DocStyles(); foreach (DocStyle dsorig in OriginalPlantFormat.DocStyles.DocStyleList) { if (!dsorig.Inactive && dsorig.IsStepSection) { FormatConfig.DocStyle ds = new FormatConfig.DocStyle(); ds.Index = dsorig.Index.ToString(); ds.Name = dsorig.Name; if (ds.Layout == null) ds.Layout = new FormatConfig.Layout(); // See if in the FormatConfig, use it FormatConfig.DocStyle found = null; if (MyFormatConfig.PlantFormat.DocStyles != null) { foreach (FormatConfig.DocStyle fcds in MyFormatConfig.PlantFormat.DocStyles) { float? difl = Math.Abs((float)((fcds.Layout.LeftMargin * 72) - dsorig.Layout.LeftMargin)); float? difp = Math.Abs((float)((fcds.Layout.PageLength * 72) - dsorig.Layout.PageLength)); if (fcds.Index == dsorig.Index.ToString() && (difl > 1 || difp > 1)) { found = fcds; break; } } } if (found != null) // save it values are different. { if ((found.Layout.LeftMargin * 72) != dsorig.Layout.LeftMargin) ds.Layout.LeftMargin = found.Layout.LeftMargin * 72; else ds.Layout.LeftMargin = null; if ((found.Layout.PageLength * 72) != dsorig.Layout.PageLength) ds.Layout.PageLength = found.Layout.PageLength * 72; else ds.Layout.PageLength = null; retds.Add(ds); } } } if (retds.Count > 0) changesOnly.PlantFormat.DocStyles = retds; return changesOnly; } // Check for differences in the checkoffheaderlist & checkofflist. Only Active flag is used: private FormatConfig.CheckOffHeaderList GetChangeCheckOffHeaderListForSave() { FormatConfig.CheckOffHeaderList cohlist = new FormatConfig.CheckOffHeaderList(); foreach (FormatConfig.CheckOffHeader coh in MyFormatConfig.PlantFormat.FormatData.CheckOffHeaderList) { if (!(bool)coh.Active) cohlist.Add(coh); } return cohlist; } private FormatConfig.CheckOffList GetChangeCheckOffListForSave() { FormatConfig.CheckOffList colist = new FormatConfig.CheckOffList(); foreach (FormatConfig.CheckOff co in MyFormatConfig.PlantFormat.FormatData.CheckOffList) { if (!(bool)co.Active) colist.Add(co); } return colist; } // Check for differences in the StepDataList between UCF and original data for saving of data to database: private FormatConfig.StepData GetChangeStepListForSave() { FormatConfig.StepData sdlist = new FormatConfig.StepData(); foreach (StepData sdorig in OriginalPlantFormat.FormatData.StepDataList) { if (!sdorig.Inactive) { // find this step in the config data: foreach (FormatConfig.Step fcstp in MyFormatConfig.PlantFormat.FormatData.StepData) { if (fcstp.Index == sdorig.Index.ToString()) { // see if data is different and if so, add it to the return list: System.Drawing.FontConverter cvt = new System.Drawing.FontConverter(); string origFont = cvt.ConvertToString(sdorig.Font.WindowsFont); string newFont = cvt.ConvertToString(fcstp.FontDesc.WindowsFont); if (origFont != newFont) { FormatConfig.Step stp = fcstp; sdlist.Add(stp); } break; } } } } return sdlist; } // Check for differences in the ReplaceWords between UCF and original data for saving of data to database: private FormatConfig.ReplaceStrData GetChangedReplaceListForSave() { // only saving the differences // need to compare the original format list with the list as it is stored for UCF, i.e.working with property grid and save differences. // Note that check for 'bad' data such as no flags, or null/empty replace with/word strings - don't use those. // States for replacewords: 0 = no change, -1 deleted, 1 added, 2 modified FormatConfig.ReplaceStrData retlist = new FormatConfig.ReplaceStrData(); // list of changes foreach (FormatConfig.ReplaceStr ucfrepstr in MyFormatConfig.PlantFormat.FormatData.ReplaceStrData) { // Modified foreach (ReplaceStr origrepstr in OriginalPlantFormat.FormatData.SectData.ReplaceStrList) { // B2019-113: consider replace word AND flags to determine if there was a modification if (origrepstr.ReplaceWord.Replace("{Backspace}", "") == ucfrepstr.ReplaceWord.Replace("{Backspace}", "") && (E_ReplaceFlags)ucfrepstr.Flag == origrepstr.Flag) { if ((ucfrepstr.ReplaceWith != origrepstr.ReplaceWith) && ucfrepstr.Flag != 0 && ucfrepstr.ReplaceWith != "") { ucfrepstr.State = 2; retlist.Add(ucfrepstr); break; } } } } // Added: List origstrList = new List(); // used to find added, (see later in this method) foreach (ReplaceStr origrepstr in OriginalPlantFormat.FormatData.SectData.ReplaceStrList) origstrList.Add(origrepstr.ReplaceWord); foreach (FormatConfig.ReplaceStr ucfrepstr in MyFormatConfig.PlantFormat.FormatData.ReplaceStrData) { if (!origstrList.Contains(ucfrepstr.ReplaceWord)) { // check for valid data, i.e. flag set & both replaceword & with not blank if (ucfrepstr.Flag != 0 && ucfrepstr.ReplaceWith != null && ucfrepstr.ReplaceWith != "" && ucfrepstr.ReplaceWord != null && ucfrepstr.ReplaceWord != "") { ucfrepstr.State = 1; retlist.Add(ucfrepstr); } } else // B2019-113: replace word is in the original list, see if this word was added with different flags { if (!RepWrdSameWordSameFlags(OriginalPlantFormat.FormatData.SectData.ReplaceStrList, ucfrepstr)) { ucfrepstr.State = 1; retlist.Add(ucfrepstr); } } } //Deleted: List ucfList = new List(); // used to find deleted foreach (FormatConfig.ReplaceStr ucfrepstr in MyFormatConfig.PlantFormat.FormatData.ReplaceStrData) ucfList.Add(ucfrepstr.ReplaceWord); foreach (ReplaceStr origrepstr in OriginalPlantFormat.FormatData.SectData.ReplaceStrList) { bool addtodeletelist = false; if (!ucfList.Contains(origrepstr.ReplaceWord) ) { if (!((origrepstr.ReplaceWith.Contains("$1") && origrepstr.ReplaceWord.Contains("w*")) || origrepstr.ReplaceWith.Contains("{Backspace}"))) { addtodeletelist = true; } } else // // B2019-113: for this ucf replaceword, see if its flag is in the original list { foreach (FormatConfig.ReplaceStr ucfrepstruct in MyFormatConfig.PlantFormat.FormatData.ReplaceStrData) { if (origrepstr.ReplaceWord.Replace("{Backspace}", "") == ucfrepstruct.ReplaceWord.Replace("{Backspace}", "")) { // only deleted if replace word AND flags match: if (!RepWrdSameWordSameFlags(OriginalPlantFormat.FormatData.SectData.ReplaceStrList, ucfrepstruct)) { addtodeletelist = true; break; } } } } if (addtodeletelist) { // make a deleted replacestr to save FormatConfig.ReplaceStr del = new FormatConfig.ReplaceStr(); del.State = -1; del.Flag = (FormatConfig.E_ReplaceFlagsUCF)origrepstr.Flag; del.ReplaceWord = origrepstr.ReplaceWord; del.ReplaceWith = origrepstr.ReplaceWith; retlist.Add(del); } } return retlist; } private bool RepWrdSameWordSameFlags(ReplaceStrList replaceStrList, FormatConfig.ReplaceStr ucfrepstr) { // B2019-133: if the replace word is the same, see if the UCF flag is different. The Replace Word & the flags need to be the same for it to be a match. List flags = new List(); foreach (ReplaceStr origrepstr in replaceStrList) { if (origrepstr.ReplaceWord.Replace("{Backspace}", "") == ucfrepstr.ReplaceWord.Replace("{Backspace}", "")) flags.Add(ucfrepstr.Flag); } return (flags.Contains(ucfrepstr.Flag)); } // The following uses the original format's ReplaceWords list and applies any changes made from the UCF ReplaceWords list. private FormatConfig.ReplaceStrData GetMergedReplaceList() { // need to compare the original format list with the list as it is stored for working with property grid. FormatConfig.ReplaceStrData retlist = new FormatConfig.ReplaceStrData(); // merged list List inoriglist = new List(); // use this list to find new items in formatconfig (see below) foreach (ReplaceStr origrepstr in OriginalPlantFormat.FormatData.SectData.ReplaceStrList) { // In the format config list (UCF), find the 'ReplaceWord'. This is the 'key' for defining whether the // replace word has been overwridden by UCF data. If it exists, use it: FormatConfig.ReplaceStr usethisone = null; bool deleted = false; // States for replacewords: 0 = no change, -1 deleted, 1 added, 2 modified foreach (FormatConfig.ReplaceStr ucfrepstr in MyFormatConfig.PlantFormat.FormatData.ReplaceStrData) { if (ucfrepstr.ReplaceWord == origrepstr.ReplaceWord && (E_ReplaceFlags)ucfrepstr.Flag == origrepstr.Flag) { if (ucfrepstr.State == -1) deleted = true; else usethisone = ucfrepstr; ucfrepstr.State = 2; inoriglist.Add(origrepstr.ReplaceWord); UcfForRepWords = true; break; } } // don't add in the replacewords that use 'Backspace' and regular expressions: bool supported = true; if (!deleted && usethisone == null) { if ((origrepstr.ReplaceWith.Contains("$1") || origrepstr.ReplaceWord.Contains("w*")) || origrepstr.ReplaceWith.Contains("{Backspace}")) supported = false; else { usethisone = new FormatConfig.ReplaceStr(); usethisone.Flag = (FormatConfig.E_ReplaceFlagsUCF)origrepstr.Flag; usethisone.State = 0; // no change usethisone.ReplaceWith = origrepstr.ReplaceWith; usethisone.ReplaceWord = origrepstr.ReplaceWord; } } if (!deleted && supported) retlist.Add(usethisone); } // now add in any ucf only replacements, any that are not in the inoriglist foreach (FormatConfig.ReplaceStr ucfrepstr in MyFormatConfig.PlantFormat.FormatData.ReplaceStrData) { if (!inoriglist.Contains(ucfrepstr.ReplaceWord)) { FormatConfig.ReplaceStr newone = new FormatConfig.ReplaceStr(); newone.Flag = (FormatConfig.E_ReplaceFlagsUCF)ucfrepstr.Flag; newone.State = 1; //newone.ReplaceWith = ucfrepstr.ReplaceWith; newone.ReplaceWith = ucfrepstr.ReplaceWith; newone.ReplaceWord = ucfrepstr.ReplaceWord; retlist.Add(newone); UcfForRepWords = true; } } return (retlist); } // This method reads in the format items, merging any changes from UCF into original format. It sets MyFormatConfig, which // is the structure that gets used by the PropertyGrid private void GetUCFDataForUCFGrid() { // name/description is only stored as format record fields. There are attributes in formatconfig xml that are used for defining these // when new UCFs are defined or allowing for updates. MyFormatConfig.Name = OriginalFormatInfo.Name; MyFormatConfig.Description = OriginalFormatInfo.Description; // Store original (currently saved FormatConfig) to be used for comparison when saving. savDBFormatConfig = MyFormatConfig; // Flags if (MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps == null) MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps = OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CompressSteps; if (MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression == null) MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression = OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PartialStepCompression; if (MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF == null) MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF = OriginalPlantFormat.FormatData.ProcData.CheckOffUCF; // checkoff xoffset adjustment if (MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj == null) MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj = 0; GetUCFCheckOffDataForUCFGrid((bool)MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF); // StepData: If there is no UCF data for steps, copy over from selected format FormatConfig.StepData sdlMerged = new FormatConfig.StepData(); if (MyFormatConfig.PlantFormat.FormatData.StepData == null || MyFormatConfig.PlantFormat.FormatData.StepData.Count == 0) { foreach (StepData sdorig in OriginalPlantFormat.FormatData.StepDataList) { if (!sdorig.Inactive && sdorig.Index != 0) { FormatConfig.Step stp = new FormatConfig.Step(); stp.Index = sdorig.Index.ToString(); stp.Type = sdorig.Type; stp.FontDesc = new FormatConfig.FontDesc(); stp.FontDesc.OrigWindowsFont = sdorig.Font.WindowsFont; stp.FontDesc.WindowsFont = sdorig.Font.WindowsFont; if (MyFormatConfig.PlantFormat.FormatData.StepData == null) MyFormatConfig.PlantFormat.FormatData.StepData = new FormatConfig.StepData(); sdlMerged.Add(stp); } } } else { foreach (StepData sdorig in OriginalPlantFormat.FormatData.StepDataList) { if (!sdorig.Inactive && sdorig.Index != 0) { FormatConfig.Step stp = new FormatConfig.Step(); stp.Index = sdorig.Index.ToString(); stp.Type = sdorig.Type; stp.FontDesc = new FormatConfig.FontDesc(); // See if in the FormatConfig, use it FormatConfig.Step foundinFC = null; foreach (FormatConfig.Step fcstp in MyFormatConfig.PlantFormat.FormatData.StepData) { if (fcstp.Index == sdorig.Index.ToString()) { foundinFC = fcstp; break; } } stp.FontDesc.OrigWindowsFont = new System.Drawing.Font(sdorig.Font.Family, (float)sdorig.Font.Size, sdorig.Font.WindowsFont.Style); if (foundinFC != null) stp.FontDesc.WindowsFont = new System.Drawing.Font(foundinFC.FontDesc.WindowsFont.Name, foundinFC.FontDesc.WindowsFont.Size, foundinFC.FontDesc.WindowsFont.Style); else stp.FontDesc.WindowsFont = new System.Drawing.Font(sdorig.Font.Family, (float)sdorig.Font.Size, sdorig.Font.WindowsFont.Style); sdlMerged.Add(stp); } } } MyFormatConfig.PlantFormat.FormatData.StepData = sdlMerged; // ReplacWords // if there are no replace str entries in sc, add from the selected format: if (MyFormatConfig.PlantFormat.FormatData.ReplaceStrData == null || MyFormatConfig.PlantFormat.FormatData.ReplaceStrData.Count == 0) { foreach (ReplaceStr repstrorig in OriginalPlantFormat.FormatData.SectData.ReplaceStrList) { if (!((repstrorig.ReplaceWith.Contains("$1") && repstrorig.ReplaceWord.Contains("w*")) || repstrorig.ReplaceWith.Contains("{Backspace}"))) { FormatConfig.ReplaceStr rsfc = new FormatConfig.ReplaceStr(); rsfc.Flag = (FormatConfig.E_ReplaceFlagsUCF)repstrorig.Flag; rsfc.State = 0; rsfc.ReplaceWith = repstrorig.ReplaceWith; rsfc.ReplaceWord = repstrorig.ReplaceWord; MyFormatConfig.PlantFormat.FormatData.ReplaceStrData.Add(rsfc); } } } else { MyFormatConfig.PlantFormat.FormatData.ReplaceStrData = GetMergedReplaceList(); } // Document Style (section) Data (docstyles). Get step editor type only if (MyFormatConfig.PlantFormat.DocStyles == null || MyFormatConfig.PlantFormat.DocStyles.Count == 0) { foreach (DocStyle dsorig in OriginalPlantFormat.DocStyles.DocStyleList) { if (!dsorig.Inactive && dsorig.IsStepSection) { FormatConfig.DocStyle ds = new FormatConfig.DocStyle(); ds.Index = dsorig.Index.ToString(); ds.Name = dsorig.Name; if (ds.Layout == null) ds.Layout = new FormatConfig.Layout(); ds.Layout.PageLength = (float)Math.Round((float)dsorig.Layout.PageLength / 72, 2); ds.Layout.OrigPageLength = ds.Layout.PageLength; ds.Layout.LeftMargin = (float)Math.Round((float)dsorig.Layout.LeftMargin / 72, 2); ds.Layout.OrigLeftMargin = ds.Layout.LeftMargin; if (MyFormatConfig.PlantFormat.DocStyles == null) MyFormatConfig.PlantFormat.DocStyles = new FormatConfig.DocStyles(); MyFormatConfig.PlantFormat.DocStyles.Add(ds); } } } else { foreach (DocStyle dsorig in OriginalPlantFormat.DocStyles.DocStyleList) { if (!dsorig.Inactive && dsorig.IsStepSection) { FormatConfig.DocStyle ds = new FormatConfig.DocStyle(); ds.Index = dsorig.Index.ToString(); ds.Name = dsorig.Name; if (ds.Layout == null) ds.Layout = new FormatConfig.Layout(); // See if in the FormatConfig, use it FormatConfig.DocStyle foundinFC = null; foreach (FormatConfig.DocStyle fcds in MyFormatConfig.PlantFormat.DocStyles) { if (fcds.Index == dsorig.Index.ToString()) { foundinFC = fcds; break; } } if (foundinFC != null) { if (foundinFC.Layout.LeftMargin == null) foundinFC.Layout.LeftMargin = (float)Math.Round((float)dsorig.Layout.LeftMargin / 72, 2); else foundinFC.Layout.LeftMargin = (float)Math.Round((float)foundinFC.Layout.LeftMargin / 72, 2); foundinFC.Layout.OrigLeftMargin = (float)Math.Round((float)dsorig.Layout.LeftMargin / 72, 2); if (foundinFC.Layout.PageLength == null) foundinFC.Layout.PageLength = (float)Math.Round((float)dsorig.Layout.PageLength / 72, 2); else foundinFC.Layout.PageLength = (float)Math.Round((float)foundinFC.Layout.PageLength / 72, 2); foundinFC.Layout.OrigPageLength = (float)Math.Round((float)dsorig.Layout.PageLength / 72, 2); } else { ds.Layout.OrigLeftMargin = (float)Math.Round((float)dsorig.Layout.LeftMargin / 72, 2); ds.Layout.OrigPageLength = (float)Math.Round((float)dsorig.Layout.PageLength / 72, 2); ds.Layout.LeftMargin = (float)Math.Round((float)dsorig.Layout.LeftMargin / 72, 2); ds.Layout.PageLength = (float)Math.Round((float)dsorig.Layout.PageLength / 72, 2); MyFormatConfig.PlantFormat.DocStyles.Add(ds); } } } } } private void GetUCFCheckOffDataForUCFGrid(bool ucfcheckof) { OriginalPlantFormat.FormatData.ProcData.CheckOffData.ClearCheckOffAndHeaderLists(); // CheckOffHeaders: If there is no UCF data, use from the selected format, otherwise merge: FormatConfig.CheckOffHeaderList cohdrsMerged = new FormatConfig.CheckOffHeaderList(); if (MyFormatConfig.PlantFormat.FormatData.CheckOffHeaderList == null || MyFormatConfig.PlantFormat.FormatData.CheckOffHeaderList.Count == 0) { foreach (CheckOffHeader cohorig in OriginalPlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList) { // do inactive:: FormatConfig.CheckOffHeader coh = new FormatConfig.CheckOffHeader(); coh.Index = cohorig.Index.ToString(); coh.CheckOffHeading = cohorig.CheckOffHeading; coh.Active = true; coh.OrigActive = true; cohdrsMerged.Add(coh); } } else { foreach (CheckOffHeader cohorig in OriginalPlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList) { FormatConfig.CheckOffHeader coh = new FormatConfig.CheckOffHeader(); coh.Index = cohorig.Index.ToString(); coh.CheckOffHeading = cohorig.CheckOffHeading; coh.Active = true; coh.OrigActive = true; // See if in the FormatConfig, to check its inactive flag: foreach (FormatConfig.CheckOffHeader fccoh in MyFormatConfig.PlantFormat.FormatData.CheckOffHeaderList) { if (fccoh.Index == cohorig.Index.ToString()) { coh.Active = fccoh.Active; coh.OrigActive = true; break; } } cohdrsMerged.Add(coh); } } MyFormatConfig.PlantFormat.FormatData.CheckOffHeaderList = cohdrsMerged; // CheckOffs: If there is no UCF data, use from the selected format, otherwise merge: FormatConfig.CheckOffList cosMerged = new FormatConfig.CheckOffList(); // clear the lists so that correct lists will be initialized foreach (CheckOff coorig in OriginalPlantFormat.FormatData.ProcData.CheckOffData.CheckOffList) { FormatConfig.CheckOff co = new FormatConfig.CheckOff(); co.Index = coorig.Index.ToString(); co.MenuItem = coorig.MenuItem; co.Active = true; co.OrigActive = true; // See if in the FormatConfig, to check its inactive flag: if (MyFormatConfig.PlantFormat.FormatData.CheckOffList != null) { foreach (FormatConfig.CheckOff fcco in MyFormatConfig.PlantFormat.FormatData.CheckOffList) { if (fcco.Index == coorig.Index.ToString()) { co.Active = fcco.Active; co.OrigActive = true; break; } } } cosMerged.Add(co); } MyFormatConfig.PlantFormat.FormatData.CheckOffList = cosMerged; } // The Reset button is used to reset a UCF change from the original data. If a field is added to UCF, code needs // added here for the field: private void btnReset_Click(object sender, EventArgs e) { // The code that enables the Reset button checks if a change (UCF) exists. So no need to check here. if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags:Compress Steps")) { MyFormatConfig.PlantFormat.FormatData.Flags.CompressSteps = OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CompressSteps; } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags:Partial Step Compression")) { MyFormatConfig.PlantFormat.FormatData.Flags.PartialStepCompression = OriginalPlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PartialStepCompression; } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Flags:UCF CheckOffs")) { MyFormatConfig.PlantFormat.FormatData.Flags.CheckOffUCF = OriginalPlantFormat.FormatData.ProcData.CheckOffUCF; } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:CheckOff XOffset")) { MyFormatConfig.PlantFormat.FormatData.CheckOffXOffAdj = 0; } else if (SelectedGridField.EndsWith("Data:Plant Format:Step Settings:Replace Words List")) { MyFormatConfig.PlantFormat.FormatData.ReplaceStrData.Clear(); foreach (ReplaceStr repstrorig in OriginalPlantFormat.FormatData.SectData.ReplaceStrList) { if (!((repstrorig.ReplaceWith.Contains("$1") && repstrorig.ReplaceWord.Contains("w*")) || repstrorig.ReplaceWith.Contains("{Backspace}"))) { FormatConfig.ReplaceStr rsfc = new FormatConfig.ReplaceStr(); rsfc.Flag = (FormatConfig.E_ReplaceFlagsUCF)repstrorig.Flag; rsfc.State = 0; rsfc.ReplaceWith = repstrorig.ReplaceWith; rsfc.ReplaceWord = repstrorig.ReplaceWord; MyFormatConfig.PlantFormat.FormatData.ReplaceStrData.Add(rsfc); UcfForRepWords = false; } } } btnReset.Enabled = false; btnReset.Text = "Reset"; } private void btnSaveAs_Click(object sender, EventArgs e) { // Name must be unique - description can be null. // Append a '_UCF' at end of all user control of format formats. // add a format record for this: // FormatID - next ID, db creates on new format // ParentID - format id of the format that was used as a base for this user control of format // Name - user defined // Description - user defined - if none specified by user, use the original's description // Data - null: flags that a UCF was saved as and use the parent and config from this. // // check for unique name. foreach (FormatInfo fi in FormatInfoList.SortedFormatInfoList) { if (MyFormatConfig.Name == fi.Name || MyFormatConfig.Name + "_UCF" == fi.Name) { MessageBox.Show("A format with Name " + MyFormatConfig.Name + " already exists. Name must be unique. Save As cannot be done."); return; } } using (Format tmp = Format.Get(OriginalFormatInfo.FormatID)) { string fname = MyFormatConfig.Name + (MyFormatConfig.Name.EndsWith("_UCF") ? "" : "_UCF"); Format fmt = Format.MakeFormat(tmp, fname, MyFormatConfig.Description == OriginalFormatInfo.Description || MyFormatConfig.Description == "" || MyFormatConfig.Description == null ? OriginalFormatInfo.Description : MyFormatConfig.Description, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); FormatConfig tmpForSave = GetChangesUCFForSave(); string scf = tmpForSave.ConvertToString(); scf = Regex.Replace(scf, " *<[a-zA-Z ]+/>\r\n", ""); // for now, tell the user that changes don't take affect until reentry. This was done since the 'refresh' of FormatConfig was not // working. fmt.Config = scf; fmt.Description = MyFormatConfig.Description; fmt.Save(true); MessageBox.Show(this, "Restart PROMS to have format changes take effect.", "", MessageBoxButtons.OK); btnSaveAs.Enabled = false; } } private void btnDelete_Click(object sender, EventArgs e) { // delete this format OR (the button text is set to 'delete...' if no item or version uses it) // revert to the original string msg = btnDelete.Text == "Revert to Original" ? "revert to the original?" : "delete this format?"; if (MessageBox.Show(this, "Are you sure you want to " + msg, "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { PlantFormat.IgnoreUCF = true; // the button is either 'Revert to Original' for a format that is the original and has config data, or 'Delete' for a UCF that // was created by a 'Save As'. // so do either a clear of the config data, or delete the format record depending on button's text if (btnDelete.Text == "Revert to Original") { using (Format fmt = Format.Get(OriginalFormatInfo.FormatID)) { fmt.Config = ""; fmt.Save(true); MessageBox.Show(this, "The changes that have been made to the format will take affect after reentry to PROMS", "", MessageBoxButtons.OK); MyFormatConfig = new FormatConfig(); PG.SelectedObject = MyFormatConfig; PG.Enabled = false; btnSaveAs.Enabled = false; btnDelete.Enabled = false; btnSaveClose.Enabled = false; btnSave.Enabled = false; btnReset.Enabled = false; } } else { try { Format.Delete(OriginalFormatInfo.FormatID); } catch (Exception ex) { MessageBox.Show("Could not delete the format"); return; } cbxFormatList.DataSource = FormatInfoList.GetFormatInfoListUsed(); cbxFormatList.SelectedIndex = -1; MyFormatConfig = new FormatConfig(); PG.SelectedObject = MyFormatConfig; PG.Enabled = false; btnSaveAs.Enabled = false; btnDelete.Enabled = false; btnSaveClose.Enabled = false; btnSave.Enabled = false; btnReset.Enabled = false; } PlantFormat.IgnoreUCF = false; PlantFormat.DoingUCFCheckOffs = false; } } private void btnDetails_Click(object sender, EventArgs e) { FormatConfig tmpfc = GetChangesUCFForSave(); string scf = tmpfc.ConvertToString(); scf = Regex.Replace(scf, " *<[a-zA-Z ]+/>\r\n", ""); dlgUCFDetail dtl = new dlgUCFDetail(scf, MyFormatConfig.Name, MyFormatConfig.Description); dtl.ShowDialog(); } private void btnSave_Click(object sender, EventArgs e) { // get a FormatConfig structure that only has differences from the original format. This is what gets saved. FormatConfig tmpForSave = GetChangesUCFForSave(); string scf = tmpForSave.ConvertToString(); scf = Regex.Replace(scf, " *<[a-zA-Z ]+/>\r\n", ""); int fmtid = OriginalPlantFormat.MyFormat is Format ? (OriginalPlantFormat.MyFormat as Format).FormatID : (OriginalPlantFormat.MyFormat as FormatInfo).FormatID; // for now, tell the user that changes don't take affect until reentry. This was done since the 'refresh' of FormatConfig was not // working. using (Format fmt = Format.Get(fmtid)) { FormatInfo fi = FormatInfo.GetFormatNoUCFByFormatID(OriginalFormatInfo.FormatID); if (fi.Data == "") { fmt.Data = ""; fmt.GenMac = ""; } fmt.Config = scf; fmt.Name = MyFormatConfig.Name; fmt.Description = MyFormatConfig.Description; fmt.Save(true); } } } }