2011-07-29 13:42:24 +00:00

528 lines
19 KiB
C#

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 System.Windows.Forms;
using LBWordLibrary;
using System.Drawing;
using System.Drawing.Imaging;
using Volian.Controls.Library;
namespace Volian.Print.Library
{
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; }
}
private int _Progress = 0;
public int Progress
{
get { return _Progress; }
set { _Progress = value; }
}
public PromsPrintStatusArgs(string myStatus, PromsPrinterStatusType type)
{
_MyStatus = myStatus;
_Type = type;
}
public PromsPrintStatusArgs(string myStatus, PromsPrinterStatusType type, int progress)
{
_MyStatus = myStatus;
_Type = type;
_Progress = progress;
}
}
public enum PromsPrinterStatusType
{
Start,
General,
MSWordToPDF,
PageList,
Watermark,
Read16,
Merge16,
Open16,
ReadMSWord,
MergeMSWord,
OpenMSWord,
OpenPDF,
Merge,
Total,
CloseDocument,
NewPage,
BuildSVG,
SetSVG,
SetPageEvent,
GetSection,
Before,
BuildStep,
Progress,
ProgressSetup
}
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 void OnStatusChanged(string myStatus, PromsPrinterStatusType type, int progress)
{
OnStatusChanged(this, new PromsPrintStatusArgs(myStatus, type, progress));
}
private string _Rev;
private string _RevDate;
private ItemInfo _MyItem;
private string _Watermark;
private string _PDFFile;
public string PDFFile
{
get { return _PDFFile; }
set { _PDFFile = value; }
}
private bool _DebugOutput;
public bool DebugOutput
{
get { return _DebugOutput; }
set { _DebugOutput = value; }
}
private string _BackgroundFolder;
public string BackgroundFolder
{
get { return _BackgroundFolder; }
set { _BackgroundFolder = value; }
}
private bool _OpenPDF;
public bool OpenPDF
{
get { return _OpenPDF; }
set { _OpenPDF = value; }
}
private bool _OverWrite;
public bool OverWrite
{
get { return _OverWrite; }
set { _OverWrite = value; }
}
private ChangeBarDefinition _MyChangeBarDefinition;
public ChangeBarDefinition MyChangeBarDefinition
{
get { return _MyChangeBarDefinition; }
set { _MyChangeBarDefinition = value; }
}
public PromsPrinter(ItemInfo myItem, string rev, string revDate, string watermark, bool debugOutput, string backgroundFolder,bool openPDF, bool overWrite, ChangeBarDefinition cbd, String pdfFile)
{
_MyItem = myItem;
_Rev = rev;
_RevDate = revDate;
_Watermark = watermark;
_DebugOutput = debugOutput;
_BackgroundFolder = backgroundFolder;
_OpenPDF = openPDF;
_OverWrite = overWrite;
_MyChangeBarDefinition = cbd;
_PDFFile = pdfFile;
}
public string Print(string pdfFolder)
{
if (_MyItem is ProcedureInfo)
return Print(_MyItem as ProcedureInfo, pdfFolder);
return "";
}
private string BuildMSWordPDF(SectionInfo section)
{
DateTime tStart = DateTime.Now;
string MSWordFile = null;
if (section.MyContent.ContentEntryCount == 1)
{
MSWordFile = MSWordToPDF.GetDocPdf(section, PrintOverride.TextColor);
OnStatusChanged("MSWord converted to PDF " + MSWordFile, PromsPrinterStatusType.MSWordToPDF);
}
return MSWordFile;
}
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 _DebugLayer;
private PdfLayer _WatermarkLayer;
private void CreateLayers(PdfContentByte cb)
{
if (DebugOutput)
{
_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 Text", cb.PdfWriter);
_DebugLayer = new PdfLayer("Debug", 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);
if (OpenPDF)
System.Diagnostics.Process.Start(fileName);
OnStatusChanged("OpenPDF", PromsPrinterStatusType.OpenPDF);
}
private PdfContentByte OpenDoc(string outputFileName)
{
PdfWriter writer=null;
iTextSharp.text.Document document = new iTextSharp.text.Document(PageSize.LETTER);
try
{
writer = PdfWriter.GetInstance(document, new FileStream(outputFileName, FileMode.Create));
}
catch (Exception ex)
{
MessageBox.Show("Could not create " + outputFileName + ". If it is open, close and retry.", "Error on CreatePdf");
return null;
}
document.Open();
// Create Layers
CreateLayers(writer.DirectContent);
MSWordToPDF.DebugStatus = DebugOutput ? 1 : 0;
PrintOverride.Reset();
if (DebugOutput)
{
PrintOverride.TextColor = System.Drawing.Color.Red;
PrintOverride.SvgColor = System.Drawing.Color.LawnGreen;
PrintOverride.BoxColor = System.Drawing.Color.Red;
PrintOverride.ChangeBarColor = System.Drawing.Color.Red;
PrintOverride.DebugColor = System.Drawing.Color.CadetBlue;
}
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 VlnSvgPageHelper _MyHelper = null;
private static PdfReader _MyFoldoutReader = null;
private static SectionInfo _MyFoldoutSection = null;
private string Print(ProcedureInfo myProcedure, string pdfFolder)
{
_MyFoldoutReader = null;
foreach (SectionInfo mySection in myProcedure.Sections)
{
if (mySection.MyContent.Number.ToUpper() == "FOLDOUT")
{
_MyFoldoutSection = mySection;
string foldoutPdf = PrintProcedureOrFoldout(myProcedure, true, Volian.Base.Library.VlnSettings.TemporaryFolder + @"\Foldout.pdf");
_MyFoldoutReader = foldoutPdf != null ? new PdfReader(foldoutPdf) : null;
}
}
OnStatusChanged("Print " + myProcedure.DisplayNumber, PromsPrinterStatusType.Start);
string outputFileName = pdfFolder + "\\" + PDFFile;
if (!OverWrite && File.Exists(outputFileName))
{
if (MessageBox.Show(outputFileName + " exists. Overwrite file?", "File Exists", MessageBoxButtons.YesNo) == DialogResult.No)
return null;
}
return PrintProcedureOrFoldout(myProcedure, false, outputFileName);
}
private string PrintProcedureOrFoldout(ProcedureInfo myProcedure, bool doingFoldout, string outputFileName)
{
// Create an MSWord Pdf
// Setup a pdf Document for printing
OnStatusChanged("Before OpenDoc", PromsPrinterStatusType.Before);
PdfContentByte cb = OpenDoc(outputFileName);
if (cb == null) return null;
OnStatusChanged("Before NewPage", PromsPrinterStatusType.Before);
cb.PdfDocument.NewPage(); // Start of print
OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage);
OnStatusChanged(myProcedure.DisplayNumber, PromsPrinterStatusType.ProgressSetup, myProcedure.Sections.Count);
int progress = 0;
foreach (SectionInfo mySection in myProcedure.Sections)
{
if ((mySection.MyContent.Number.ToUpper() == "FOLDOUT") != doingFoldout) continue;
PrintOverride.CompressSuper = mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressHPSuper;
PrintOverride.CompressSub = mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressHPSub;
OnStatusChanged((mySection.DisplayNumber ?? "") == "" ? mySection.DisplayText : mySection.DisplayNumber, PromsPrinterStatusType.Progress, progress++);
// Set up Helper for the particular Section
if (_MyHelper == null)
{
cb.PdfWriter.PageEvent = _MyHelper = new VlnSvgPageHelper(mySection);
_MyHelper.MyPdfWriter = cb.PdfWriter;
_MyHelper.CreatingFoldoutPage = doingFoldout;
_MyHelper.MyPdfContentByte = cb;
if (!mySection.IsStepSection) _MyHelper.PageBookmarks.Add((ItemInfo)mySection, ((mySection.DisplayNumber ?? "") == "" ? "" : mySection.DisplayNumber + " - ") + mySection.DisplayText, null);
if (DebugOutput)
{
// 16-bit background
string procedureFileName = BackgroundFolder + "\\" + CreateFileName(myProcedure.DisplayNumber);
FileInfo VEPromsFile = new FileInfo(procedureFileName);
if (VEPromsFile.Exists && !doingFoldout)
{
_MyHelper.BackgroundFile = procedureFileName;
// X argument below: accounts for 16-bit pdf OverrideLeftMargin = -2 characters at the plant format's default Font's
// characters per inch.
// 16bit OverrideLeftMargin, defined as -2 in driver\drvin.rtf, - override took 2 characters out, so we're adding it back in:
_MyHelper.BackgroundOffset = new PointF(2 * 72F / (float)myProcedure.ActiveFormat.PlantFormat.FormatData.Font.CPI, -9.5F);
_MyHelper.BackgroundPageOffset = 0;
}
_MyHelper.WatermarkLayer = _WatermarkLayer;
_MyHelper.PageListLayer = _PagelistLayer;
_MyHelper.TextLayer = _TextLayer;
_MyHelper.BackgroundLayer = _BackgroundLayer;
_MyHelper.DebugLayer = _DebugLayer;
}
_MyHelper.Rev = _Rev;
_MyHelper.RevDate = _RevDate;
_MyHelper.Watermark = _Watermark;
_MyHelper.DoZoomOMatic = DebugOutput;
OnStatusChanged("After Set PageEvent", PromsPrinterStatusType.SetPageEvent);
}
else
{
if (!mySection.IsStepSection)_MyHelper.PageBookmarks.Add((ItemInfo)mySection, ((mySection.DisplayNumber ?? "") == "" ? "" : mySection.DisplayNumber + " - ") + mySection.DisplayText, null);
_MyHelper.MySection = mySection;
OnStatusChanged("After Set Svg", PromsPrinterStatusType.SetSVG);
}
PdfReader readerWord = null;
string myPdfFile = null;
if (mySection.IsStepSection)
{
if ((mySection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
DoFoldoutPage(cb, "Beginning of Step Section", _TextLayer, _MyHelper);
CreateStepPdf(mySection, cb);
}
else
{
myPdfFile = BuildMSWordPDF(mySection);
try
{
readerWord = myPdfFile != null ? new PdfReader(myPdfFile) : null;
OnStatusChanged("Get Section", PromsPrinterStatusType.GetSection);
int sectPageCount = 0;
float locEndOfWordDoc = 0;
float pdfSize = 0;
using (PdfInfo myPdf = PdfInfo.Get(mySection))
{
sectPageCount = (int)(Math.Ceiling(myPdf.PageCount));
locEndOfWordDoc = (float)(myPdf.PageCount - (sectPageCount-1)) * 100;
pdfSize = (float)myPdf.PageCount;
}
for (int ii = 0; ii < sectPageCount; ii++)
{
if (((mySection.MyDocStyle.StructureStyle.Style ?? 0) & E_DocStructStyle.UseSectionFoldout) != 0)
DoFoldoutPage(cb, "Word Document", _TextLayer, _MyHelper);
int pageNumber = 1 + ii;
if (readerWord != null)
{
bool doimport2 = true;
PdfImportedPage fgPage = null;
try
{
fgPage = cb.PdfWriter.GetImportedPage(readerWord, ii + 1);
}
catch (Exception ex)
{
Console.WriteLine(ex);
doimport2 = false;
}
OnStatusChanged("Read MSWord", PromsPrinterStatusType.ReadMSWord);
if (doimport2) AddImportedPageToLayer(cb.PdfWriter.DirectContent, _MSWordLayer, fgPage, 0, 0);
if (ii == sectPageCount - 1)
{
// if there's and end message, add it to the appropriate location on the last page of
// the word document:
float ylocation = cb.PdfDocument.PageSize.Height - ((float)mySection.MyDocStyle.Layout.TopMargin + locEndOfWordDoc * 72); // 72 - pts per inch.
iTextSharp.text.Font fnt = VolianPdf.GetFont(mySection.MyDocStyle.End.Font.WindowsFont);
fnt.Color=new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Black));
iTextSharp.text.Paragraph para = new Paragraph(mySection.MyDocStyle.End.Message, fnt);
float wtpm = (float)mySection.MyDocStyle.Layout.PageWidth - (float)mySection.MyDocStyle.Layout.LeftMargin;
float centerpos = (float)mySection.MyDocStyle.Layout.LeftMargin + (wtpm - (mySection.MyDocStyle.End.Message.Length * mySection.MyDocStyle.End.Font.CharsToTwips)) / 2;
float yBottomMargin = Math.Max(0, (float)mySection.MyDocStyle.Layout.TopMargin - (float)mySection.MyDocStyle.Layout.PageLength - 2 * vlnPrintObject.SixLinesPerInch);
Rtf2Pdf.TextAt(cb, para, centerpos, ylocation + 6, 100, 12, "", yBottomMargin);
}
OnStatusChanged("Merge MSWord", PromsPrinterStatusType.MergeMSWord);
}
OnStatusChanged("Before NewPage", PromsPrinterStatusType.Before);
cb.PdfDocument.NewPage(); // Word Document
OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage);
}
}
catch (Exception ex)
{
cb.PdfDocument.NewPage(); // can we put out 'error on page'?
}
}
}
if (_MyHelper.BackgroundFile != null)
{
_MyHelper.MySvg = null;
while (cb.PdfWriter.CurrentPageNumber <= _MyHelper.BackgroundPageCount)
{
PrintTextMessage(cb, "No Proms Output", _TextLayer);
cb.PdfDocument.NewPage(); // only have 16bit pages left (for DebugMode)
}
}
OnStatusChanged(myProcedure.DisplayNumber + " PDF Creation Completed", PromsPrinterStatusType.Progress, progress);
CloseDocument(cb, outputFileName);
_MyHelper = null;
return outputFileName;
}
private static void PrintTextMessage(PdfContentByte cb, string message, PdfLayer textLayer)
{
if (textLayer != null) cb.BeginLayer(textLayer);
float fontSize = 30;
ColumnText ct = new ColumnText(cb);
iTextSharp.text.Font font = FontFactory.GetFont("Arial", fontSize, new iTextSharp.text.Color(PrintOverride.TextColor));
Chunk chk = new Chunk(message, font);
float xCenter = cb.PdfDocument.PageSize.Width / 2;
float yCenter = cb.PdfDocument.PageSize.Height / 2;
float width = chk.GetWidthPoint() * 1.01F;
float height = fontSize * 1.5F;
ct.SetSimpleColumn(xCenter - width / 2, yCenter - height / 2, xCenter + width / 2, yCenter + height / 2);
Phrase ph = new Phrase(chk);
ct.AddElement(ph);
cb.SetColorFill(new iTextSharp.text.Color(PrintOverride.TextColor));
ct.Go();
if (textLayer != null) cb.EndLayer();
}
private float _NoBreakYOffset = 0;
private void CreateStepPdf(SectionInfo section, PdfContentByte cb)
{
iTextSharp.text.pdf.PdfWriter writer = cb.PdfWriter;
ItemInfo myItemInfo = section as ItemInfo;
// 792: 72 * 11 inches - TopRow - Top is high value
float _PointsPerPage = 792;
float yTopMargin = _PointsPerPage - (float)myItemInfo.MyDocStyle.Layout.TopMargin;
// the following line was modified to comment out the - 2 * SixLinesPerInch. this fixed a pagination problem with WCN EMG E-3.
float yBottomMargin = Math.Max(0, yTopMargin - (float)myItemInfo.MyDocStyle.Layout.PageLength); // - 2 * vlnPrintObject.SixLinesPerInch);
vlnParagraph.Prefix = myItemInfo.Path;
Rtf2Pdf.PdfDebug = true;
Rtf2Pdf.Offset = new PointF(0, 2.5F);
_MyHelper.ChangeBarDefinition = MyChangeBarDefinition;
vlnParagraph myParagraph = new vlnParagraph(null, cb, myItemInfo, (float)myItemInfo.MyDocStyle.Layout.LeftMargin, _NoBreakYOffset, 0, myItemInfo.ColumnMode, myItemInfo.ActiveFormat);
if (myItemInfo.HasChildren)
myParagraph.ToPdf(cb, yTopMargin, yTopMargin, yBottomMargin);
else
PrintTextMessage(cb, "No Section Content", _TextLayer);
SectionConfig.SectionPagination sp = SectionConfig.SectionPagination.Separate; // always the default
if ( section.NextItemCount > 0)
{
SectionInfo tmpii = SectionInfo.Get(section.NextItem.ItemID);
// if this section & the next section are not accessory pages, see if there is continuous pagination,
// i.e. no page break between them.
if (section.IsStepSection && tmpii.IsStepSection)
{
SectionConfig sc = tmpii.SectionConfig;
try
{
if (sc != null) sp = sc.Section_Pagination;
}
catch (Exception ex)
{
sp = SectionConfig.SectionPagination.Separate;
}
}
}
if (sp == SectionConfig.SectionPagination.Separate)
{
cb.PdfDocument.NewPage(); // end of step section
_NoBreakYOffset = 0;
}
else
{
_NoBreakYOffset = myParagraph.YBottomMost;
}
OnStatusChanged("StepSection converted to PDF " + section.ShortPath, PromsPrinterStatusType.BuildStep);
}
public static void DoFoldoutPage(PdfContentByte cb, string str, PdfLayer textLayer)
{
cb.Circle(400, 100, 50);
PrintTextMessage(cb, "Foldout for: " + str, textLayer);
cb.PdfDocument.NewPage(); // Temporary for foldout/16bit-32bit page alignment
}
public static void DoFoldoutPage(PdfContentByte cb, string str, PdfLayer textLayer, VlnSvgPageHelper myPageHelper)
{
if (_MyFoldoutSection == null) return;
SectionInfo saveSect = myPageHelper.MySection;
myPageHelper.MySection = _MyFoldoutSection;
myPageHelper.OnFoldoutPage = true;
if (_MyFoldoutReader != null)
{
bool doimport2 = true;
PdfImportedPage fgPage = null;
try
{
fgPage = cb.PdfWriter.GetImportedPage(_MyFoldoutReader,1);
}
catch (Exception ex)
{
Console.WriteLine(ex);
doimport2 = false;
}
if (doimport2) AddImportedPageToLayer(cb.PdfWriter.DirectContent, textLayer, fgPage, 0, 0);
}
//PrintTextMessage(cb, "Foldout for: " + str, textLayer);
cb.PdfDocument.NewPage(); // Temporary for foldout/16bit-32bit page alignment
myPageHelper.MySection = saveSect;
myPageHelper.OnFoldoutPage = false;
}
}
}