2013-10-04 20:30:14 +00:00

967 lines
41 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;
using Volian.Base.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
{
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
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 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; }
}
private bool _OriginalPageBreak; // use 16bit page breaks.
public bool OriginalPageBreak
{
get { return _OriginalPageBreak; }
set { _OriginalPageBreak = value; }
}
private bool _InsertBlankPages;
public bool InsertBlankPages
{
get { return _InsertBlankPages; }
set { _InsertBlankPages = value; }
}
public PromsPrinter(ItemInfo myItem, string rev, string watermark, bool debugOutput, bool origPgBrk, string backgroundFolder, bool openPDF, bool overWrite, ChangeBarDefinition cbd, String pdfFile, bool insertBlankPages)
{
_MyItem = myItem;
_Rev = rev;
_Watermark = watermark;
_DebugOutput = debugOutput;
_BackgroundFolder = backgroundFolder;
_OpenPDF = openPDF;
_OverWrite = overWrite;
_MyChangeBarDefinition = cbd;
_PDFFile = pdfFile;
_OriginalPageBreak = origPgBrk;
_InsertBlankPages = insertBlankPages;
}
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);
// the following checks if the content of page is landscape and rotates because we're printing on
// a portrait page. If, at some point, we print a total landscape page, not a mix, this will need
// re-evaluated.
if (page.Height < page.Width)
image.RotationDegrees = 90F;
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)
{
try
{
cb.PdfDocument.Close();
}
catch (Exception ex)
{
Console.WriteLine("{0} - {1}", ex.GetType().Name, ex.Message);
}
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));
writer.PDFXConformance = PdfWriter.PDFA1B;
}
catch (Exception ex)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Could not create");
sb.AppendLine();
sb.AppendLine(outputFileName + ".");
sb.AppendLine();
sb.AppendLine("If it is open, close and retry.");
MessageBox.Show(sb.ToString(), "Error on CreatePdf", MessageBoxButtons.OK, MessageBoxIcon.Warning);
//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 static List<PdfReader> _MyFoldoutReader = null;
public static List<PdfReader> MyFoldoutReader
{
get { return PromsPrinter._MyFoldoutReader; }
set { PromsPrinter._MyFoldoutReader = value; }
}
private static List<SectionInfo> _MyFoldoutSection = null;
private string Print(ProcedureInfo myProcedure, string pdfFolder)
{
if (_MyFoldoutReader != null) _MyFoldoutReader.Clear();
else _MyFoldoutReader = new List<PdfReader>();
if (_MyFoldoutSection != null) _MyFoldoutSection.Clear();
else _MyFoldoutSection = new List<SectionInfo>();
if (myProcedure.Sections != null)
{
int cnt = 0;
foreach (SectionInfo mySection in myProcedure.Sections)
{
if ((myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts && mySection.MyContent.Number.ToUpper() == "FOLDOUT")
|| (myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.AlternateFloatingFoldout && mySection.MyContent.Text.ToUpper().Contains("FOLDOUT")))
{
// if floating foldouts, need a list of sections & foldoutreaders. Just do first for now.
_MyFoldoutSection.Add(mySection);
string foldoutPdf = PrintProcedureOrFoldout(myProcedure, mySection, Volian.Base.Library.VlnSettings.TemporaryFolder + @"\Foldout" + cnt.ToString() + @".pdf");
_MyFoldoutReader.Add(foldoutPdf != null ? new PdfReader(foldoutPdf) : null);
cnt++;
}
}
}
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, null, outputFileName);
}
// See if the last non Foldout Section has a Final Message.
private int GetFinalMessageSectionID(ProcedureInfo myProcedure, bool doingFoldout)
{
if (!doingFoldout)
{
// Work backwards because we don't want to include any foldouts. Find the last section that is not
// a foldout. If it has a final message, this is the 'last section' and should have a final message.
// If it doesn't have a final message, then none should be printed.
int cntSect = myProcedure.Sections.Count;
for (int i = cntSect - 1; i >= 0; i--)
{
SectionInfo mySection = myProcedure.Sections[i] as SectionInfo;
if (!mySection.DisplayText.ToUpper().Contains("FOLDOUT"))
{
if (mySection.MyDocStyle.Final != null && mySection.MyDocStyle.Final.Message != null && mySection.MyDocStyle.Final.Message.Length > 0)
return mySection.ItemID;
else
return -1;
}
}
}
return -1;
}
private bool _AllowAllWatermarks = false;
public bool AllowAllWatermarks
{
get { return _AllowAllWatermarks; }
set { _AllowAllWatermarks = value; }
}
private string PrintProcedureOrFoldout(ProcedureInfo myProcedure, SectionInfo myFoldoutSection, string outputFileName)
{
bool doingFoldout = myFoldoutSection != null;
// The following line accounts for 16bit OverrideLeftMargin when the 'Absolute' attribute is used in the genmac.
// We don't want to use the OverrideLeftMargin when 'Absolute' is used in the genmac.
// It's set here because the Volian.Svg.Library cannot call back to Volian.Print.Library to get this value.
Svg.Library.Svg.AbsoluteOffset = new PointF(2 * 72F / (float)myProcedure.ActiveFormat.PlantFormat.FormatData.Font.CPI, -9.5F);
// 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
//_MyLog.InfoFormat("NewPage 1 {0}", cb.PdfWriter.CurrentPageNumber);
OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage);
if (myProcedure.Sections == null)
{
MessageBox.Show("This procedure has no content and will not be printed.", "Empty Procedure", MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;
}
OnStatusChanged(myProcedure.DisplayNumber, PromsPrinterStatusType.ProgressSetup, myProcedure.Sections.Count);
int progress = 0;
int finalMessageSectionID = GetFinalMessageSectionID(myProcedure, doingFoldout);
string LastFmtName = null;
int lastDocStyle = -1;
foreach (SectionInfo mySection in myProcedure.Sections)
{
if (((mySection.MyContent.Number.ToUpper() == "FOLDOUT" && myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts)
|| (myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.AlternateFloatingFoldout && mySection.MyContent.Text.ToUpper().Contains("FOLDOUT")))
!= doingFoldout) continue;
if (myFoldoutSection != null && myFoldoutSection.ItemID != mySection.ItemID) 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)
{
LastFmtName = mySection.ActiveFormat.Name;
lastDocStyle = (int)mySection.MyDocStyle.Index;
string hlsText = "";
int hlsItemId = 0;
if (mySection.IsStepSection && mySection.Steps != null && mySection.Steps.Count > 0)
{
hlsItemId = mySection.Steps[0].ItemID;
hlsText = mySection.Steps[0].DisplayText; // save the High level step text for use in the page list
}
cb.PdfWriter.PageEvent = _MyHelper = new VlnSvgPageHelper(mySection, this, hlsText, hlsItemId);
_MyHelper.AllowAllWatermarks = AllowAllWatermarks;
_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 + "\\" + PDFFile;//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:
if (mySection.ActiveFormat.Name.ToUpper().StartsWith("WST") || _MyHelper.Back32BitPROMS) // compare folder contains PROMS generated PDF
_MyHelper.BackgroundOffset = new PointF(0, 0);
else
_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.Watermark = _Watermark;
_MyHelper.DoZoomOMatic = DebugOutput;
_MyHelper.OriginalPageBreak = OriginalPageBreak;
OnStatusChanged("After Set PageEvent", PromsPrinterStatusType.SetPageEvent);
}
else
{
//added by jcb to reset mygaps when changing a section. found old section gaps were carrying over to new section
_MyHelper.MyGaps.Clear();
//Console.WriteLine("'{0}' PromsPrinter", mySection.DisplayText);
// if pagination is separate or we've changed the format, we have not done the first page
// (if this format has the useonfirst page docstyle flag)
if (LastFmtName != mySection.ActiveFormat.Name || lastDocStyle != (int)mySection.MyDocStyle.Index || mySection.SectionConfig.Section_Pagination == SectionConfig.SectionPagination.Separate)
{
_MyHelper.DidFirstPageDocStyle = false;
lastDocStyle = (int)mySection.MyDocStyle.Index;
LastFmtName = mySection.ActiveFormat.Name;
}
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;
_MyHelper.FinalMessageSectionID = finalMessageSectionID; // set VlnSvgPageHelper with the finalMessageSectionID
if (mySection.IsAutoTOCSection)
GenerateTOC(mySection, myProcedure, cb, _TextLayer);
else
{
if (mySection.IsStepSection)
{
if (mySection.Steps != null && mySection.Steps.Count > 0)
{
// get first step to send to floating foldout indx.&& MyItemInfo.FoldoutIndex>-1)
ItemInfo firstStep = mySection.Steps[0];
if (firstStep.FoldoutIndex() > -1)
DoFoldoutPage(cb, "Beginning of Step Section", _TextLayer, _MyHelper, firstStep.FoldoutIndex(), InsertBlankPages);
else if (!_MyHelper.CreatingFoldoutPage && _MyFoldoutReader.Count > 0 && InsertBlankPages)
{
// only insert a blank page if this section does not have a foldout (but the procedure as a whole does)
// and the checkbox on the print dialog to add blank pages is checked
_MyHelper.OnBlankPage = true;
cb.PdfDocument.Add(new iTextSharp.text.Table(1));
cb.PdfDocument.NewPage();
//_MyLog.InfoFormat("NewPage Begin Step Sect blank {0}", cb.PdfWriter.CurrentPageNumber);
}
}
CreateStepPdf(mySection, cb);
}
else
CreateWordDocPdf(cb, mySection, ref readerWord, ref myPdfFile);
}
}
if (_MyHelper != null && _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)
//_MyLog.InfoFormat("NewPage 2 {0}", cb.PdfWriter.CurrentPageNumber);
DebugPagination.WriteLine("{0:D6},'{1}'",
_MyHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, "No PROMS Output");
}
}
OnStatusChanged(myProcedure.DisplayNumber + " PDF Creation Completed", PromsPrinterStatusType.Progress, progress);
DebugPagination.TotalPages += cb.PdfWriter.CurrentPageNumber;
CloseDocument(cb, outputFileName);
_MyHelper = null;
return outputFileName;
}
public void CreateWordDocPdf(PdfContentByte cb, SectionInfo mySection, ref PdfReader readerWord, ref string myPdfFile)
{
_MyHelper.MySection = mySection;
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;
}
string tocKey = string.Format("TOC{0}", mySection.ItemID);
if (_MyHelper.MyTOCPageCounts.ContainsKey(tocKey))
{
PageCount pc = _MyHelper.MyTOCPageCounts[tocKey];
// add 1 because have not hit end page yet.
pc.Total = _MyHelper.CurrentTOCPageNumber + 1;
pc.DrawTemplates();
}
else
{
// see if this section will be added to the table of content. This is for sections that
// precede tha actual Automated TOC section.
SectionConfig sc = mySection.MyConfig as SectionConfig;
if (sc != null && sc.Section_TOC == "Y")
{
string tockey = "TOC" + mySection.ItemID.ToString();
if (!_MyHelper.MyTOCPageNums.ContainsKey(tockey))
// increment the CurrentTOCPageNumber by 1 since we haven't hit an
// endpage yet, and that's what increments it to the current page number.
_MyHelper.MyTOCPageNums.Add(tockey, _MyHelper.CurrentTOCPageNumber + 1);
}
}
float origYoff = (float)mySection.MyDocStyle.Layout.TopMargin;
for (int ii = 0; ii < sectPageCount; ii++)
{
int pageNumber = 1 + ii;
if (((mySection.MyDocStyle.StructureStyle.Style ?? 0) & E_DocStructStyle.UseSectionFoldout) != 0)
DoFoldoutPage(cb, "Word Document", _TextLayer, _MyHelper, 0, false);
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)
{
if (cb.PdfWriter.CurrentPageNumber > 1 && _MyFoldoutReader.Count > 0 && InsertBlankPages)
{
// only insert a blank page if this section does not have a foldout (but the procedure as a whole does)
// and the checkbox on the print dialog to add blank pages is checked
_MyHelper.OnBlankPage = true;
cb.PdfDocument.Add(new iTextSharp.text.Table(1));
cb.PdfDocument.NewPage();
//_MyLog.InfoFormat("NewPage 3 blank {0}", cb.PdfWriter.CurrentPageNumber);
}
float yoff = 0;
if (_MyHelper.DidFirstPageDocStyle) yoff = origYoff - (float)mySection.MyDocStyle.Layout.TopMargin;
AddImportedPageToLayer(cb.PdfWriter.DirectContent, _MSWordLayer, fgPage, (float)(mySection.MyDocStyle.Layout.MSWordXAdj??0), (float)(mySection.MyDocStyle.Layout.MSWordYAdj??0)+yoff);
DebugPagination.WriteLine("{0:D6},'{1}',{2}",
_MyHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, mySection.ShortPath,pageNumber);
}
if (ii == sectPageCount - 1)
{
// if there's and end message, add it to the appropriate location on the last page of
// the word document:
if ((mySection.MyDocStyle.End.Message ?? "") != "")
{
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.FixedMessage, 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);
if (mySection.MyDocStyle.LandscapePageList)// && mySection.MyDocStyle.Layout.PageWidth > mySection.MyDocStyle.Layout.PageLength)
_MyHelper.IsLandscape = true;
else
_MyHelper.IsLandscape = false;
cb.PdfDocument.NewPage(); // Word Document
//_MyLog.InfoFormat("NewPage 3 {0}", cb.PdfWriter.CurrentPageNumber);
// if this document style has another style that is for pages other than first, we need to
// reset the document style off of this section AND reset docstyle values used.
_MyHelper.DidFirstPageDocStyle = true;
DebugPagination.WriteLine("CreateWordDocPdf");
if ((mySection.MyDocStyle.StructureStyle.Where & E_DocStyleUse.UseOnFirstPage) > 0)
_MyHelper.MySection = mySection; // this resets the docstyle/pagestyle if pagehelper
OnStatusChanged("After NewPage", PromsPrinterStatusType.NewPage);
}
}
catch (Exception ex)
{
cb.PdfDocument.NewPage(); // can we put out 'error on page'?
_MyLog.InfoFormat("NewPage error on page {0}", cb.PdfWriter.CurrentPageNumber);
}
}
private void GenerateTOC(SectionInfo tocSection, ProcedureInfo myProcedure, PdfContentByte cb, PdfLayer textLayer)
{
iTextSharp.text.pdf.PdfWriter writer = cb.PdfWriter;
float _PointsPerPage = 792;
float yTopMargin = _PointsPerPage - (float)tocSection.MyDocStyle.Layout.TopMargin;
float yBottomMargin = Math.Max(0, yTopMargin - (float)tocSection.MyDocStyle.Layout.PageLength); // - 2 * vlnPrintObject.SixLinesPerInch);
if (textLayer != null) cb.BeginLayer(textLayer);
TableOfContentsData tOfC = tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData;
ItemInfo procItem = ItemInfo.Get(myProcedure.ItemID);
lastyLocation = 0;
AddSectionToTOC(tocSection, procItem, tOfC, cb, yTopMargin, 0);
if (textLayer != null) cb.EndLayer();
cb.PdfDocument.NewPage();
//_MyLog.InfoFormat("NewPage 4 {0}", cb.PdfWriter.CurrentPageNumber);
_NoBreakYOffset = 0;
}
float lastyLocation = 0;
private string GetRtfToC(string txt, TableOfContentsData tOfCData)
{
StringBuilder _RtfSB = new StringBuilder();
Volian.Controls.Library.DisplayText toctxt = new Volian.Controls.Library.DisplayText(txt, tOfCData.Font, false);
System.Drawing.Font myFont = toctxt.TextFont.WindowsFont;
_RtfSB.Append(vlnPrintObject.AddFontTable(myFont));
_RtfSB.Append(toctxt.StartText);
_RtfSB.Append("}");
return _RtfSB.ToString();
}
private float AddSectionToTOC(SectionInfo tocSection, ItemInfo ii, TableOfContentsData tOfC, PdfContentByte cb, float yPageStart, float yLocation)
{
// The following adjustments are for WCN1:
// for xAdjNumber: 6 is for 1 char less in 16bit (\promsnt\exe\print\tabocont.c, method 'howMany'.
// 1.2 is a tweak to get output to match between 16 & 32 bit.
// for xAdjTitle: .8 & 1.2 are both tweaks to get output to match.
// for xAdjTitleIndent: 6 is for 1 char less. 2.4 is a tweak
float xAdjNumber = -6 + 1.2F;
float xAdjTitle = .8F + 1.2F;
float xAdjTitleIndent = -6 + 2.4F;
float yadj = 0.5F; // tweak to get 16 & 32 bit output to match.
float yPageStartAdj = yPageStart - yadj;
float leftMargin = (float)tocSection.MyDocStyle.Layout.LeftMargin;
float secNumPos = (float)tOfC.TofCSecNumPos + xAdjNumber;
float secTitlePos = (float)tOfC.TofCSecTitlePos + xAdjTitle;
float secPagePos = (float)tOfC.TofCPageNumPos + xAdjNumber;
float height = tOfC.Font.WindowsFont.Size * 1.5F;
if (ii.Sections != null)
{
foreach (SectionInfo mySection in ii.Sections)
{
SectionConfig sc = mySection.MyConfig as SectionConfig;
if ((mySection.MyDocStyle != null && mySection.MyDocStyle.IncludeInTOC && (sc == null || sc.Section_TOC != "Y"))
|| ((mySection.MyDocStyle == null || !mySection.MyDocStyle.IncludeInTOC) && (sc != null && sc.Section_TOC == "Y")))
{
// need to do the section number, section title & page number. Page number
// has to be put on at end after number of page is known, so use a Template.
string tmptxt = mySection.MyContent.Number == null || mySection.MyContent.Number == "" ? " " : mySection.MyContent.Number;
string rtfText = GetRtfToC(tmptxt, tOfC);
Paragraph myparagraphn = vlnPrintObject.RtfToParagraph(rtfText);
float width = 0;
foreach (Chunk chkt in myparagraphn.Chunks)
width += chkt.GetWidthPoint();
float numwidth = width;
float yBottomMargin = yPageStart - (float)tocSection.MyDocStyle.Layout.PageLength + (2 * vlnPrintObject.SixLinesPerInch);
Rtf2Pdf.Offset = new PointF(0, 2.5F);
// for indenting of subsections, count up tree. Only start indenting
// at third level, i.e. not indent on 1.0 and 1.1, but indent on 1.1.1:
int level = 0;
ItemInfo iilvl = mySection as ItemInfo;
while (!iilvl.IsProcedure)
{
level++;
iilvl = iilvl.MyParent;
}
// check what level the plant wants the auto ToC indented:
int tofCNumLevels = tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCNumLevels ?? 0;
if (tofCNumLevels > 0 && level > tofCNumLevels) return yLocation;
level = level <= 2 ? 0 : level - 2; // no indenting until third level
float indentOffset = (level * (secTitlePos - secNumPos));
float retval = Rtf2Pdf.TextAt(cb, myparagraphn, leftMargin + secNumPos + indentOffset, yPageStart - yLocation, width * 1.3F, height, "", yBottomMargin);
if (retval == 0) // do a newpage, it couldn't fit on current page.
{
cb.PdfDocument.NewPage();
//_MyLog.InfoFormat("NewPage 5 {0}", cb.PdfWriter.CurrentPageNumber);
yLocation = 0;
retval = Rtf2Pdf.TextAt(cb, myparagraphn, leftMargin + secNumPos + indentOffset, yPageStart - yLocation, width * 1.3F, height, "", yBottomMargin);
}
// if the starting column of text would be in 'middle of' the number, just put it
// a few spaces after the number. The '18' below represents 3 chars.
float adjSecTitlePos = secTitlePos + indentOffset + (level * 6);
if (secNumPos + numwidth + indentOffset > secTitlePos + indentOffset)
adjSecTitlePos = secNumPos + numwidth + 18 - xAdjTitleIndent + indentOffset;
rtfText = GetRtfToC(mySection.MyContent.Text, tOfC);
Paragraph myparagrapht = vlnPrintObject.RtfToParagraph(rtfText);
width = secPagePos - adjSecTitlePos - 6;
retval = Rtf2Pdf.TextAt(cb, myparagrapht, leftMargin + adjSecTitlePos, yPageStart - yLocation, width, height, "", yBottomMargin);
// add a template for the page number:
if (lastyLocation != 0 && ((lastyLocation - retval) > vlnPrintObject.SixLinesPerInch))
yLocation += (lastyLocation - retval - vlnPrintObject.SixLinesPerInch);
lastyLocation = retval;
// if the space character is not null & is not a space, the we've got to put out
// these between the section title & the page number
if (tOfC.TofCSpaceChar != null && tOfC.TofCSpaceChar != "" && tOfC.TofCSpaceChar != " ")
{
width = 0;
foreach (Chunk chkt in myparagrapht.Chunks)
width += chkt.GetWidthPoint();
float startSpace = leftMargin + adjSecTitlePos + width;
float endSpace = leftMargin + secPagePos;
float numSpace = endSpace - startSpace;
string spaceStr = "";
rtfText = GetRtfToC(tOfC.TofCSpaceChar, tOfC);
Paragraph tmpmyparagraph = vlnPrintObject.RtfToParagraph(rtfText);
float spacchrwid = 0;
foreach (Chunk chkt in tmpmyparagraph.Chunks)
spacchrwid += chkt.GetWidthPoint();
while (numSpace > 0)
{
spaceStr = spaceStr + tOfC.TofCSpaceChar;
numSpace -= spacchrwid;
}
rtfText = GetRtfToC(spaceStr, tOfC);
Paragraph myparagraphs = vlnPrintObject.RtfToParagraph(rtfText);
retval = Rtf2Pdf.TextAt(cb, myparagraphs, startSpace, yPageStart - yLocation, endSpace - startSpace, height, "", yBottomMargin);
}
// if in the pre-table of content list, just put the page number out as text.
// otherwise, add a template _MyHelper.MyTOCPageCounts
string key = "TOC" + mySection.ItemID.ToString();
if (mySection.IsAutoTOCSection || _MyHelper.MyTOCPageNums.ContainsKey(key))
{
string pnum = _MyHelper.MyTOCPageNums.ContainsKey(key) ? _MyHelper.MyTOCPageNums[key].ToString() : (_MyHelper.CurrentTOCPageNumber + 1).ToString();
rtfText = GetRtfToC(pnum, tOfC);
Paragraph myparagraphp = vlnPrintObject.RtfToParagraph(rtfText);
width = pnum.Length * 6;
retval = Rtf2Pdf.TextAt(cb, myparagraphp, leftMargin + secPagePos, yPageStart - yLocation, width, height, "", yBottomMargin);
}
else
AddTemplateTOCPageCounts(tOfC, yLocation, yPageStartAdj, leftMargin, secPagePos, height, mySection);
yLocation += vlnPrintObject.SixLinesPerInch;
}
yLocation = AddSectionToTOC(tocSection, mySection, tOfC, cb, yPageStart, yLocation);
}
}
return yLocation;
}
private void AddTemplateTOCPageCounts(TableOfContentsData tOfC, float yLocation, float yPageStartAdj, float leftMargin, float secPagePos, float height, SectionInfo mySection)
{
string key = "TOC" + mySection.ItemID.ToString();
PdfTemplate tmp = _MyHelper.MyTOCPageCounts.AddToTemplateList(key, _MyHelper.MyPdfWriter, "{TOCPAGE}", tOfC.Font.WindowsFont, Element.ALIGN_LEFT, PrintOverride.TextColor);
_MyHelper.MyPdfContentByte.AddTemplate(tmp, leftMargin + secPagePos, (yPageStartAdj - yLocation) - height / 2);
}
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", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, fontSize,iTextSharp.text.Font.NORMAL, 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 float _NoBreakYPageStart = 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, null, null);
float localYPageStart = 0;
float yPageStart = yTopMargin;
if (myItemInfo.HasChildren || myItemInfo.MyDocVersion.DocVersionConfig.SelectedSlave > 0)
localYPageStart = myParagraph.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin);
else if(!myItemInfo.MyDocStyle.OptionalSectionContent)
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
//_MyLog.InfoFormat("NewPage 6 {0}", cb.PdfWriter.CurrentPageNumber);
_NoBreakYOffset = 0;
yPageStart = yTopMargin;
}
else
{
if (_MyHelper.BottomMessage != null)
{
_MyHelper.DrawBottomMessage(cb);
localYPageStart += 12;
myParagraph.YBottomMost += 24; // two lines.
}
float tmplocal = localYPageStart;
_NoBreakYOffset = myParagraph.YBottomMost;
float yOffset = localYPageStart - yTopMargin;
_NoBreakYOffset -= yOffset;
yPageStart = localYPageStart;
Volian.Base.Library.DebugText.WriteLine("NOBREAK:{0},'{1}','{2}','{3}','{4}','{5}'", section.ItemID, tmplocal, yTopMargin, localYPageStart, _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
//_MyLog.InfoFormat("NewPage 7 {0}", cb.PdfWriter.CurrentPageNumber);
}
public static void DoFoldoutPage(PdfContentByte cb, string str, PdfLayer textLayer, VlnSvgPageHelper myPageHelper, int foldoutindx, bool insertBlankPages)
{
if (_MyFoldoutSection == null || _MyFoldoutSection.Count==0) return;
// if the very first page to be output is a 'foldout', treat this as a special case, since
// if duplex printing is on, the foldout should always be on the left side, i.e. or behind
// the document text. The option PROMS provides is to either:
// 1) Skip doing the foldout before the first page, if the 'InsertBlankPages' isn't set, by not checking
// the checkbox on the print dialog.
// 2) Insert a blank page as the first page, if the 'InsertBlankPages' is set.
if (!myPageHelper.PrintedAPage && !insertBlankPages) return;
if (!myPageHelper.PrintedAPage)
{
// only insert a blank page if this is the very first page printed & section has a foldout
// and the checkbox on the print dialog to add blank pages is checked. This will put out a blank page as
// as the first page so that duplex printing is correct for this condition.
myPageHelper.OnBlankPage = true;
cb.PdfDocument.Add(new iTextSharp.text.Table(1));
cb.PdfDocument.NewPage();
}
SectionInfo saveSect = myPageHelper.MySection;
myPageHelper.MySection = _MyFoldoutSection[foldoutindx];
myPageHelper.OnFoldoutPage = true;
if (_MyFoldoutReader != null)
{
bool doimport2 = true;
PdfImportedPage fgPage = null;
try
{ // read saved foldout page
fgPage = cb.PdfWriter.GetImportedPage(_MyFoldoutReader[foldoutindx],1);
}
catch (Exception ex)
{
Console.WriteLine(ex);
doimport2 = false;
}
if (doimport2)
{// put the saved foldout page into the PDF
AddImportedPageToLayer(cb.PdfWriter.DirectContent, textLayer, fgPage, 0, 0);
DebugPagination.WriteLine("{0:D6},'{1}',{2}",
myPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, "Foldout", 1);
}
}
//_MyLog.InfoFormat("DoFoldoutPage {0}", cb.PdfWriter.CurrentPageNumber);
//PrintTextMessage(cb, "Foldout for: " + str, textLayer);
cb.PdfDocument.NewPage(); // Temporary for foldout/16bit-32bit page alignment
//_MyLog.InfoFormat("NewPage 8 {0}", cb.PdfWriter.CurrentPageNumber);
myPageHelper.MySection = saveSect;
myPageHelper.OnFoldoutPage = false;
}
public static byte[] WatermarkPDF(byte[] buffer, string watermark)
{
PdfReader reader = new PdfReader(buffer);
MemoryStream ms = new MemoryStream();
PdfStamper stamper = new PdfStamper(reader, ms);
PdfLayer layer = new PdfLayer("Watermark", stamper.Writer);
layer.SetPrint("Print", true);
for (int i = 1; i <= reader.NumberOfPages; i++)
{
PdfContentByte cb = stamper.GetUnderContent(i);
cb.SaveState();
cb.BeginLayer(layer);
SvgWatermark wm = new SvgWatermark(cb, watermark, System.Drawing.Color.Blue, .15F);
wm.SetSquareDotPattern(.7F);
//wm.SetTextPattern(8, 3);
//wm.SetTextPattern2(8);
//wm.SetHashPattern(1, 6);
//wm.SetDotPattern(5, 2);
wm.Draw();
cb.EndLayer();
cb.RestoreState();
}
stamper.Close();
/*
cb.SaveState();
if (_WatermarkLayer != null) cb.BeginLayer(_WatermarkLayer);
SvgWatermark myWatermark = new SvgWatermark(cb, Watermark, System.Drawing.Color.Blue, .15F);
myWatermark.SetSquareDotPattern(.7F);
myWatermark.Draw();
if (_WatermarkLayer != null) cb.EndLayer();
cb.RestoreState();
*/
return ms.ToArray();
}
}
}