// ======================================================================== // Copyright 2006 - Volian Enterprises, Inc. All rights reserved. // Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE // ------------------------------------------------------------------------ // $Workfile: $ $Revision: $ // $Author: $ $Date: $ // // $History: $ // ======================================================================== using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Data.OleDb; using System.Collections.Specialized; using System.Collections.Generic; using System.Xml; using System.Xml.XPath; using System.IO; using System.Text; using VEPROMS.CSLA.Library; namespace DataLoader { public partial class Loader { private Dictionary dicOldToNew; private Item AddSection(Item procitem, string Number, string Title, string SecType, DateTime Dts, string Userid, ConfigInfo ci, string stpseq, string fmt, int libdocid, string pth, Item FromItem, DocVersion docver) { frmMain.UpdateLabels(0, 1, 0); try { FormatInfo format = null; // Tie the section to format used, this will add the format xml if it doesn't exist in // the database yet. Note that if there is no format at this level then none should // be set so that the inheritance works correctly. if (fmt != null && fmt != "") format = GetFormat(fmt); // Find the docstyle based on the section type (step[1]) & the 'type' from the dbf // record sectype[0]) string dstyleindx = ((stpseq == null || stpseq == "") ? " " : stpseq.Substring(1, 1)) + ((SecType==null||SecType == "") ? " " : SecType.Substring(0, 1)); int docstyleindx = GetDocStyleIndx(dstyleindx, format, procitem, docver); // tack on the column mode - add to config xml for node. if (stpseq != null && stpseq.Substring(1, 1) == "0" && stpseq.Substring(5, 1) != " ") { if (ci == null) ci = new ConfigInfo(null); ci.AddItem("Section", "ColumnMode", stpseq.Substring(5, 1)); } // find rtf file (or use the library document temp file) & read it into the field // acccontent int Documentid=0; bool needEntry = false; if (libdocid != 0 || stpseq.Substring(1, 1) != "0") { needEntry = true; string fname = null; if (libdocid != 0) { Documentid = libdocid; } else { int num = Convert.ToInt32(stpseq[0]) - 64; string thenum = num.ToString("d2"); fname = string.Format("{0}\\rtffiles\\{1}.A{2}", pth, ProcFileName, thenum); Application.DoEvents(); SaveSectionDocument(fname, stpseq, SecType, ref Documentid); if (Documentid == 0) { if (MissingDocument==null) MissingDocument = Document.MakeDocument("MISSING FILE IN CONVERSION", null, null, null); Documentid = MissingDocument.DocID; } } } if (Userid == null || Userid == "") Userid = "Migration"; // test for performance Content cont; using(Format fmt2 = format == null ? null : format.Get()) cont = Content.New(Number, Title, 10000+docstyleindx, fmt2, ci==null?null:ci.ToString(), Dts, Userid); Entry entry = cont.MyEntry; if (needEntry) { entry.MyDocument = Document.Get(Documentid); entry.DTS = Dts; entry.UserID = Userid; //entry = Entry.MakeEntry(cont.ContentID, Document.Get(Documentid), Dts, Userid); } cont.MyZContent.OldStepSequence = ProcNumber + "|" + stpseq; Item itm = null; // the stpseq for section records may include a space & some other data. This // was not part of what is stored in the transition records, so just look at // the sequence before the space for section records. Then use the first character // with a '0'. This is what's stored in the transition record, for example, if the // section was BI, the transition record would have B0 (the reasoning is that // for steps, this is what could be stored if there were enough steps. int trindxsp = stpseq.IndexOf(' '); string trstpseq = trindxsp < 0 ? stpseq : stpseq.Substring(0, 1)+ "0"; if (dicTrans_ItemIds.ContainsKey(ProcNumber + "|" + trstpseq)) { itm = dicTrans_ItemIds[ProcNumber + "|" + trstpseq]; itm.MyContent = cont; itm.MyPrevious = FromItem; itm.DTS = Dts; itm.UserID = Userid; if (!itm.IsSavable) ErrorRpt.ErrorReport(itm); itm.Save(); dicTrans_ItemIds.Remove(ProcNumber + "|" + trstpseq); dicTrans_MigrationErrors.Remove(ProcNumber + "|" + trstpseq); } else itm = Item.MakeItem(FromItem, cont, Dts, Userid); dicTrans_ItemDone[ProcNumber+"|"+trstpseq] = itm; dicOldStepSequence[itm] = stpseq; return itm; } catch (Exception ex) { log.Error("Save Section"); log.ErrorFormat("oldstepsequence = {0}", stpseq); log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException); log.ErrorFormat(ex.StackTrace); } return null; } private int LookupOldToNew(string lkup) { if (dicOldToNew == null) { dicOldToNew = new Dictionary(); //dicOldToNew.Add("", 1); dicOldToNew.Add("0", 1); dicOldToNew.Add("0 ", 1); dicOldToNew.Add("00", 1); dicOldToNew.Add("01", 2); dicOldToNew.Add("02", 4); dicOldToNew.Add("03", 8); dicOldToNew.Add("04", 16); dicOldToNew.Add("I", 32); dicOldToNew.Add("I ", 32); dicOldToNew.Add("I0", 32); dicOldToNew.Add("I1", 64); dicOldToNew.Add("I2", 128); dicOldToNew.Add("I3", 256); dicOldToNew.Add("I4", 512); dicOldToNew.Add("A", 1024); dicOldToNew.Add("A ", 1024); dicOldToNew.Add("A0", 1024); dicOldToNew.Add("A1", 2048); dicOldToNew.Add("A2", 4096); dicOldToNew.Add("A3", 8192); dicOldToNew.Add("A4", 16384); dicOldToNew.Add("F", 32768); dicOldToNew.Add("F ", 32768); dicOldToNew.Add("F0", 32768); dicOldToNew.Add("F1", 65536); dicOldToNew.Add("F2", 131072); dicOldToNew.Add("F3", 262144); dicOldToNew.Add("F4", 524288); dicOldToNew.Add("05", 1048576); dicOldToNew.Add("06", 2097152); dicOldToNew.Add("07", 4194304); dicOldToNew.Add("08", 8388608); dicOldToNew.Add("09", 16777216); dicOldToNew.Add("0:", 33554432); dicOldToNew.Add("0;", 67108864); dicOldToNew.Add("0<", 134217728); dicOldToNew.Add("0=", 268435456); dicOldToNew.Add("0>", 536870912); } int retval = -1; try { retval = dicOldToNew[lkup]; } catch (Exception ex) { Console.WriteLine(string.Format("Error in oldtonew {0}", lkup)); Console.WriteLine(string.Format("Error = {0}", ex.Message)); } return retval; } private int GetDocStyleIndx(string dstyleindx, FormatInfo format, Item procitem, DocVersion docver) { // get the format, if format is set, use it, otherwise walk if (format == null) { format = GetFormat(procitem, docver); } int docstyle = LookupOldToNew(dstyleindx); foreach (DocStyle ds in format.PlantFormat.DocStyles.DocStyleList) { if ((ds.OldToNew & docstyle)>0) return (int)ds.Index; } Console.WriteLine("Error getting docstyle index"); return 0; } private FormatInfo GetFormat(Item procitem, DocVersion docver) { return procitem.MyItemInfo.ActiveFormat; //while (procitem.MyItemInfo.a .MyContent.MyFormat == null) //{ // // find the first sibling // while (procitem.PreviousID != null) // procitem = procitem.MyPrevious; // if (procitem.ItemPartCount == 0) return docver.MyDocVersionInfo.ActiveFormat; // // find the parent node // procitem = procitem.ItemParts[0].MyContent.ContentItems[0].MyItem; //} //return procitem.MyContent.MyFormat; } //private FormatInfo GetFormat(DocVersion docver) //{ // if (docver.MyDocVersionInfo.MyFormat != null) return docver.MyDocVersionInfo.MyFormat; // return GetFormat(docver.MyDocVersionInfo.MyFolder); //} //private FormatInfo GetFormat(FolderInfo folder) //{ // if (folder.MyFormat != null) return folder.MyFolderInfo.MyFormat; // return GetFormat(folder.MyParent); //} private string SectTitle(OleDbConnection cn, DataRowView dr, bool UseMultiLineSectionTitle, bool ConvertCaret) { string tbuff = null; string menustr = null; if (UseMultiLineSectionTitle) { bool titleInMemo = false; // for accessory pages... if (dr["Step"].ToString().Substring(1, 1) != "0") { // The long section title is stored on a record with the "~" character. // This was done since originally the actual accessory page data was stored in the memo // field, so the long title could not be stored there, another record had to be used. OleDbDataAdapter da = new OleDbDataAdapter("select * from " + ProcFileName + " where [Step] like '" + dr["Step"].ToString().Substring(0, 1) + "~';", cn); DataSet ds = new DataSet(); try { da.Fill(ds); if (ds.Tables[0].Rows.Count == 1) { DataRow row = ds.Tables[0].Rows[0]; tbuff = TextConvert.ConvertText(row["Textm"].ToString(),ConvertCaret); if (tbuff != null && tbuff != "") titleInMemo = true; } else // no long section title existed for this accessory page tbuff = TextConvert.ConvertText(dr["Text"].ToString().PadRight(130, ' ').Substring(0, 75).TrimEnd(), ConvertCaret); } catch (Exception ex) { log.ErrorFormat("Error getting long section title {0}", ex.Message); } da.Dispose(); } // For step sections, the long section title is stored on the section record // (see above comment for accessory pages to see the difference) else { tbuff = TextConvert.ConvertText(dr["TextM"].ToString().Trim(), ConvertCaret); } //// TESTS were run & it looked like that whitespace was removed before saving, //// so, put up a message box if find out otherwise.... //int nl = tbuff.IndexOf("\n"); //if (nl > -1) // MessageBox.Show("multiline text for section title, fix this!!"); //// remove newlines & any other escape/whitespace chars. int nl = tbuff.IndexOf("\n"); if (nl > -1 || titleInMemo) { string tmpstr = tbuff.Replace("\r", ""); tmpstr = tmpstr.Replace("\t", ""); tmpstr = tmpstr.Replace("\n", " "); // get rid of multiple spaces while (tmpstr.IndexOf(" ") > -1) tmpstr = tmpstr.Replace(" ", " "); tbuff = tmpstr; if (tbuff.Substring(tbuff.Length - 1, 1) == " ") tbuff = tbuff.Substring(0, tbuff.Length - 1); menustr = tbuff; } else { menustr = TextConvert.ConvertText(dr["Text"].ToString().PadRight(80, ' ').Substring(0, 75).TrimEnd(), ConvertCaret); } } else { // format does not include long section title menustr = TextConvert.ConvertText(dr["Text"].ToString().PadRight(80, ' ').Substring(0, 75).TrimEnd(), ConvertCaret); } return menustr; } private Item MigrateSection(Item procitem, string procnum, OleDbConnection cn, DataRowView dr, DataTable dt, Item FromItem, bool isSubSection, string pth, DocVersion docver) { Int32 thesectid = 0; bool isautogen = false; string stype = dr["type"].ToString(); string s = dr["text"].ToString().PadRight(130, ' '); string num = s.Substring(85, 20).TrimEnd(); string fmt = s.Substring(75, 10).TrimEnd(); if (fmt == "") fmt = null; bool ismulti = false; bool conv_caret = true; // sectFormat is a local that represents the format to be used by this section. // Note that if the format is set for this section, check it against what the inherited // value would be (for example, what the format is for the set), if they are the same // clear the format at the section level. FormatInfo sectFormat = null; FormatInfo docverFormat = docver.MyDocVersionInfo.ActiveFormat; if (fmt != null&& fmt !="") // Is there a long section title (from format flag) sectFormat = GetFormat(fmt); else // either from this format, or the plant. sectFormat = docverFormat; if (sectFormat != null) { ismulti = sectFormat.PlantFormat.FormatData.SectData.StepSectionData.UseMultiLineSectionTitle; conv_caret = sectFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta; } if (fmt != null && fmt != "") if (fmt == docverFormat.Name) fmt = null; string title = SectTitle(cn, dr, ismulti, conv_caret); string init = dr["initials"].ToString().Trim(); string sequence = dr["CSequence"].ToString().PadRight(10); string step = dr["CStep"].ToString(); int libDocid = 0; DateTime dts = GetDTS(dr["Date"].ToString(), dr["Time"].ToString()); ConfigInfo ci = new ConfigInfo(null); ci.AddItem("Section", "OldType", stype); // for steps sections... // Step Section Header Format: // A0 1X2S51 &Y // ^^^^^^^^^^^^ // ||||||||||||| // ||||||||||||`- 'Y','N', or blank signals to print section header - lib/section/addsec.c // |||||||||||`-- (bits) Auto Indent, Editable Data, Checkoff Header Type - lib/section/addsec.c // ||||||||||`--- blank // ||||||||`----- Link With Enhanced Document ' '-Default(not determined) 0-NO 1-YES // |||||||`------ MetaSection - number of subsections is given // ||||||`------- S-Separate(PageBreak); T-Continuous; ' '-Default // |||||`-------- Column mode (1,2,3,' '-default) // ||||`--------- X -only proc section; x -orig. proc; ' ' -other // |||`---------- Position within the procedure // ||`----------- ALWAYS leave blank // |`------------ Step Section Header marker // `------------- Internal section number (starts at A) if (step.Substring(1, 1) == "0") { // if this section has the original edit section flag (sequence[2]) save the id. // set pagination, continuous, separate. If blank, don't create attribute - uses format default. if (sequence.Substring(4, 1) == "T") { ci.AddItem("Section", "Pagination", "C"); } else if (sequence.Substring(4, 1) == "S") { ci.AddItem("Section", "Pagination", "S"); } // Step: linked to enhanced (!exist = N) if (sequence.Substring(7, 1) == "1") { ci.AddItem("Step", "LnkEnh", "Y"); } char cbittst = sequence.PadRight(10)[8]; if (cbittst == ' ') cbittst = '\0'; else { // determine if TOC element (!exist = N) if ((cbittst & TOC) > 1) { ci.AddItem("Section", "TOC", "Y"); } // determine if autogenerated section (!exist = N) if ((cbittst & AUTOGEN) > 1) { isautogen = true; ci.AddItem("Section", "AutoGen", "Y"); } } // Here are subsection flags, i.e. the following are only set if this // is a subsection. bool didsub = false; if (isSubSection) { // Subsection: editable (!exist = Y) if ((cbittst & EDDATA) > 0) { ci.AddItem("SubSection", "Edit", "N"); } // Subsection: print section headers (!exist = Y) if ((cbittst & PH) > 0) { didsub = true; ci.AddItem("SubSection", "PH", "N"); } // Subsection: autoindent (!exist = Y) if ((cbittst & AUTOIND) > 0) { ci.AddItem("SubSection", "AutoIndent", "N"); } } if (!didsub && sequence.Substring(4, 1) == "N") { ci.AddItem("SubSection", "PH", "N"); } } else { // Accessory Section Format: // AI 1 2 // ^^ ^ ^ // || | | // || | `- # of pages (ASCII value minus 48) // || `--- Position within the procedure // |`----- Acc. page type (A,I, or F) // `------ Internal section number (starts at A) ci.AddItem("Section", "NumPages", sequence.Substring(3, 1)); // see if it's a libdoc too string thekey = procnum.PadRight(20) + step.Substring(0, 1).PadRight(10); if (dicLibDocRef.ContainsKey(thekey)) { // if it is a library document, see if the section record has already been // saved. If it has, just use this section id, otherwise, create the // section record with info from the library document file. libDocid = dicLibDocRef[thekey]; } } Item secitem = AddSection(procitem, num, title, stype, dts, init, ci, step + sequence, fmt, libDocid, pth, FromItem, docver); thesectid = secitem.ItemID; // if the editsectid hasn't been set yet, set it to this section id, i.e. the first // one processed. Then if this section has the original edit section flag (sequence[2]) // save the id. The first step is necessary in case there is no original edit section // flag set, so that the first section is the default one to get opened in edit. if (EditSectId==0)EditSectId = thesectid; if (libDocid<1 && step[1] == '0' && (sequence[2] == 'x' || sequence[2] == 'X')) EditSectId = thesectid; // ContentType (2 in the following call) are: // 0 = structure, // 1 = procedure, // 2 = section, // 3 = step // 4 = branch // fromtype values are (see steps.cs too) // 1 = procedure, // 2 = section, // 3 = caution // 4 = note // 5 = RNO // 6 = step // 7 = table if (!isautogen) { // Process the Data Table - First look for High Level Steps string sQry = string.Format("Step like '[{0}]%' and Sequence='S'", dr["Step"].ToString().Substring(0, 1)); DataView dv = new DataView(dt, sQry, "StepNo", DataViewRowState.CurrentRows); Item FrItem = null; frmMain.pbStepMaximum = dt.Rows.Count; frmMain.pbStepValue = 0; foreach (DataRowView drv in dv) { FrItem = MigrateStep(cn, dt, drv, FrItem, conv_caret, pth, docver); if (secitem.MyContent.ContentParts.Count == 0) { // type 6 is step secitem.MyContent.ContentParts.Add(6, FrItem); if (!secitem.MyContent.IsSavable) ErrorRpt.ErrorReport(secitem.MyContent); secitem.MyContent.Save(); } } } return secitem; } private void LoadSection(DataSet ds, OleDbDataAdapter da, string FileName) { try { da.Fill(ds, "Sections"); DataTable dt = ds.Tables["Sections"]; dt.CaseSensitive = true; dt.Columns.Add("CStep", System.Type.GetType("System.String")); dt.Columns.Add("CSequence", System.Type.GetType("System.String")); // set the cstep & csequence - couldn't do it in the add because it needed a sql function foreach (DataRow drw in ds.Tables["Sections"].Rows) { drw["CStep"] = TextConvert.ConvertSeq(drw["Step"].ToString()); drw["CSequence"] = TextConvert.ConvertSeq(drw["Sequence"].ToString()); } dt.Columns.Add("StepNo", System.Type.GetType("System.Int32"), "Convert(Convert(Substring(CStep,2,1),'System.Char'),'System.Int32')-48"); dt.Columns.Add("Level", System.Type.GetType("System.Int32"), "Len(CSequence)"); dt.Columns.Add("SubStepNo", System.Type.GetType("System.Int32"), "Convert(Convert(Substring(CSequence,Len(CSequence),1),'System.Char'),'System.Int32')-48"); dt.Columns.Add("locb", System.Type.GetType("System.Int32"), "Convert(Convert(Substring(CSequence,2,1),'System.Char'),'System.Int32')-48"); } catch (Exception ex) { FileInfo fi; switch (ex.Message) { case "Index file not found.":// then delete inf file fi = new FileInfo(frmMain.tbSourceText + "\\" + FileName + ".inf"); fi.Delete(); LoadSection(ds, da, FileName);// Try Again break; case "External table is not in the expected format.": // then pad dbt file with 128 zeros. fi = new FileInfo(frmMain.tbSourceText + "\\" + FileName + ".dbt"); FileStream fs = fi.OpenWrite(); fs.Position = fs.Length; byte[] buf = new byte[128]; for (int i = 0; i < 128; i++) buf[i] = 0; fs.Write(buf, 0, 128); fs.Close(); LoadSection(ds, da, FileName);// Try Again break; default: // Unrecognized error Console.WriteLine("Unrecognized error: error = {0}", ex.Message); log.ErrorFormat("File - {0}.DBF\r\n\r\n{1}\r\n\r\n{2}", FileName, ex.Message, ex.InnerException); break; } } } } }