From 45f0a22be4f92940ffee027137bc66ce4c394c98 Mon Sep 17 00:00:00 2001 From: Rich Date: Thu, 25 Mar 2010 19:31:05 +0000 Subject: [PATCH] Class to support overlay with VE-PROMS (16 bit) Class that performs print function Change to use frmPrintMSWord --- PROMS/VEPROMS/PrintMSWord/Program.cs | 2 +- PROMS/VEPROMS/PrintMSWord/Proms2010Print.cs | 209 +++++ PROMS/VEPROMS/PrintMSWord/PromsPrinter.cs | 854 ++++++++++++++++++++ 3 files changed, 1064 insertions(+), 1 deletion(-) create mode 100644 PROMS/VEPROMS/PrintMSWord/Proms2010Print.cs create mode 100644 PROMS/VEPROMS/PrintMSWord/PromsPrinter.cs diff --git a/PROMS/VEPROMS/PrintMSWord/Program.cs b/PROMS/VEPROMS/PrintMSWord/Program.cs index dd2fbb55..3ca02c65 100644 --- a/PROMS/VEPROMS/PrintMSWord/Program.cs +++ b/PROMS/VEPROMS/PrintMSWord/Program.cs @@ -14,7 +14,7 @@ namespace PrintMSWord { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new frmPrintMsWord()); + Application.Run(new frmPrintMSWord()); } } } \ No newline at end of file diff --git a/PROMS/VEPROMS/PrintMSWord/Proms2010Print.cs b/PROMS/VEPROMS/PrintMSWord/Proms2010Print.cs new file mode 100644 index 00000000..456b0319 --- /dev/null +++ b/PROMS/VEPROMS/PrintMSWord/Proms2010Print.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml.Serialization; +using VEPROMS.CSLA.Library; + +namespace PrintMSWord +{ + [XmlRoot("Proms2010Print")] + [Serializable()] + public class Proms2010Print + { + private string _PROMS16_Folder; + [XmlAttribute("PROMS16_Folder")] + public string PROMS16_Folder + { + get { return _PROMS16_Folder; } + set { _PROMS16_Folder = value; } + } + private Proms2010Procedures _Procedures; + //[XmlElement("Procedures")] + public Proms2010Procedures Procedures + { + get { return _Procedures; } + set { _Procedures = value; } + } + public Proms2010Procedure GetProcedure(ProcedureInfo myProc) + { + return Procedures.GetProcedure(myProc); + } + } + public class Proms2010Procedures : List + { + public Proms2010Procedure GetProcedure(ProcedureInfo myProc) + { + foreach (Proms2010Procedure proc in this) + if (proc.ItemID == myProc.ItemID) return proc; + return null; + } + } + public class Proms2010Procedure + { + public Proms2010Procedure() + { ;} + public Proms2010Procedure(ProcedureInfo myProc) + { + ItemID = myProc.ItemID; + Number = myProc.DisplayNumber; + Title = myProc.DisplayText; + Sections = Proms2010Sections.GetSections(myProc); + } + + private int _ItemID; + [XmlAttribute("ItemID")] + public int ItemID + { + get { return _ItemID; } + set { _ItemID = value; } + } + private string _Number; + [XmlAttribute("Number")] + public string Number + { + get { return _Number; } + set { _Number = value; } + } + private string _Title; + [XmlAttribute("Title")] + public string Title + { + get { return _Title; } + set { _Title = value; } + } + private int _PageCount; + [XmlAttribute("PageCount")] + public int PageCount + { + get { return _PageCount; } + set + { + if (Sections != null) + Sections.FixPageCount(value); + _PageCount = value; + } + } + private string _Rev; + [XmlAttribute("Rev")] + public string Rev + { + get { return _Rev; } + set { _Rev = value; } + } + private string _RevDate; + [XmlAttribute("RevDate")] + public string RevDate + { + get { return _RevDate; } + set { _RevDate = value; } + } + private Proms2010Sections _Sections; + [XmlElement("Sections")] + public Proms2010Sections Sections + { + get { return _Sections; } + set { _Sections = value; } + } + public Proms2010Section GetSection(SectionInfo mySection) + { + return Sections.GetSection(mySection); + } + } + public class Proms2010Sections : List + { + public static Proms2010Sections GetSections(ProcedureInfo proc) + { + Proms2010Sections sections = new Proms2010Sections(); + foreach (SectionInfo mySection in proc.Sections) + sections.Add(new Proms2010Section(mySection)); + return sections; + } + public int TotalPages + { + get + { + int retval = 0; + foreach (Proms2010Section section in this) + retval += section.PageCount; + return retval; + } + } + public void FixPageCount(int total) + { + int stepPages = total - TotalPages; + foreach (Proms2010Section section in this) + if (section.PageCount == 0) + { + section.PageCount = stepPages; + break; + } + FixStartingPages(); + } + public void FixStartingPages() + { + int pageCount = 0; + foreach (Proms2010Section section in this) + { + section.StartingPage = pageCount; + pageCount += section.PageCount; + } + } + public Proms2010Section GetSection(SectionInfo mySection) + { + foreach (Proms2010Section section in this) + if (section.ItemID == mySection.ItemID) + return section; + return null; + } + } + public class Proms2010Section + { + public Proms2010Section() + { ;} + public Proms2010Section(SectionInfo mySection) + { + ItemID = mySection.ItemID; + Number = mySection.DisplayNumber; + Title = mySection.DisplayText; + if (mySection.MyContent.MyEntry != null) // MSWord Section + PageCount = (int)Math.Ceiling(double.Parse(mySection.SectionConfig.Section_NumPages)); + else // Step Section + PageCount = 0; + } + private int _ItemID; + [XmlAttribute("ItemID")] + public int ItemID + { + get { return _ItemID; } + set { _ItemID = value; } + } + private string _Number; + [XmlAttribute("Number")] + public string Number + { + get { return _Number; } + set { _Number = value; } + } + private string _Title; + [XmlAttribute("Title")] + public string Title + { + get { return _Title; } + set { _Title = value; } + } + private int _PageCount; + [XmlAttribute("PageCount")] + public int PageCount + { + get { return _PageCount; } + set { _PageCount = value; } + } + private int _StartingPage = 0; + [XmlAttribute("StartingPage")] + public int StartingPage + { + get { return _StartingPage; } + set { _StartingPage = value; } + } + } +} diff --git a/PROMS/VEPROMS/PrintMSWord/PromsPrinter.cs b/PROMS/VEPROMS/PrintMSWord/PromsPrinter.cs new file mode 100644 index 00000000..5be51013 --- /dev/null +++ b/PROMS/VEPROMS/PrintMSWord/PromsPrinter.cs @@ -0,0 +1,854 @@ +using System; +using System.Collections.Generic; +using System.Text; +using VEPROMS.CSLA.Library; +using Volian.Svg.Library; +using iTextSharp.text.factories; +using iTextSharp.text; +using iTextSharp.text.pdf; +using System.Text.RegularExpressions; +using System.IO; +using System.Xml; +using LBWordLibrary; +using System.Drawing; +using System.Drawing.Imaging; +using Volian.Controls.Library; + +namespace PrintMSWord +{ + public delegate void PromsPrinterStatusEvent(object sender,PromsPrintStatusArgs args); + public class PromsPrintStatusArgs + { + private string _MyStatus; + public string MyStatus + { + get { return _MyStatus; } + } + private DateTime _When = DateTime.Now; + public DateTime When + { + get { return _When; } + } + private PromsPrinterStatusType _Type; + public PromsPrinterStatusType Type + { + get { return _Type; } + set { _Type = value; } + } + public PromsPrintStatusArgs(string myStatus, PromsPrinterStatusType type) + { + _MyStatus = myStatus; + _Type = type; + } + } + public enum PromsPrinterStatusType + { + Start, + General, + MSWordToPDF, + PageList, + Watermark, + Read16, + Merge16, + Open16, + ReadMSWord, + MergeMSWord, + OpenMSWord, + OpenPDF, + Merge, + Total, + CloseDocument, + NewPage, + BuildSVG, + SetSVG, + SetPageEvent, + GetSection, + Before + } + public class PromsPrinter + { + public event PromsPrinterStatusEvent StatusChanged; + private void OnStatusChanged(object sender, PromsPrintStatusArgs args) + { + if (StatusChanged != null) + StatusChanged(sender, args); + } + private void OnStatusChanged(string myStatus, PromsPrinterStatusType type) + { + OnStatusChanged(this, new PromsPrintStatusArgs(myStatus, type)); + } + private string _Rev; + private string _RevDate; + private ItemInfo _MyItem; + private string _Watermark; + public PromsPrinter(ItemInfo myItem, string rev, string revDate, string watermark) + { + _MyItem = myItem; + _Rev = rev; + _RevDate = revDate; + _Watermark = watermark; + } + public string Print(string pdfFolder, Proms2010Print myProms2010Print, string myMSWordFile,System.Windows.Forms.Form myForm) + { + if(_MyItem is SectionInfo) + return Print(_MyItem as SectionInfo, pdfFolder, myProms2010Print,myForm); + else if (_MyItem is ProcedureInfo) + return Print(_MyItem as ProcedureInfo, pdfFolder, myProms2010Print,myForm); + return ""; + } + private string BuildMSWordPDF(SectionInfo section, System.Windows.Forms.Form myForm) + { + DateTime tStart = DateTime.Now; + string MSWordFile = null; + if (section.MyContent.ContentEntryCount == 1) + { + MSWordFile = MSWordToPDF.ToPDFReplaceROs(section, false, myForm); + OnStatusChanged("MSWord converted to PDF " + MSWordFile, PromsPrinterStatusType.MSWordToPDF); + } + return MSWordFile; + } + private string Print(SectionInfo mySection, string pdfFolder, Proms2010Print myProms2010Print, System.Windows.Forms.Form myForm) + { + // Create an output file name + string outputFileName = pdfFolder + "\\" + CreateFileName(mySection.MyProcedure.DisplayNumber, mySection.DisplayNumber, mySection.DisplayText); + //Console.WriteLine("Section {0}", outputFileName); + Proms2010Procedure proc = myProms2010Print.GetProcedure(mySection.MyProcedure); + Proms2010Section sect = proc == null ? null : proc.GetSection(mySection); + // Create an MSWord Pdf + // Setup a pdf Document for printing + PdfContentByte cb = OpenDoc(outputFileName); + // Create Layers + CreateLayers(cb); + // Setup pdfPageEventHelper for the particular Section + // Try to grab a 16-bit version of the output as a background + string procedureFileName = myProms2010Print.PROMS16_Folder + "\\" + CreateFileName(mySection.MyProcedure.DisplayNumber); + FileInfo VEPromsFile = new FileInfo(procedureFileName); + PdfReader reader16 = VEPromsFile.Exists ? new PdfReader(procedureFileName) : null; + // Loop through MSWord Pages + FormatInfo activeFormat = mySection.ActiveFormat; + DocStyle docStyle = GetDocStyle(activeFormat, (mySection.MyContent.Type ?? 10000)); + Svg mySvg = BuildSvg(mySection,activeFormat,docStyle); + cb.PdfWriter.PageEvent = new SvgPageHelper(mySvg,_PagelistLayer,_WatermarkLayer); + string myMSWordFile = BuildMSWordPDF(mySection,myForm); + PdfReader readerWord = myMSWordFile != null ? new PdfReader(myMSWordFile) : null; + for (int ii = 0; ii < sect.PageCount; ii++) + { + int pageNumber = 1 + ii + sect.StartingPage; + cb.PdfDocument.NewPage(); + PdfImportedPage bgPage = cb.PdfWriter.GetImportedPage(reader16, pageNumber); + AddImportedPageToLayer(cb.PdfWriter.DirectContentUnder, _BackgroundLayer, bgPage, 12, -9.7F); + if (readerWord != null) + { + PdfImportedPage fgPage = cb.PdfWriter.GetImportedPage(readerWord, ii + 1); + AddImportedPageToLayer(cb.PdfWriter.DirectContentUnder, _MSWordLayer, fgPage, 0, 0); + } + } + CloseDocument(cb, outputFileName); + // Return the fileName; + return outputFileName; + } + private int _PLPage = 0; + private int _PLOf = 0; + private List _MissingTokens = new List(); + private string ReplacePageListToken(Match match) + { + switch (match.Value) + { + case "{PAGE}": // Current Page Number + string retval = _PLPage.ToString(); + _PLPage++; // Increment Page Number + return retval; + case "{OF}": // Total Page Count for this section + return _PLOf.ToString(); + case "{REVDATE}": // Revision Date + return _RevDate; + case "{REV}": // Revision Number + return _Rev; + } + if (!_MissingTokens.Contains(match.Value)) + { + _MissingTokens.Add(match.Value); + Console.WriteLine("\t\t\t\tcase \"{0}\": // Unhandled Token\r\n\t\t\t\t\treturn \"\";", match.Value); + } + return ""; + } + //private Regex regexReplaceTokens = new Regex(@"{[^{}]}"); + private string mySvg_ProcessText(object sender, SvgProcessTextArgs args) + { + if (!args.MyText.Contains("{")) + return args.MyText; + return regexFindToken.Replace(args.MyText, new MatchEvaluator(ReplacePageListToken)); + } + private static void AddImportedPageToLayer(PdfContentByte cb, PdfLayer layer, PdfImportedPage page, float xOff, float yOff) + { + cb.BeginLayer(layer); + iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(page); + image.SetAbsolutePosition(xOff, yOff); + cb.AddImage(image); + cb.EndLayer(); + } + private PdfLayer _TextLayer; + private PdfLayer _BackgroundLayer; + private PdfLayer _MSWordLayer; + private PdfLayer _PagelistLayer; + private PdfLayer _WatermarkLayer; + private void CreateLayers(PdfContentByte cb) + { + _BackgroundLayer = new PdfLayer("16-Bit", cb.PdfWriter); + _MSWordLayer = new PdfLayer("32-Bit MSWord", cb.PdfWriter); + _PagelistLayer = new PdfLayer("32-Bit Pagelist", cb.PdfWriter); + _TextLayer = new PdfLayer("32-Bit Pagelist Text", cb.PdfWriter); + _WatermarkLayer = new PdfLayer("Watermark", cb.PdfWriter); + _WatermarkLayer.SetPrint("Watermark", true); + } + + private void CloseDocument(PdfContentByte cb, string fileName) + { + cb.PdfDocument.Close(); + OnStatusChanged("CloseDocument", PromsPrinterStatusType.CloseDocument); + System.Diagnostics.Process.Start(fileName); + OnStatusChanged("OpenPDF", PromsPrinterStatusType.OpenPDF); + } + + private PdfContentByte OpenDoc(string outputFileName) + { + iTextSharp.text.Document document = new iTextSharp.text.Document(PageSize.LETTER); + PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outputFileName, FileMode.Create)); + document.Open(); + // Create Layers + CreateLayers(writer.DirectContent); + return writer.DirectContent; + } + private string CreateFileName(string procNumber, string sectNumber, string sectTitle) + { + return FixFileName(procNumber + "_" + ((sectNumber ?? "") != "" ? sectNumber : sectTitle)); + } + private string CreateFileName(string procNumber) + { + return FixFileName(procNumber); + } + private string FixFileName(string name) + { + return Regex.Replace(name, "[ .,]", "_") + ".pdf"; + } + int _StepPageNumber = 0; + private string Print(ProcedureInfo myProcedure, string pdfFolder, Proms2010Print myProms2010Print, System.Windows.Forms.Form myForm) + { + OnStatusChanged("Print " + myProcedure.DisplayNumber, PromsPrinterStatusType.Start); + Proms2010Procedure proc = myProms2010Print.GetProcedure(myProcedure); + SetupPageCount(myProcedure, proc); + // Create an output file name + string outputFileName = pdfFolder + "\\" + CreateFileName(myProcedure.DisplayNumber); + //Console.WriteLine("Section {0}", outputFileName); + // Create an MSWord Pdf + // Setup a pdf Document for printing + OnStatusChanged("Before OpenDoc", PromsPrinterStatusType.Before); + PdfContentByte cb = OpenDoc(outputFileName); + OnStatusChanged("OpenDoc", PromsPrinterStatusType.Before); + // Setup pdfPageEventHelper for the particular Section + // Try to grab a 16-bit version of the output as a background + string procedureFileName = myProms2010Print.PROMS16_Folder + "\\" + CreateFileName(myProcedure.DisplayNumber); + FileInfo VEPromsFile = new FileInfo(procedureFileName); + PdfReader reader16 = VEPromsFile.Exists ? new PdfReader(procedureFileName) : null; + OnStatusChanged("OpenReader16", PromsPrinterStatusType.Open16); + // Loop through MSWord Pages + SvgPageHelper myHelper = null; + OnStatusChanged("Before NewPage", PromsPrinterStatusType.Before); + cb.PdfDocument.NewPage(); + OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage); + foreach (SectionInfo mySection in myProcedure.Sections) + { + OnStatusChanged("Before BuildSvg", PromsPrinterStatusType.Before); + FormatInfo activeFormat = mySection.ActiveFormat; + DocStyle docStyle = GetDocStyle(activeFormat, (mySection.MyContent.Type ?? 10000)); + Svg mySvg = BuildSvg(mySection,activeFormat,docStyle); + OnStatusChanged("After BuildSvg", PromsPrinterStatusType.BuildSVG); + if (myHelper == null) + { + cb.PdfWriter.PageEvent = myHelper = new SvgPageHelper(mySvg, _PagelistLayer, _WatermarkLayer); + OnStatusChanged("After Set PageEvent", PromsPrinterStatusType.SetPageEvent); + } + else + { + myHelper.MySvg = mySvg; + OnStatusChanged("After Set Svg", PromsPrinterStatusType.SetSVG); + } + string myMSWordFile = BuildMSWordPDF(mySection, myForm); + + PdfReader readerWord = myMSWordFile != null ? new PdfReader(myMSWordFile) : null; + OnStatusChanged("Open MSWord", PromsPrinterStatusType.OpenMSWord); + Proms2010Section sect = proc == null ? null : proc.GetSection(mySection); + OnStatusChanged("Get Section", PromsPrinterStatusType.GetSection); + SetupPageNumbering(docStyle, sect.PageCount); + for (int ii = 0; ii < sect.PageCount; ii++) + { + int pageNumber = 1 + ii + sect.StartingPage; + //OnStatusChanged("Before NewPage", PromsPrinterStatusType.Before); + //cb.PdfDocument.NewPage(); + //if (docStyle.NumberingSequence == E_NumberingSequence.IncludeWoThSteps) + // stepPageNumber = _PLPage; + //OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage); + if (reader16 != null) + { + PdfImportedPage bgPage = cb.PdfWriter.GetImportedPage(reader16, pageNumber); + OnStatusChanged("Read VEPROMS", PromsPrinterStatusType.Read16); + AddImportedPageToLayer(cb.PdfWriter.DirectContentUnder, _BackgroundLayer, bgPage, 12, -9.7F); + OnStatusChanged("Merge VEPROMS", PromsPrinterStatusType.Merge16); + } + if (readerWord != null) + { + PdfImportedPage fgPage = cb.PdfWriter.GetImportedPage(readerWord, ii + 1); + OnStatusChanged("Read MSWord", PromsPrinterStatusType.ReadMSWord); + AddImportedPageToLayer(cb.PdfWriter.DirectContentUnder, _MSWordLayer, fgPage, 0, 0); + OnStatusChanged("Merge MSWord", PromsPrinterStatusType.MergeMSWord); + } + OnStatusChanged("Before NewPage", PromsPrinterStatusType.Before); + cb.PdfDocument.NewPage(); + OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage); + } + SavePageNumbering(docStyle); + } + CloseDocument(cb, outputFileName); + // Return the fileName; + return outputFileName; + } + + private void SetupPageCount(ProcedureInfo myProcedure, Proms2010Procedure proc) + { + _PLPage = 1; + _PageNumber = new Dictionary(); + _PageNumber.Add("Procedure Steps", 1); + _PageCount = new Dictionary(); + _PageCount.Add("Procedure Steps", 0); + foreach (SectionInfo mySection in myProcedure.Sections) + { + if (mySection.IsStepSection) + { + Proms2010Section sect = proc == null ? null : proc.GetSection(mySection); + if (sect != null) _PageCount["Procedure Steps"] += sect.PageCount; + } + else + { + FormatInfo activeFormat = mySection.ActiveFormat; + DocStyle docStyle = GetDocStyle(activeFormat, (mySection.MyContent.Type ?? 10000)); + int pageCount = Convert.ToInt32(Math.Ceiling(mySection.MyContent.MyEntry.MyDocument.DocumentConfig.Printing_Length)); + switch (docStyle.IsStepSection ? E_NumberingSequence.WithSteps : docStyle.NumberingSequence ?? E_NumberingSequence.WithSteps) + { + case E_NumberingSequence.WithSteps: + _PageCount["Procedure Steps"] += pageCount; + break; + case E_NumberingSequence.NoPageNum: + case E_NumberingSequence.WithinEachDocStyle: + case E_NumberingSequence.WithinEachSection: + case E_NumberingSequence.WithinEachDocStyle1: + case E_NumberingSequence.GroupedByPagination: + case E_NumberingSequence.GroupedByLevel: + case E_NumberingSequence.WithStepsAndSecondaryPageNumber: + case E_NumberingSequence.WithStepsAndSecondaryPageNumberGroupedByLevel: + case E_NumberingSequence.Like6_ButDoesntNeedSubsection: + case E_NumberingSequence.Like6_ButDoesntNeedSubsection1: + default: + break; + } + } + } + } + Dictionary _PageNumber; + Dictionary _PageCount; + private void SavePageNumbering(DocStyle docStyle) + { + switch (docStyle.IsStepSection ? E_NumberingSequence.WithSteps : docStyle.NumberingSequence ?? E_NumberingSequence.WithSteps) + { + case E_NumberingSequence.WithSteps: + _PageNumber["Procedure Steps"] = _PLPage; + break; + case E_NumberingSequence.NoPageNum: + case E_NumberingSequence.WithinEachDocStyle: + case E_NumberingSequence.WithinEachSection: + case E_NumberingSequence.WithinEachDocStyle1: + case E_NumberingSequence.GroupedByPagination: + case E_NumberingSequence.GroupedByLevel: + case E_NumberingSequence.WithStepsAndSecondaryPageNumber: + case E_NumberingSequence.WithStepsAndSecondaryPageNumberGroupedByLevel: + case E_NumberingSequence.Like6_ButDoesntNeedSubsection: + case E_NumberingSequence.Like6_ButDoesntNeedSubsection1: + default: + break; + } + } + //private int _PLNextPage = 0; + //private int _PLNextOf = 0; + private void SetupPageNumbering(DocStyle docStyle, int pageCount) + { + //_PLNextOf = pageCount; + switch (docStyle.IsStepSection ? E_NumberingSequence.WithSteps : docStyle.NumberingSequence ?? E_NumberingSequence.WithSteps) + { + case E_NumberingSequence.WithSteps: + _PLPage = _PageNumber["Procedure Steps"]; + _PLOf = _PageCount["Procedure Steps"]; + break; + case E_NumberingSequence.NoPageNum: + case E_NumberingSequence.WithinEachDocStyle: + case E_NumberingSequence.WithinEachSection: + case E_NumberingSequence.WithinEachDocStyle1: + case E_NumberingSequence.GroupedByPagination: + case E_NumberingSequence.GroupedByLevel: + case E_NumberingSequence.WithStepsAndSecondaryPageNumber: + case E_NumberingSequence.WithStepsAndSecondaryPageNumberGroupedByLevel: + case E_NumberingSequence.Like6_ButDoesntNeedSubsection: + case E_NumberingSequence.Like6_ButDoesntNeedSubsection1: + default: + _PLOf = pageCount; + _PLPage = 1; + break; + } + Console.WriteLine("'{0}','{1}',{2}",docStyle.Name, docStyle.NumberingSequence,_PLPage); + } + private Svg BuildSvg(SectionInfo section,FormatInfo activeFormat,DocStyle docStyle) + { + Svg mySvg = null; + mySvg = SvgSerializer.StringDeserialize(BuildMyText(activeFormat)); + mySvg.ViewBox.Height = 1100; + mySvg.ViewBox.Width = 850; + mySvg.Height = new SvgMeasurement(11, E_MeasurementUnits.IN); + mySvg.Width = new SvgMeasurement(8.5F, E_MeasurementUnits.IN); + mySvg.LeftMargin = (float)docStyle.Layout.LeftMargin; + mySvg.TopMargin = 9.6F; + PageStyle pageStyle = docStyle.pagestyle; + AddPageListItems(mySvg, pageStyle, section); + //DocStyle docStyle = GetDocStyle(activeFormat, (section.MyContent.Type ?? 10000)); + mySvg.ProcessText += new SvgProcessTextEvent(mySvg_ProcessText); + return mySvg; + } + private static Regex regexTextOnly = new Regex(@"^[^{}]*$"); + private static Regex regexJustTokens = new Regex(@"^{([^{}\?]*}{)*[^{}\?]*}$"); + private static Regex regexConditional = new Regex(@"^{.*\?.*}$"); + private static Regex regexFindToken = new Regex("{[^{}]*}"); + private void AddPageListItems(Svg mySvg, PageStyle pageStyle, SectionInfo section) + { + SvgGroup svgGroup = new SvgGroup(); + foreach (PageItem pageItem in pageStyle.PageItems) + { + if (regexJustTokens.IsMatch(pageItem.Token)) + { + MatchCollection matches = regexFindToken.Matches(pageItem.Token); + foreach (Match match in matches) + { + string token = match.Value; + switch (match.Value) + { + case "{HEADER1}": + case "{HEADER2}": + case "{HEADER3}": + case "{HEADER4}": + case "{HEADER5}": + case "{BOX1}": + case "{BOX2}": + case "{BOX3}": + case "{BOX4}": + case "{BOX5}": + case "{BOX6}": + case "{BOX7}": + case "{BOX8}": + svgGroup.Add(PageItemToSvgUse(pageItem, FirstAndLast(token))); + break; + case "{DRAFTPAGE}": + case "{REFERENCEPAGE}": + case "{MASTERPAGE}": + case "{SAMPLEPAGE}": + mySvg.SetValidWaterMark(token, _Watermark); + break; + case "{PROCTITLE}": + SplitTitle(svgGroup, pageItem, section.MyProcedure.DisplayText, (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength); + break; + case "{EOPNUM}": + svgGroup.Add(PageItemToSvgText(pageItem, section.MyProcedure.DisplayNumber)); + break; + case "{SECTIONLEVELTITLE}": + SplitTitle(svgGroup, pageItem, section.DisplayText, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionTitleLength); + svgGroup.Add(PageItemToSvgText(pageItem, section.DisplayText)); + break; + case "{SECTIONLEVELNUMBER}": + svgGroup.Add(PageItemToSvgText(pageItem, section.DisplayNumber)); + break; + default: + Console.WriteLine("Token not processed {0}", token); + break; + } + } + } + else + { + svgGroup.Add(PageItemToSvgText(pageItem,pageItem.Token)); + } + } + mySvg.Add(svgGroup); + } + + private string FirstAndLast(string token) + { + // strip the curly braces and return the first and last character + // For example Header1 becomes H1 and Box2 becomes B2 + return token.Substring(1, 1) + token.Substring(token.Length - 2, 1); + } + private void SplitTitle(SvgGroup svgGroup, PageItem pageItem, string title, int? len) + { + // TODO: need to calculate len in either points or inches and use the font from the pageItem to determine the number of characters + if(len == null || title.Length < len) + { + svgGroup.Add(PageItemToSvgText(pageItem, title)); + return; + } + // Otherwise determine how many line to split the text into + List titleLines = SplitText(title,(int)len); + // Move up 6 Points per line to find the starting point + float yOffset = -6 * (titleLines.Count-1); + foreach (string line in titleLines) + { + svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset)); + yOffset += 12; + } + } + + + private List SplitText(string title, int len) + { + List retval = new List(); + int strlen = title.Length; + int start = 0; + while ((strlen - start) > len) + { + int width = FindWidth(title, start, len); + retval.Add(title.Substring(start, width)); + start += width; + while (title[start] == ' ') start++; + } + if (strlen - start > 0) + retval.Add(title.Substring(start, strlen - start)); + return retval; + } + + private int FindWidth(string title, int start, int len) + { + for (int ii = start + len; ii > start; ii--) + { + if (title[ii] == ' ') + { + while (title[ii] == ' ') ii--; + if (ii > start) + return 2 + ii - start; + return len; + } + } + return len; + } + + private string BuildMyText(FormatInfo activeFormat) + { + string sGenMac = activeFormat.GenMac; + if (!sGenMac.Contains("xmlns")) + sGenMac = sGenMac.Replace(".StringSerialize(mySvg); + XmlDocument xDocPrintout = new XmlDocument(); + xDocPrintout.LoadXml(str); + XmlNode xn = xDocPrintout.DocumentElement.ChildNodes[0]; + xn.AppendChild(xDocPrintout.ImportNode(xDocGenMac.DocumentElement, true)); + return xDocPrintout.OuterXml; + } + private DocStyle GetDocStyle(FormatInfo formatInfo, int type) + { + int i = type - 10000; + return formatInfo.PlantFormat.DocStyles.DocStyleList[i]; + } + private SvgPart PageItemToSvgUse(PageItem pageItem, string templateName) + { + SvgUse svgUse = new SvgUse(); + svgUse.UseID = templateName; + svgUse.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT); + svgUse.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT); + return svgUse; + } + private static SvgText PageItemToSvgText(PageItem pageItem, string text) + { + SvgText svgText = new SvgText(); + svgText.Text = text; + E_Justify justify = pageItem.Justify ?? E_Justify.PSLeft; + if ((justify & E_Justify.PSLeft) == E_Justify.PSLeft) + svgText.Justify = SvgJustify.Left; + else if ((justify & E_Justify.PSRight) == E_Justify.PSRight) + svgText.Justify = SvgJustify.Right; + else + svgText.Justify = SvgJustify.Center; + svgText.Font = pageItem.Font.WindowsFont; + svgText.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT); + svgText.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT); + if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace + return svgText; + } + private SvgPart PageItemToSvgText(PageItem pageItem, string text, float yOffset) + { + SvgText svgText = new SvgText(); + svgText.Text = text; + E_Justify justify = pageItem.Justify ?? E_Justify.PSLeft; + if ((justify & E_Justify.PSLeft) == E_Justify.PSLeft) + svgText.Justify = SvgJustify.Left; + else if ((justify & E_Justify.PSRight) == E_Justify.PSRight) + svgText.Justify = SvgJustify.Right; + else + svgText.Justify = SvgJustify.Center; + svgText.Font = pageItem.Font.WindowsFont; + svgText.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT); + svgText.Y = new SvgMeasurement((float)(yOffset + pageItem.Row ?? 0), E_MeasurementUnits.PT); + if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace + return svgText; + } + } + public static class MSWordToPDF + { + private static LBApplicationClass _MyApp = null; + public static LBApplicationClass MyApp + { + get + { + if (_MyApp == null) + _MyApp = new LBApplicationClass(); + return _MyApp; + } + } + public static string ToPDFReplaceROs(SectionInfo sect, bool openPdf, System.Windows.Forms.Form myForm ) + { + int docStyleIndex = ((int)sect.MyContent.Type) % 10000; + DocStyle myDocStyle = sect.ActiveFormat.PlantFormat.DocStyles.DocStyleList[docStyleIndex]; + PageStyle myPageStyle = myDocStyle.pagestyle; + ProcedureInfo proc = sect.ActiveParent as ProcedureInfo; + DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo; + ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst; + ROFSTLookup lookup = rofst.ROFSTLookup; + string igPrefix = dvi.DocVersionConfig.RODefaults_graphicsprefix; + string spPrefix = dvi.DocVersionConfig.RODefaults_setpointprefix; + // string AccPageID = string.Format("<{0}-{1}>", accPrefix, roch.appid); + + //AddInfo("{0}:{1}", proc.DisplayNumber, (sect.DisplayNumber == "" ? sect.DisplayText : sect.DisplayNumber)); + using (DSOFile myFile = new DSOFile(sect.MyContent.MyEntry.MyDocument)) + { + LBDocumentClass myDoc = MyApp.Documents.Open(myFile.FullName); + float newTop = (float)myDocStyle.Layout.TopRow; + float newLeft = (float)myDocStyle.Layout.LeftMargin; + float newLength = (float)myDocStyle.Layout.PageLength; + float newWidth = (float)myDocStyle.Layout.PageWidth; + float oldTop = myDoc.PageSetup.TopMargin; + float oldLeft = myDoc.PageSetup.LeftMargin; + float oldBottom = myDoc.PageSetup.BottomMargin; + float oldRight = myDoc.PageSetup.RightMargin; + float oldHeight = myDoc.PageSetup.PageHeight; + float oldWidth = myDoc.PageSetup.PageWidth; + float newRight = oldWidth - (newWidth + newLeft); + if (newRight < 0) newRight = 0; + float newBottom = oldBottom - newTop; + //Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", newTop, newLeft, newLength, newWidth, oldTop, oldLeft, oldBottom, oldRight,oldHeight,oldWidth); + myDoc.PageSetup.BottomMargin = 0;// 11 * 72 - (newTop + newLength); + myDoc.PageSetup.RightMargin = newRight; + myDoc.PageSetup.LeftMargin = newLeft; + myDoc.PageSetup.TopMargin = newTop; + LBSelection sel = FindRO(); + while (sel != null) + { + string val = lookup.GetROValueByAccPagID(sel.Text, spPrefix, igPrefix); + int? type = lookup.GetROTypeByAccPagID(sel.Text, spPrefix, igPrefix); + if ((int)type == 8) // Image + { + //Console.WriteLine("Image: {0} - {1}", sect.MyContent.Number, sect.MyContent.Text); + bool imageROTokenReplaced = false; + string[] vals = val.Split("\n".ToCharArray()); + ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]); + if (roImage != null) + { + ROImageFile roImageFile = new ROImageFile(roImage); + float width = 72 * Int32.Parse(vals[3], System.Globalization.NumberStyles.AllowHexSpecifier) / 12.0F; + int lines = Int32.Parse(vals[2], System.Globalization.NumberStyles.AllowHexSpecifier); + float height = 72 * lines / 6.0F; + //sel.MoveEnd(LBWdUnits.wdLine, lines);// The number of lines depends on the third parameter + //sel.EndKey(LBWdUnits.wdLine, true); + //sel.MoveEnd(LBWdUnits.wdCharacter, -1); + //Console.WriteLine("Lines = {0}", lines); + sel.Text = ""; + // TODO: Need to create a temporary file for printing. + // TODO: Need a way to eliminate the temporary file when done printing. + // LBInlineShape shape = sel.InlineShapes.AddPicture(@"C:\Plant\HLP\VEHLP\ro\No1Seal.bmp"); + float x = (float)sel.get_Information(LBWdInformation.wdHorizontalPositionRelativeToPage); + float y = (float)sel.get_Information(LBWdInformation.wdVerticalPositionRelativeToPage); + //LBInlineShape shape = sel.InlineShapes.AddPicture(pngFile); + LBRange myRange = sel.Paragraphs.First.Range; + float yTop = (float)myRange.get_Information(LBWdInformation.wdVerticalPositionRelativeToPage); + LBShape shape = myDoc.Shapes.AddPicture(roImageFile.MyFile.FullName, x, y - yTop, sel.Range); + // LBInlineShape shape = sel.InlineShapes.AddPicture(roImageFile.MyFile.FullName); + //Console.WriteLine("{0} Shape Width {1} Height {2}", val.Replace("\n", "','"), shape.Width, shape.Height); + shape.Width = width; + shape.Height = height; + //Console.WriteLine("{0} Shape Width {1} Height {2}", val.Replace("\n", "','"), shape.Width, shape.Height); + imageROTokenReplaced = true; + } + if (!imageROTokenReplaced) + sel.Text = string.Format("Bad Image Link (Missing Image File:{0})", vals[0]); + } + else if ((int)type == 4) // X-Y Plot + { + val = val.Replace("`", "\xB0"); + //AddInfo("\tRO Found {0} = '{1}'", sel.Text, val); + sel.Text = ""; + //float width = 72 * Int32.Parse(vals[3], System.Globalization.NumberStyles.AllowHexSpecifier) / 12.0F; + //float height = 72 * lines / 6.0F; + string pngFile = @"C:\Temp\XYPlot1.png"; + RectangleF plotRect = CreatePlot(pngFile, val, 600F,myForm); + //LBShape shape = myDoc.Shapes.AddPicture(@"C:\Temp\XYPlot.png", 0, 0, sel.Range); + float x = (float)sel.get_Information(LBWdInformation.wdHorizontalPositionRelativeToPage); + float y = (float)sel.get_Information(LBWdInformation.wdVerticalPositionRelativeToPage); + //LBInlineShape shape = sel.InlineShapes.AddPicture(pngFile); + LBRange myRange = sel.Paragraphs.First.Range; + float yTop = (float)myRange.get_Information(LBWdInformation.wdVerticalPositionRelativeToPage); + float xAdjust = -29.3F; // TODO: Check this value + float yAdjust = 9.1F; // TODO: Check this value + LBShape shape = myDoc.Shapes.AddPicture(pngFile, x + xAdjust + plotRect.X, yAdjust + y - yTop + plotRect.Y, sel.Range); + //Console.WriteLine(",{0},{1},{2},{3}", x, y - yTop, xAdjust,yAdjust); + shape.LockAspectRatio = LBMsoTriState.msoTrue; + //shape.Width = .89F * shape.Width; + //shape.Width = float.Parse(tbAdjust.Text) * shape.Width; + shape.Width = plotRect.Width; + //shape.Height = .89F * shape.Height; + sel.WholeStory(); + sel.Range.Font.Color = LBWdColor.wdColorRed; + //Console.WriteLine("{0} Shape Width {1} Height {2}", val.Replace("\n", "','"), shape.Width, shape.Height); + //shape.Width = width; + //shape.Height = height; + //Console.WriteLine("{0} Shape Width {1} Height {2}", val.Replace("\n", "','"), shape.Width, shape.Height); + //imageROTokenReplaced = true; + } + else + { + val = val.Replace("`", "\xB0"); + //AddInfo("\tRO Found {0} = '{1}'", sel.Text, val); + InsertROValue(sel, val, sect.ActiveFormat.PlantFormat.FormatData.ROData.UpRoIfPrevUpper); + } + sel = FindRO(); + } + sel = MyApp.Selection; + sel.WholeStory(); + sel.Range.Font.Color = LBWdColor.wdColorRed; + sel.ParagraphFormat.LineSpacingRule = LBWdLineSpacing.wdLineSpaceExactly; + sel.ParagraphFormat.LineSpacing = 12; + //Console.WriteLine("{0},{1}", sel.ParagraphFormat.LineSpacing, sel.ParagraphFormat.LineSpacingRule); + string fileName = sect.DisplayNumber == "" ? sect.DisplayText : sect.DisplayNumber; + //MyApp.Visible = true; + //MessageBox.Show("Ready to make PDF"); + //MyApp.Visible = false; + fileName = CreatePDF(fileName, openPdf); + //MyApp.Visible = true; + MyApp.ActiveDocument.Close(); + MyApp.Quit(); + _MyApp = null; + return fileName; + } + } + private static RectangleF CreatePlot(string pngFile, string xyPlot, float resolution, System.Windows.Forms.Form myForm) + { + RectangleF retval = new RectangleF(0, 0, 0, 0); + Graphics grfx = myForm.CreateGraphics(); + string emfFile = pngFile.Replace(".png", ".emf"); + Metafile mf = new Metafile(emfFile, grfx.GetHdc()); + grfx.Dispose(); + grfx = Graphics.FromImage(mf); + float dpi = grfx.DpiX; + //grfx.ScaleTransform(resolution / grfx.DpiX, (resolution +1F) / grfx.DpiY); + grfx.ScaleTransform(resolution / grfx.DpiX, resolution / grfx.DpiY); + grfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; + grfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + grfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + grfx.Clear(System.Drawing.Color.Transparent); + XYPlots.XYPlot.BlackColor = System.Drawing.Color.Red; + XYPlots.XYPlot myPlot = new XYPlots.XYPlot(xyPlot); + myPlot.SetMargins(0, 0, 0, 0); + myPlot.Process(new VG.VGOut_Graphics(grfx)); + grfx.Dispose(); + GraphicsUnit gu = new GraphicsUnit(); + retval = mf.GetBounds(ref gu); + retval.Width *= dpi / resolution; + retval.Height *= dpi / resolution; + retval.X *= dpi / resolution; + retval.Y *= dpi / resolution; + //retval.X = myPlot.Width-retval.Width; + //AddInfo("{0},{1},{2},{3},{4},{5}", myPlot.Width, myPlot.Height, retval.Width, retval.Height,retval.X,retval.Y); + //Console.Write("{0},{1},{2},{3}", myPlot.Width, myPlot.Height, retval.Width, retval.Height); + mf.Save(pngFile, ImageFormat.Png); + //Console.WriteLine("'pngfile','{0}'", pngFile); + mf.Dispose(); + FileInfo myFile = new System.IO.FileInfo(emfFile); + myFile.Delete(); + return retval; + } + private static void InsertROValue(LBSelection sel, string roValue, bool upRoIfPrevUpper) + { + if (roValue == null) + { + sel.Text = "RO Not Found"; + sel.Font.Color = LBWdColor.wdColorRed; + } + else + { + if (upRoIfPrevUpper && sel.LastWasUpper) roValue = roValue.ToUpper(); + // Convert fortran formatted numbers to scientific notation. + + string tmp = DisplayRO.ConvertFortranFormatToScienctificNotation(roValue); + // Look for superscript or subscript and insert the appropriate commands + Match roMatch = Regex.Match(tmp, @"(.*?)\\(super|sub) (.*?)\\nosupersub "); + if (roMatch.Groups.Count == 4)// Superscript or subscript found + { + sel.Font.Color = LBWdColor.wdColorRed; + while (roMatch.Groups.Count == 4) + { + sel.TypeText(roMatch.Groups[1].Value); // output the text preceeding the super or sub command + sel.Font.Position = roMatch.Groups[2].Value=="super" ? 2 : -2; // Shift the vertical position for super or sub + sel.TypeText(roMatch.Groups[3].Value); // output the superscript or subscript + sel.Font.Position = 0; // restore the vertical position + tmp = tmp.Substring(roMatch.Length); // remove the processed text + roMatch = Regex.Match(tmp, @"(.*?)\\(super|sub) (.*?)\\nosupersub "); // check to see if the text contain another super or sub + } + if(tmp != "")// Add any remaining text + sel.TypeText(tmp); + sel.Font.Color = LBWdColor.wdColorAutomatic; + } + else // if no superscripts or subscripts just output the text + { + sel.Text = roValue; + sel.Font.Color = LBWdColor.wdColorRed; + } + } + } + private static LBSelection FindRO() + { + LBSelection sel = MyApp.Selection; + LBFind find = sel.Find; + find.ClearFormatting(); + find.Text = "[<](?@)-(?@)[>]"; + //find.Wrap = LBWdFindWrap.wdFindStop; + find.Wrap = LBWdFindWrap.wdFindContinue; + find.MatchCase = false; + find.MatchWholeWord = false; + find.MatchWildcards = true; + find.MatchSoundsLike = false; + find.MatchAllWordForms = false; + if (find.Execute()) return sel; + return null; + } + private static string CreatePDF(string fileName, bool openPdf) + { + return MyApp.CreatePDF(@"C:\Temp\" + fileName + ".pdf", openPdf); + } + + } +}