Rich 5a5502d8fc Added somecode so that profile errors will be recordedd to the Error Log
Added a reference to Log4Net
Fixed Profile Logic when PDF cannot be created because it is already open.
2015-02-16 20:51:34 +00:00

1419 lines
64 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,
LoadVlnParagraph
}
public class PromsPrinter
{
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public event PromsPrinterStatusEvent StatusChanged;
internal void OnStatusChanged(object sender, PromsPrintStatusArgs args)
{
if (StatusChanged != null)
StatusChanged(sender, args);
}
internal void OnStatusChanged(string myStatus, PromsPrinterStatusType type)
{
OnStatusChanged(this, new PromsPrintStatusArgs(myStatus, type));
}
public void OnStatusChanged(string msg)
{
OnStatusChanged(this, new PromsPrintStatusArgs(msg, PromsPrinterStatusType.General));
}
internal 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; }
}
private static List<string> _TransPageNumProblems = null;
public static List<string> TransPageNumProblems
{
get { return PromsPrinter._TransPageNumProblems; }
set { PromsPrinter._TransPageNumProblems = value; }
}
public static void ClearTransPageNumProblems()
{
_TransPageNumProblems = null;
}
public static DialogResult ReportTransPageNumProblems()
{
if (TransPageNumProblems != null && TransPageNumProblems.Count > 0)
{
string pnProbl = null;
foreach (string pstr in TransPageNumProblems)
pnProbl = pnProbl + "\n" + pstr;
return MessageBox.Show("Review the page numbers specified on transitions that transition to the following:\n" + pnProbl
+ "\r\n\r\nDo you want to review the PDF output prior to the page number update?"
+ "\r\n\r\nThis shouldd help to determine the cause of the inconsistent page numbers.",
"Inconsistent transition page numbers.", MessageBoxButtons.YesNo,MessageBoxIcon.Question);
}
return DialogResult.No;
}
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;
}
private string _BeforePageNumberPdf = null;
public string BeforePageNumberPdf
{
get { return _BeforePageNumberPdf; }
set { _BeforePageNumberPdf = value; }
}
public string Print(string pdfFolder, bool makePlacekeeper)
{
if (_MyItem is ProcedureInfo)
{
if (!(_MyItem.ActiveFormat.PlantFormat.FormatData.TransData.UseTransitionModifier ||
_MyItem.ActiveFormat.PlantFormat.FormatData.TransData.UseSpecificTransitionModifier))
return Print(_MyItem as ProcedureInfo, pdfFolder, makePlacekeeper);
else
{
// if the plant uses transition modifiers and/or page num in transition format,
// need to do two passes. First pass, sets the pagenumbers for each item,
// 2nd pass fills in the page numbers in transitions.
DirectoryInfo di = new DirectoryInfo(pdfFolder + @"\BeforePageNumber");
if (!di.Exists) di.Create();
string retstr = Print(_MyItem as ProcedureInfo, pdfFolder + @"\BeforePageNumber", false);
if (retstr == null) return null;
BeforePageNumberPdf = retstr;
ProcedureInfo.RefreshPageNumTransitions(_MyItem as ProcedureInfo);
return Print(_MyItem as ProcedureInfo, pdfFolder, makePlacekeeper);
}
}
return "";
}
private string BuildMSWordPDF(SectionInfo section)
{
if (section.PageNumber == 0) section.PageNumber = _MyHelper.CurrentPageNumber;
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)
{
int profileDepth = ProfileTimer.Push(">>>> CloseDocument");
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);
ProfileTimer.Pop(profileDepth);
}
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));
// PDFA1B does not allow layers, so this is disabled for now
// If enabled, CreateLayers will need to be skipped.
//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, bool makePlacekeeper)
{
int profileDepth = ProfileTimer.Push(">>>> PromsPrinter.Print");
if (_TransPageNumProblems == null) _TransPageNumProblems = new List<string>();
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", false);
_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)
{
ProfileTimer.Pop(profileDepth);
return null;
}
}
string retval = PrintProcedureOrFoldout(myProcedure, null, outputFileName, makePlacekeeper);
ProfileTimer.Pop(profileDepth);
return retval;
}
// 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 makePlacekeeper)
{
int profileDepth = ProfileTimer.Push(">>>> PrintProcedureOrFoldout");
Rtf2Pdf.TextAtCounter = 0;
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)
{
ProfileTimer.Pop(profileDepth);
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);
ProfileTimer.Pop(profileDepth);
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;
PrintOverride.CompressPropSubSup = mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressPropSubSup;
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:
float x = 0;
float y = 0;
if (!(mySection.ActiveFormat.Name.ToUpper().StartsWith("WST") || _MyHelper.Back32BitPROMS)) // compare folder contains PROMS generated PDF
{
x = 2 * 72F / (float)myProcedure.ActiveFormat.PlantFormat.FormatData.Font.CPI;
y = -9.5F;
}
x += 72F * VlnSettings.GetCommandFloat("X", x);
y -= 72F * VlnSettings.GetCommandFloat("Y", y);
_MyHelper.BackgroundOffset = new PointF(x,y);
_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);
}
// if this format uses phonelists, see if this section has one. We need to know the number
//of lines to adjust the pagelength for pagination and printing.
_MyHelper.PhoneListHeight = 0;
if (mySection.ActiveFormat.PlantFormat.FormatData.SectData.PrintPhoneList)
{
// get config for section
SectionConfig sc = mySection.MyConfig as SectionConfig;
if (sc.Section_PhoneList != null && sc.Section_PhoneList == "Y")
{
DocVersionConfig dvc = mySection.MyDocVersion.MyConfig as DocVersionConfig;
if (dvc != null)
{
string phlist = dvc.Print_PhoneList;
if (phlist != null && phlist != "")
{
// count lines:
int cl = 0;
int indx = phlist.IndexOf("\n");
while (indx > 0)
{
cl++;
if (indx + 1 > phlist.Length)
indx = -1;
else
indx = phlist.IndexOf("\n", indx + 1);
}
if (cl == 0) cl = 1; // phone list is a single line without an ending newline
_MyHelper.PhoneListHeight = cl * vlnPrintObject.SixLinesPerInch;
}
}
}
}
PdfReader readerWord = null;
string myPdfFile = null;
_MyHelper.FinalMessageSectionID = finalMessageSectionID; // set VlnSvgPageHelper with the finalMessageSectionID
if (mySection.IsAutoTOCSection)
GenerateTOC(mySection, myProcedure, cb, _TextLayer);
// is this the right place for PlaceKeeper?
// I think we need to check if the actual PlaceKeeper section has the PlaceKeeper flag set (for auto generation)
// users can turn this off and edit the section manaully in 16-bit.
//else if (mySection.IsPlacekeeperSection)
// GeneratePlaceKeeper(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)
{
// if it is continuous pagination, don't do blank page - not sure if this is correct place for this:
if (mySection.SectionConfig.Section_Pagination == SectionConfig.SectionPagination.Separate)
{
// 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);
}
}
_MyHelper.PrintedSectionPage = 0;
}
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);
if (DebugPagination.IsOpen) DebugPagination.WriteLine("{0:D6},'{1}'",
_MyHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, "No PROMS Output");
}
}
OnStatusChanged(myProcedure.DisplayNumber + " PDF Creation Completed", PromsPrinterStatusType.Progress, progress);
if (DebugPagination.IsOpen) DebugPagination.TotalPages += cb.PdfWriter.CurrentPageNumber;
CloseDocument(cb, outputFileName);
if (_MyHelper != null && makePlacekeeper)
{
// Setting the default font to Arial since that is what Calvert is currently using for their Placekeeper pages
VE_Font pkFont = new VE_Font("Arial", 11, E_Style.None, 12); // default font info.
// Ideally, we should grab the font from the DocStyle used for the Placekeeper.
// Note that Calvert has two Placekeeper docSyles (EOPs and AOPs) in the same format.
// Both Placekeeper DocStyles use Arial 11 pt font, so there is no need to grab it from the format file.
//foreach (DocStyle ds in _MyHelper.MySection.ActiveFormat.PlantFormat.DocStyles.DocStyleList)
//{ // note that this will get the last Placekeeper font setting
// if (ds.StructureStyle.Style == E_DocStructStyle.Placekeeper)
// pkFont = ds.Font;
//}
if (_MyHelper.MyPlacekeepers.Count > 0)
new Placekeeper(_MyHelper.MyPlacekeepers, pkFont);
}
_MyHelper = null;
ProfileTimer.Pop(profileDepth);
return outputFileName;
}
public void CreateWordDocPdf(PdfContentByte cb, SectionInfo mySection, ref PdfReader readerWord, ref string myPdfFile)
{
int profileDepth = ProfileTimer.Push(">>>> CreateWordDocPdf");
_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;
bool resetSvgForCont = true;
for (int ii = 0; ii < sectPageCount; ii++)
{
int pageNumber = 1 + ii;
bool didFoldout = false;
if (((mySection.MyDocStyle.StructureStyle.Style ?? 0) & E_DocStructStyle.UseSectionFoldout) != 0)
{
didFoldout = true;
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 (!didFoldout && 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);
if(DebugPagination.IsOpen) 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);
bool landscape = (mySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_WordContentLandscaped) == E_DocStructStyle.DSS_WordContentLandscaped;
if (landscape)
{
cb.SaveState();
System.Drawing.Drawing2D.Matrix myMatrix = new System.Drawing.Drawing2D.Matrix(0, 1, -1, 0, cb.PdfDocument.PageSize.Height, 0);
cb.Transform(myMatrix);
}
Rtf2Pdf.TextAt(cb, para, centerpos, ylocation + 6, 100, 12, "", yBottomMargin);
if (landscape) cb.RestoreState();
}
}
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;
// Calvert has a case in their stp landscape word docs where a ' (Continued)' message
// appears in their pagelist item for printing the section title, {ATTACHTITLECONT} pagelist
// However, other sections use this token, but do NOT have the continue message - so
// the docstyle was added to flag the difference between them (STP-Landscape Attachments has it,
// STP-Attachments do not)
if (resetSvgForCont && (mySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListAddSectCont) == E_DocStructStyle.DSS_PageListAddSectCont)
{
_MyHelper.ResetSvg();
resetSvgForCont = false; // only need to reset it once (for all pages after 1st page)
}
//DebugPagination.WriteLine("CreateWordDocPdf");
if ((mySection.MyDocStyle.StructureStyle.Where & E_DocStyleUse.UseOnFirstPage) > 0)
_MyHelper.MySection = mySection; // this resets the docstyle/pagestyle in 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);
}
finally
{
_MyHelper.IsLandscape = false; // reset landscape mode to false
}
ProfileTimer.Pop(profileDepth);
}
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);
ItemInfo procItem = myProcedure;
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;
}
//private void GeneratePlaceKeeper(SectionInfo pkSection, ProcedureInfo myProcedure, PdfContentByte cb, PdfLayer textLayer)
//{
// iTextSharp.text.pdf.PdfWriter writer = cb.PdfWriter;
// float _PointsPerPage = 792;
// float yTopMargin = _PointsPerPage - (float)pkSection.MyDocStyle.Layout.TopMargin;
// float yBottomMargin = Math.Max(0, yTopMargin - (float)pkSection.MyDocStyle.Layout.PageLength); // - 2 * vlnPrintObject.SixLinesPerInch);
// if (textLayer != null) cb.BeginLayer(textLayer);
// PlacekeeperData pkdata = pkSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.PlacekeeperData;
// ItemInfo procItem = ItemInfo.Get(myProcedure.ItemID);
// lastyLocation = 0;
// AddSectionToPK(pkSection, procItem, pkdata, 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)
{
return GetRtfToC(txt, tOfCData, null);
}
private string GetRtfToC(string txt, TableOfContentsData tOfCData, VE_Font overrideFont)
{
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;
if (overrideFont != null)
{
toctxt = new Volian.Controls.Library.DisplayText(txt, overrideFont, false);
myFont = overrideFont.WindowsFont;//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;
int startIndentAfterLevel = tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCStartIndentAfterLevel ?? 2; //
//level = level <= 2 ? 0 : level - 2; // no indenting until third level
level = level <= startIndentAfterLevel ? 0 : level - startIndentAfterLevel;
float indentOffset = (level * (secTitlePos - secNumPos));
// 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;
// Do the title first since it may wrap to 2nd line and this is an issue for
// doing a pagebreak, i.e. may cause a page break when the number on a single line
// would not.
//if (tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData
if (level == 0 && tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCUnderlineFirstLevelTitle)
{
VE_Font ovrFont = new VE_Font(tOfC.Font.Family, (int)tOfC.Font.Size,(E_Style)tOfC.Font.Style | E_Style.Underline, (float)tOfC.Font.CPI);
rtfText = GetRtfToC(mySection.MyContent.Text, tOfC, ovrFont);
}
else
rtfText = GetRtfToC(mySection.MyContent.Text, tOfC);
Paragraph myparagrapht = vlnPrintObject.RtfToParagraph(rtfText);
width = secPagePos - adjSecTitlePos - 6;
float savTitleWid = width;
float retval = Rtf2Pdf.TextAt(cb, myparagrapht, leftMargin + adjSecTitlePos, yPageStart - yLocation, width, height, "", yBottomMargin);
if (retval == 0) // couldn't fit, flags need for a page break.
{
cb.PdfDocument.NewPage();
_MyHelper.ResetSvg(); // needed to reset so that PSNotFirst pagelist justify flag gets used for BGE
yLocation = lastyLocation = 0;
retval = Rtf2Pdf.TextAt(cb, myparagrapht, leftMargin + adjSecTitlePos, yPageStart - yLocation, width, height, "", yBottomMargin);
}
float ttlRetval = retval;
float savTitleFillWidth = Rtf2Pdf.FillWidth;
// Now do the section number. Retval is the ylocation on page after the text
// is put out.
retval = Rtf2Pdf.TextAt(cb, myparagraphn, leftMargin + secNumPos + indentOffset, yPageStart - yLocation, numwidth * 1.3F, height, "", yBottomMargin);
float lSpace = (tOfC.TofCLineSpacing == 2) ? 2 * vlnPrintObject.SixLinesPerInch : vlnPrintObject.SixLinesPerInch;
// adjust ylocation for pagenumber - the ylocation will get reset if the
// section title split on 2 lines and the page number needs to be on the 2nd line.
if (retval != ttlRetval) yLocation += (retval - ttlRetval);
// retval = the minimum (further down the page) between section number and
// title - this accounts for multi line title.
retval = Math.Min(retval, ttlRetval);
lastyLocation = retval;
// check that the page number should be in the TOC (some BGE sections do not have the page number)
if (!((mySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DontNumberInTOC) == E_DocStructStyle.DontNumberInTOC))
{
// add a template for the page number:
// 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();
// get height - if two lines high, need width of 2nd line for adding
// space characters
float heightTtl = vlnPrintObject.GetHeight(cb, myparagrapht, savTitleWid, false);
string spaceStr = "";
float startSpace = 0;
// the '6's in the next few code lines & in the 'while' loop below allows the placement of the dots (or other space character)
// to be not too close to section title & page number.
if (heightTtl > vlnPrintObject.SixLinesPerInch)
{
// this title is 2 or more lines, find start of leader dots by determining length of text
// on 2nd line (the savTitleFillWidth is the widest line of the split title)
float secondLineWidth = width - savTitleFillWidth;
startSpace = leftMargin + adjSecTitlePos + secondLineWidth + 6;
}
else
startSpace = leftMargin + adjSecTitlePos + width + 6;
float endSpace = leftMargin + secPagePos - 6;
float numSpace = endSpace - startSpace;
rtfText = GetRtfToC(tOfC.TofCSpaceChar, tOfC);
Paragraph tmpmyparagraph = vlnPrintObject.RtfToParagraph(rtfText);
float spacchrwid = 0;
foreach (Chunk chkt in tmpmyparagraph.Chunks)
spacchrwid += chkt.GetWidthPoint();
while (numSpace > 6)
{
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 += (tOfC.TofCLineSpacing == 2 ? 2 * vlnPrintObject.SixLinesPerInch : 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 string GetRtfPlacekeeper(string txt, PlacekeeperData pkCData)
//{
// StringBuilder _RtfSB = new StringBuilder();
// Volian.Controls.Library.DisplayText pktxt = new Volian.Controls.Library.DisplayText(txt, pkCData.Font, false);
// System.Drawing.Font myFont = pktxt.TextFont.WindowsFont;
// _RtfSB.Append(vlnPrintObject.AddFontTable(myFont));
// _RtfSB.Append(pktxt.StartText);
// _RtfSB.Append("}");
// return _RtfSB.ToString();
//}
//private float AddSectionToPK(SectionInfo pkSection, ItemInfo ii, PlacekeeperData pkData, PdfContentByte cb, float yPageStart, float yLocation)
//{
// SectionConfig pkSC = pkSection.MyConfig as SectionConfig;
// if (pkSC.Section_Placekeeper != "Y") return yLocation; // automatic generation of Placekeeper turned off
// 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)pkSection.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.ItemID != pkSection.ItemID && sc != null && sc.Section_Placekeeper == "Y")
// {
// // Look at each step in the section and build a Placekeeper for those steps that are marked
// // 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 = GetRtfPlacekeeper(tmptxt, pkData);//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)pkSection.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 = pkSection.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));
// // 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;
// //float retval = Rtf2Pdf.TextAt(cb, myparagrapht, leftMargin + adjSecTitlePos, yPageStart - yLocation, width, height, "", yBottomMargin);
// //float ttlRetval = retval;
// //if (retval == 0)
// //{
// // cb.PdfDocument.NewPage();
// // //_MyLog.InfoFormat("NewPage 5 {0}", cb.PdfWriter.CurrentPageNumber);
// // yLocation = lastyLocation = 0;
// // retval = Rtf2Pdf.TextAt(cb, myparagrapht, leftMargin + adjSecTitlePos, yPageStart - yLocation, width, height, "", yBottomMargin);
// // ttlRetval = retval;
// //}
// //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 = lastyLocation = 0;
// // retval = Rtf2Pdf.TextAt(cb, myparagraphn, leftMargin + secNumPos + indentOffset, yPageStart - yLocation, width * 1.3F, height, "", yBottomMargin);
// //}
// //retval = Math.Min(retval, ttlRetval);
// //float lSpace = (tOfC.TofCLineSpacing == 2) ? 2 * vlnPrintObject.SixLinesPerInch : vlnPrintObject.SixLinesPerInch;
// //if (lastyLocation != 0 && ((lastyLocation - retval) > lSpace))
// // yLocation += (lastyLocation - retval - lSpace);
// //lastyLocation = retval;
// //// check that the page number should be in the TOC (some BGE sections do not have the page number)
// //if (!((mySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DontNumberInTOC) == E_DocStructStyle.DontNumberInTOC))
// //{
// // // add a template for the page number:
// // // 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 AddTemplatePKPageCounts(TableOfContentsData tOfC, float yLocation, float yPageStartAdj, float leftMargin, float secPagePos, float height, SectionInfo mySection)
//{
// string key = "PK" + 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)
{
int profileDepth = ProfileTimer.Push(">>>> CreateStepPdf");
//PrintTimer pt = new PrintTimer();
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.PathPrefix = myItemInfo.Path;
//Rtf2Pdf.PdfDebug = true;
Rtf2Pdf.Offset = new PointF(0, 2.5F);
if (section.MyDocStyle.LandscapePageList)
{
if ((section.MyConfig as SectionConfig).Section_Pagination == SectionConfig.SectionPagination.Separate)
{
System.Drawing.Drawing2D.Matrix myMatrix = new System.Drawing.Drawing2D.Matrix(0, 1, -1, 0, cb.PdfDocument.PageSize.Height, 0);
cb.Transform(myMatrix);
}
}
else
_MyHelper.IsLandscape = false;
_MyHelper.ChangeBarDefinition = MyChangeBarDefinition;
//pt.Description = "vlnParagrph";
vlnParagraph myParagraph = new vlnParagraph(null, cb, myItemInfo, (float)myItemInfo.MyDocStyle.Layout.LeftMargin, _NoBreakYOffset, 0, myItemInfo.ColumnMode, myItemInfo.ActiveFormat, null, null, 0,true,this);
//pt.Description = "After vlnParagrph";
float localYPageStart = 0;
float yPageStart = yTopMargin;
if (myItemInfo.HasChildren || myItemInfo.MyDocVersion.DocVersionConfig.SelectedSlave > 0)
{
localYPageStart = myParagraph.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin);
if (myParagraph.MyPlaceKeeper != null)
_MyHelper.MyPlacekeepers.Add(myParagraph.MyPlaceKeeper);
}
else if (!myItemInfo.MyDocStyle.OptionalSectionContent)
PrintTextMessage(cb, "No Section Content", _TextLayer);
SectionConfig.SectionPagination sp = SectionConfig.SectionPagination.Separate; // always the default
ItemInfo nxtItem = section.NextItem;
if (nxtItem != null)
{
// 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 && nxtItem.IsStepSection)
{
SectionInfo si = nxtItem as SectionInfo;
SectionConfig sc = si.SectionConfig;
try
{
if (sc != null) sp = sc.Section_Pagination;
}
catch (Exception ex)
{
sp = SectionConfig.SectionPagination.Separate;
}
}
}
if (sp == SectionConfig.SectionPagination.Separate)
{
if (section.MyDocStyle.LandscapePageList)
{
_MyHelper.IsLandscape = false;
}
cb.PdfDocument.NewPage(); // end of step section
//_MyLog.InfoFormat("NewPage 6 {0}", cb.PdfWriter.CurrentPageNumber);
_NoBreakYOffset = 0;
yPageStart = yTopMargin;
}
else
{
if (nxtItem != null && nxtItem.MyPrevious != null && nxtItem.ActiveFormat.PlantFormat.FormatData.SectData.SectionHeader.Level0Big)
localYPageStart -= 12;
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);
//pt.Description = "End";
ProfileTimer.Pop(profileDepth);
}
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);
if (DebugPagination.IsOpen) 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();
}
}
//public class PrintTimer
//{
// private DateTime _StartTime = DateTime.Now;
// public DateTime StartTime
// {
// get { return _StartTime; }
// set { _StartTime = value; }
// }
// private string _Description = "Start";
// public string Description
// {
// get { return _Description; }
// set
// {
// DateTime dtNext = DateTime.Now;
// //Console.WriteLine("{0},'{1}'", TimeSpan.FromTicks(dtNext.Ticks - LastTime.Ticks).TotalSeconds, Description);
// _Description = value;
// _LastTime = dtNext;
// }
// }
// private DateTime _LastTime = DateTime.Now;
// public DateTime LastTime
// {
// get { return _LastTime; }
// set { _LastTime = value; }
// }
//}
}