using System; using System.Collections.Generic; using System.Text; using VEPROMS.CSLA.Library; using iTextSharp.text.pdf; using iTextSharp.text; using System.IO; using System.Text.RegularExpressions; namespace Volian.Print.Library { public delegate void TransitionReportEvent(object sender, EventArgs args); public class PDFTransitionReport { public event TransitionReportEvent TransitionProcessed; private void OnTransitionProcessed(object sender, EventArgs args) { if (TransitionProcessed != null) TransitionProcessed(sender, args); } public event TransitionReportEvent ProcedureProcessed; private void OnProcedureProcessed(object sender, EventArgs args) { if (ProcedureProcessed != null) ProcedureProcessed(sender, args); } public event TransitionReportEvent DocVersionProcessed; private void OnDocVersionProcessed(object sender, EventArgs args) { if (DocVersionProcessed != null) DocVersionProcessed(sender, args); } private string _FileName; public string FileName { get { return _FileName; } set { _FileName = value; } } private PdfPCell _CurrentPageNumberCell = null; private int _CurrentPageNumber = 1; public int CurrentPageNumber { get { return _CurrentPageNumber; } set { if (_CurrentPageNumberCell != null) { _CurrentPageNumber = value; _CurrentPageNumberCell.Phrase.Clear(); _CurrentPageNumberCell.Phrase.Add("Page " + value.ToString()); } } } private FolderInfo folderInfo; private ProcedureInfo procedureInfo; private TransitionInfoList transitionInfoList; private int _TransitionInfoCount; public int TransitionInfoCount { get { return _TransitionInfoCount; } set { _TransitionInfoCount = value; } } private List _MyDocVersionList; public List MyDocVersionList { get { return _MyDocVersionList; } set { _MyDocVersionList = value; } } private int _ProcedureCount; public int ProcedureCount { get { return _ProcedureCount; } set { _ProcedureCount = value; } } public PDFTransitionReport(FolderInfo fi, string fileName) { _FileName = fileName; folderInfo = fi; } public PDFTransitionReport(ProcedureInfo pi, string fileName) { _FileName = fileName; procedureInfo = pi; transitionInfoList = TransitionInfoList.GetTransitionReportData(procedureInfo.MyDocVersion.VersionID, procedureInfo.ItemID); _TransitionInfoCount = transitionInfoList.Count; } public void BuildTransitionReport() { iTextSharp.text.Document document = new iTextSharp.text.Document(PageSize.LETTER.Rotate(), 36, 36, 36, 36); if (!CreateResultsPDF(document)) return; try { if (folderInfo != null) { if (MyDocVersionList.Count == 1) { DocVersionInfo dvi = MyDocVersionList[0]; foreach (ProcedureInfo pi in dvi.Procedures) { procedureInfo = pi; transitionInfoList = TransitionInfoList.GetTransitionReportData(dvi.VersionID, procedureInfo.ItemID); if (transitionInfoList.Count > 0) { _TransitionInfoCount = transitionInfoList.Count; OnProcedureProcessed(this, new EventArgs()); BuildProcedureReport(document); } else { OnProcedureProcessed(this, new EventArgs()); } } } else { foreach (DocVersionInfo dvi in MyDocVersionList) { ProcedureCount = dvi.Procedures.Count; OnDocVersionProcessed(this, new EventArgs()); foreach (ProcedureInfo pi in dvi.Procedures) { procedureInfo = pi; transitionInfoList = TransitionInfoList.GetTransitionReportData(dvi.VersionID, procedureInfo.ItemID); _TransitionInfoCount = transitionInfoList.Count; OnProcedureProcessed(this, new EventArgs()); BuildProcedureReport(document); } } } } else { BuildProcedureReport(document); } } catch (Exception ex) { StringBuilder msg = new StringBuilder(); document.Add(new Paragraph("Error:")); while (ex != null) { document.Add(new Paragraph(ex.GetType().Name)); document.Add(new Paragraph(ex.Message)); ex = ex.InnerException; } } finally { if (document.IsOpen()) { document.Close(); //System.Diagnostics.Process.Start(_FileName); } } } PdfOutline outline = null; ProcedureInfo lastProcedureInfo = null; private PdfPTable BuildProcedurePDFTable(Dictionary levels, Dictionary fonts, int cols, int paddingBottom, int level, iTextSharp.text.Document doc) { PdfPTable t = new PdfPTable(cols); t.HeaderRows = 4; t.DefaultCell.Padding = 4; t.WidthPercentage = 100; float[] widths; if(level == 1 || level == 2 || level == 4) widths = new float[] { 20f, 47f, 33f }; else widths = new float[] { 33f, 47f, 20f }; t.SetWidths(widths); //report title Phrase h = new Phrase(); h.Font = fonts[1]; if (folderInfo != null) h.Add(string.Format("Procedure Set {0} Transition Report", folderInfo.Name)); else h.Add("Transition Report"); PdfPCell c = new PdfPCell(h); c.Colspan = cols-1; c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.DarkGoldenrod); t.AddCell(c); //date generated h = new Phrase(); h.Font = fonts[4]; h.Add(DateTime.Now.ToString("dddd MMMM d, yyyy @ h:mm tt")); c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_RIGHT; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.DarkGoldenrod); t.AddCell(c); //procedure title h = new Phrase(); h.Font = fonts[2]; h.Add(string.Format("{0} - {1}", procedureInfo.DisplayNumber, procedureInfo.DisplayText)); PdfDestination dest = new PdfDestination(PdfDestination.FITH, cb.PdfDocument.PageSize.Height); if (lastProcedureInfo != procedureInfo) { outline = new PdfOutline(cb.RootOutline, dest, procedureInfo.DisplayNumber, false); lastProcedureInfo = procedureInfo; } c = new PdfPCell(h); c.Colspan = cols-1; c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.Goldenrod); t.AddCell(c); //page number _CurrentPageNumberCell = BuildCell(1, string.Format("Page {0}",CurrentPageNumber), fonts[4], new Color(System.Drawing.Color.Goldenrod)); _CurrentPageNumberCell.PaddingBottom = paddingBottom; t.AddCell(_CurrentPageNumberCell); //transition category h = new Phrase(); h.Font = fonts[3]; if (transitionInfoList.Count == 0) h.Add("N/A"); else { h.Add(levels[level]); dest = new PdfDestination(PdfDestination.FITH, cb.PdfDocument.PageSize.Height); new PdfOutline(outline, dest, levels[level]); } c = new PdfPCell(h); c.Colspan = cols; c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.Khaki); t.AddCell(c); //add column headers h = new Phrase(); h.Font = fonts[4]; h.Add("From Procedure Location"); c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_CENTER; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.PaleGoldenrod); t.AddCell(c); h = new Phrase(); h.Font = fonts[4]; h.Add("From Procedure Text"); c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_CENTER; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.PaleGoldenrod); t.AddCell(c); h = new Phrase(); h.Font = fonts[4]; h.Add("To Procedure Location"); c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_CENTER; c.PaddingBottom = paddingBottom; c.BackgroundColor = new Color(System.Drawing.Color.PaleGoldenrod); t.AddCell(c); return t; } PdfContentByte cb; private void BuildProcedureReport(iTextSharp.text.Document doc) { Dictionary tranTypes = FormatInfo.GetTransitionTypesByFormatID(procedureInfo.ActiveFormat.FormatID); Dictionary levels = new Dictionary(); levels.Add(1, "Internal Transitions"); levels.Add(2, "External From Transitions"); levels.Add(3, "External To Transitions"); levels.Add(4, "Outside From Transitions"); levels.Add(5, "Outside To Transitions"); Dictionary fonts = new Dictionary(); fonts.Add(1, pdf.GetFont("Arial Unicode MS", 12, 0, Color.BLACK)); fonts.Add(2, pdf.GetFont("Arial Unicode MS", 10, 0, Color.BLACK)); fonts.Add(3, pdf.GetFont("Arial Unicode MS", 8, 0, Color.BLACK)); fonts.Add(4, pdf.GetFont("Arial Unicode MS", 8, 0, Color.BLACK)); int lastLevel = transitionInfoList.Count > 0 ? transitionInfoList[0].Level : 0; //set level to first transition level #region buildtable int cols = 3; int paddingBottom = 6; if (folderInfo != null) doc.NewPage(); PdfPTable t = BuildProcedurePDFTable(levels, fonts, cols, paddingBottom, lastLevel, doc); #endregion //gather data if (transitionInfoList.Count == 0) { Phrase h = new Phrase(); h.Font = fonts[4]; h.Add("This procedure contains no transitions"); PdfPCell c = new PdfPCell(h); c.Colspan = cols; c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; t.AddCell(c); } else { foreach (TransitionInfo ti in transitionInfoList) { //add category OnTransitionProcessed(this, new EventArgs()); if (ti.Level != lastLevel) { if (lastLevel > 0) { doc.Add(t); doc.NewPage(); lastLevel = ti.Level; t = BuildProcedurePDFTable(levels, fonts, cols, paddingBottom, lastLevel, doc); } } //add from path Phrase h = new Phrase(); h.Font = fonts[4]; h.Add(StripProcInfo(ti.PathFrom, procedureInfo)); PdfPCell c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; if (lastLevel > 1 && (!tranTypes[ti.TranType].Contains("{Proc") && !tranTypes[ti.TranType].Contains("other procedure"))) c.BackgroundColor = new Color(System.Drawing.Color.LightCoral); t.AddCell(c); //add from text h = new Phrase(); h.Font = fonts[4]; ItemInfo myItemInfo = ti.MyContent.ContentItems[0]; h.Add(GetTextPath(myItemInfo, 0)); c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; if (lastLevel > 1 && (!tranTypes[ti.TranType].Contains("{Proc") && !tranTypes[ti.TranType].Contains("other procedure"))) c.BackgroundColor = new Color(System.Drawing.Color.LightCoral); t.AddCell(c); //add to text h = new Phrase(); h.Font = fonts[4]; myItemInfo = ti.MyItemToID; h.Add(GetTextPath(myItemInfo, ti.Level)); c = new PdfPCell(h); c.HorizontalAlignment = Element.ALIGN_LEFT; c.PaddingBottom = paddingBottom; if (lastLevel > 1 && (!tranTypes[ti.TranType].Contains("{Proc") && !tranTypes[ti.TranType].Contains("other procedure"))) c.BackgroundColor = new Color(System.Drawing.Color.LightCoral); t.AddCell(c); } } doc.Add(t); } private string StripProcInfo(string pathfrom, ProcedureInfo procedureInfo) { if (pathfrom.StartsWith(procedureInfo.DisplayNumber)) return pathfrom.Replace(string.Format("{0}, {1}", procedureInfo.DisplayNumber, procedureInfo.DisplayText), "").Trim(); else return pathfrom; } private string GetTextPath(ItemInfo myItemInfo, int level) { StringBuilder sb = new StringBuilder(); if (myItemInfo.IsProcedure) return myItemInfo.MyProcedure.DisplayNumber + " " + myItemInfo.MyProcedure.DisplayText; if (myItemInfo.IsSection) { if (level > 1) return myItemInfo.MyProcedure.DisplayNumber + " " + myItemInfo.MyProcedure.DisplayText + "\r\n " + myItemInfo.DisplayText; else return myItemInfo.DisplayText; } if (myItemInfo.IsHigh) return myItemInfo.ActiveSection.DisplayText + "\r\n " + myItemInfo.DisplayText; else { string tmp = ""; return GetTextPath(myItemInfo, sb, ref tmp); } } private string GetTextPath(ItemInfo myItemInfo, StringBuilder sb, ref string indent) { if (myItemInfo == null) return sb.ToString(); if (myItemInfo.IsHigh) { sb.Append(myItemInfo.DisplayText); } else { if (myItemInfo.ActiveParent != null) { GetTextPath(myItemInfo.ActiveParent as ItemInfo, sb, ref indent); indent += " "; sb.Append("\r\n" + indent + myItemInfo.DisplayText); } } return sb.ToString(); } public void BuildTransitionReport(FolderInfo fi) { System.Windows.Forms.MessageBox.Show("folder"); } private bool CreateResultsPDF(iTextSharp.text.Document document) { bool result = false; string suffix = ""; int i = 0; // just for safety, the while loop expects to find a file extension // so make sure it has one before going into the loop if (!_FileName.ToUpper().EndsWith(".PDF")) _FileName += ".pdf"; // Try to open a file for creating the PDF. while (result == false) { string fileName = _FileName; // Bug fix: B2013-086 // the folder path part of _FileName contained a folder name with a period // resulting is an invalid file location/file name. // Changed the IndexOf call to the LastIndexOf //int loc = fileName.IndexOf("."); int loc = fileName.LastIndexOf("."); if (loc > -1) { string fname = fileName.Substring(0, loc); fileName = fname + suffix + ".pdf"; } else fileName = fileName + suffix + ".pdf"; // string fileName = _FileName.ToLower().Replace(".pdf", suffix + ".pdf"); try { PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(fileName, FileMode.Create)); writer.PageEvent = new MyPageEvent(this); document.SetMargins(36, 36, 36, 36); document.Open(); cb = writer.DirectContent; _FileName = fileName; result = true; } catch (System.IO.IOException exIO) { if (exIO.Message.Contains("because it is being used by another process")) suffix = string.Format("_{0}", ++i);// If this file is in use, increment the suffix and try again else // If some other error, display a message and don't print the results { ShowException(exIO); return false; } } catch (Exception ex) { ShowException(ex); return false; // Could not open the output file } } return true; } private static void ShowException(Exception ex) { Console.WriteLine("{0} - {1}", ex.GetType().Name, ex.Message); StringBuilder msg = new StringBuilder(); string sep = ""; string indent = ""; while (ex != null) { msg.Append(string.Format("{0}{1}{2}:\r\n{1}{3}", sep, indent, ex.GetType().Name, ex.Message)); ex = ex.InnerException; sep = "\r\n"; indent += " "; } System.Windows.Forms.MessageBox.Show(msg.ToString(), "Error during PDF creation for search:", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); } private PdfPCell BlankCell(int colSpan) { PdfPCell c = new PdfPCell(); c.Colspan = colSpan; c.Border = 0; return c; } private PdfPCell BuildCell(int colspan, string txt, Font f, iTextSharp.text.Color clr) { Phrase h = new Phrase(); h.Font = f; h.Add(txt); PdfPCell c = new PdfPCell(h); c.HorizontalAlignment = iTextSharp.text.Element.ALIGN_RIGHT; c.Colspan = colspan; c.BackgroundColor = clr; return c; } } public class MyPageEvent : PdfPageEventHelper { private PDFTransitionReport _rpt = null; public MyPageEvent(PDFTransitionReport rpt) { _rpt = rpt; } public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document) { base.OnEndPage(writer, document); _rpt.CurrentPageNumber = writer.PageNumber + 1; } } }