2498 lines
		
	
	
		
			117 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			2498 lines
		
	
	
		
			117 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;
 | |
| using JR.Utils.GUI.Forms;
 | |
| 
 | |
| 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
 | |
| 	{
 | |
| 		public bool NeedSupInfoBreak = false;
 | |
| 		public E_SupInfoPrintType SupInfoPrintType = E_SupInfoPrintType.None;
 | |
| 		// used to link supinfo steps in pdf
 | |
| 		public int SupInfoPdfPageCount = -1;
 | |
| 		private Dictionary<int, int> _SupInfoPdfPage;
 | |
| 		public Dictionary<int, int> SupInfoPdfPage
 | |
| 		{
 | |
| 			get { return _SupInfoPdfPage; }
 | |
| 			set { _SupInfoPdfPage = value; }
 | |
| 		}
 | |
| 		private bool _DoingFacingPage = false;		// used to flag actual pdf generation of facing page within final print (so no section titles get printed)
 | |
| 		public bool DoingFacingPage
 | |
| 		{
 | |
| 			get { return _DoingFacingPage; }
 | |
| 			set { _DoingFacingPage = value; }
 | |
| 		}
 | |
| 		// used to save word sections with resolved ROs (for export file generated from approve)
 | |
| 		private Dictionary<int, byte[]> _DocReplace;
 | |
| 		public Dictionary<int, byte[]> DocReplace
 | |
| 		{
 | |
| 			get { return _DocReplace; }
 | |
| 			set { _DocReplace = value; }
 | |
| 		}
 | |
| 		private bool _SaveLinks = false;
 | |
| 		public bool SaveLinks
 | |
| 		{
 | |
| 			get { return _SaveLinks; }
 | |
| 			set { _SaveLinks = value; }
 | |
| 		}
 | |
| 		private bool _RemoveTrailingHardReturnsAndManualPageBreaks = false;
 | |
| 		public bool RemoveTrailingHardReturnsAndManualPageBreaks
 | |
| 		{
 | |
| 			get { return _RemoveTrailingHardReturnsAndManualPageBreaks; }
 | |
| 			set { _RemoveTrailingHardReturnsAndManualPageBreaks = value; }
 | |
| 		}
 | |
| 
 | |
| 		private string _Prefix = ""; // RHM20150506 Multiline ItemID TextBox
 | |
| 		public string Prefix
 | |
| 		{
 | |
| 			get { return _Prefix; }
 | |
| 			set { _Prefix = value; }
 | |
| 		}
 | |
| 		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;
 | |
| 		public ItemInfo MyItem
 | |
| 		{
 | |
| 			get { return _MyItem; }
 | |
| 			set { _MyItem = value; }
 | |
| 		}
 | |
| 		private string _Watermark;
 | |
| 		//C2018-009 print PROMS version
 | |
| 		private string _PromsVersion = "";
 | |
| 		public string PromsVersion
 | |
| 		{
 | |
| 			get { return _PromsVersion; }
 | |
| 			set { _PromsVersion = value; }
 | |
| 		}
 | |
| 		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 bool _BatchPrint = true;		// flags that a batch-type print is occurring, i.e. AllProcedures or Automatic testing
 | |
| 		public bool BatchPrint
 | |
| 		{
 | |
| 			get { return _BatchPrint; }
 | |
| 			set { _BatchPrint = 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 + "\r\n" + pstr;
 | |
| 				Clipboard.SetText(pnProbl);
 | |
| 				return FlexibleMessageBox.Show("The following list was placed on the Windows Clipboard."
 | |
| 					+ "\r\nIt shows the page numbers of the locations that are referenced by transitions."
 | |
| 					+ "\r\nThis list, along with the PDF, can help you to determine the cause of the inconsistent page numbers."
 | |
| 					+ "\r\n\r\nDo you want to also review the PDF output prior to the second pass printing?"
 | |
| 					// C2017-018 Output Column Headers for Inconsistent Page Transitions
 | |
| 					+ "\r\n\r\nItemID\tTransition Destination\tPage Pass 1\t Page Pass 2\r\n\r\n" + pnProbl, 
 | |
| 					"Inconsistent Transition Page Numbers", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
 | |
| 			}
 | |
| 			return DialogResult.No;
 | |
| 		}
 | |
| 		private ReaderHelper _MyReaderHelper;
 | |
| 		public ReaderHelper MyReaderHelper
 | |
| 		{
 | |
| 			get { return _MyReaderHelper; }
 | |
| 			set { _MyReaderHelper = value; }
 | |
| 		}
 | |
| 		private string _BlankPageText;		// C2019-004: Allow user to define duplex blank page text
 | |
| 		public string BlankPageText
 | |
| 		{
 | |
| 			get { return _BlankPageText; }
 | |
| 			set { _BlankPageText = value; }
 | |
| 		}
 | |
| 		// use DidAll & MergeNotIncuded to know that printing all (not single) was done. Used w/ merge code to know when to return, i.e. not include in merged pdf
 | |
| 		private bool _DidAll;
 | |
| 		public bool DidAll				// value passed in from frmPdfStatusForm				
 | |
| 		{
 | |
| 			get { return _DidAll; }
 | |
| 			set { _DidAll = value; }
 | |
| 		}
 | |
| 		private bool _MergeNotIncluded;
 | |
| 		public bool MergeNotIncluded
 | |
| 		{
 | |
| 			get { return _MergeNotIncluded; }
 | |
| 			set { _MergeNotIncluded = 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, bool batchPrint, string prefix, bool saveLinks, bool removeTrailngHardReturnsAndManualPageBreaks, string blankPageText, bool didAll)
 | |
| 		{
 | |
| 			Prefix = prefix; // RHM20150506 Multiline ItemID TextBox
 | |
| 			_MyItem = myItem;
 | |
| 			_Rev = rev;
 | |
| 			_Watermark = watermark;
 | |
| 			_DebugOutput = debugOutput;
 | |
| 			_BackgroundFolder = backgroundFolder;
 | |
| 			_OpenPDF = openPDF;
 | |
| 			_OverWrite = overWrite;
 | |
| 			_MyChangeBarDefinition = cbd;
 | |
| 			_PDFFile = pdfFile;
 | |
| 			_OriginalPageBreak = origPgBrk;
 | |
| 			_InsertBlankPages = insertBlankPages;
 | |
| 			_BatchPrint = batchPrint;
 | |
| 			_MyReaderHelper = new ReaderHelper(this);
 | |
| 			_SaveLinks = saveLinks;
 | |
| 			_RemoveTrailingHardReturnsAndManualPageBreaks = removeTrailngHardReturnsAndManualPageBreaks;
 | |
| 			_BlankPageText = blankPageText;
 | |
| 			_DidAll = didAll;
 | |
| 			_MergeNotIncluded = false;
 | |
| 			//_MyReaderHelper.LoadTree(myItem);
 | |
| 		}
 | |
| 		// Pass 1 PDF Name
 | |
| 		private string _BeforePageNumberPdf = null;
 | |
| 		public string BeforePageNumberPdf
 | |
| 		{
 | |
| 			get { return _BeforePageNumberPdf; }
 | |
| 			set { _BeforePageNumberPdf = value; }
 | |
| 		}
 | |
| 		// Pass 2 PDF Name
 | |
| 		private string _BeforePageNumber2Pdf = null;
 | |
| 		public string BeforePageNumber2Pdf
 | |
| 		{
 | |
| 			get { return _BeforePageNumber2Pdf; }
 | |
| 			set { _BeforePageNumber2Pdf = value; }
 | |
| 		}
 | |
| 		public string Print(string pdfFolder, bool makePlacekeeper, bool makeContinuousActionSummary)
 | |
| 		{
 | |
| 			if (_MyItem is ProcedureInfo)
 | |
| 			{
 | |
| 				ProcedureConfig pcfg = (ProcedureConfig)(_MyItem as ProcedureInfo).MyConfig;
 | |
| 				if (DidAll && pcfg.Print_NotInMergeAll)		// will be merging a pdf, so don't print this procedure if user set that on procedure propertures
 | |
| 				{
 | |
| 					_MergeNotIncluded = true;
 | |
| 					return null;
 | |
| 				}
 | |
| 				// B2017-186 First do Procedures that don't have page number transitions
 | |
| 				if (!(_MyItem.ActiveFormat.PlantFormat.FormatData.TransData.UseTransitionModifier ||
 | |
| 					_MyItem.ActiveFormat.PlantFormat.FormatData.TransData.UseSpecificTransitionModifier))
 | |
| 				{
 | |
| 					// B2017-186 Do Facing Page SAMGs
 | |
| 					if ((_MyItem as ProcedureInfo).ProcHasSupInfoData)
 | |
| 					{
 | |
| 						// Use two passes to print facing page supplemental information for SAMGs
 | |
| 						//	First pass gets pagination for the step sections and stores the associated supplemental information ids in 
 | |
| 						//		the list StepSectPageBreaksForSupInfo off of the section object
 | |
| 						//	Second pass prints the supplemental information pdfs using the list generated in the first pass to know where to do the
 | |
| 						//		supplemental information page breaks & then merges in those pages when printing the step sections.
 | |
| 						SectionInfo.ResetLookupStepSectPageBreaks();		// B2017-192: Reset lists for tracking page breaks
 | |
| 						SectionInfo.ResetLookupStepSectPageBreaksForSupInfo();
 | |
| 						SupInfoPrintType = E_SupInfoPrintType.DoPageBreaks;
 | |
| 						string retstr = Print(_MyItem as ProcedureInfo, pdfFolder, false, false);
 | |
| 						if (retstr == null) return null;
 | |
| 						SupInfoPrintType = E_SupInfoPrintType.Merge;
 | |
| 						return Print(_MyItem as ProcedureInfo, pdfFolder, false, false);
 | |
| 					}
 | |
| 					else // B2017-186 Neither Facing Pages or Page Number Transitions
 | |
| 						return Print(_MyItem as ProcedureInfo, pdfFolder, makePlacekeeper, makeContinuousActionSummary);
 | |
| 				}
 | |
| 				else // B2017-186 Page Number Transitions
 | |
| 				{
 | |
| 					string retstr;
 | |
| 					// 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 + @"\PageNumberPass1");
 | |
| 					if (!di.Exists) di.Create();
 | |
| 					if ((_MyItem as ProcedureInfo).ProcHasSupInfoData)// B2017-186 Adds Facing Page Code to Page Number Transition Code
 | |
| 					{
 | |
| 						// Use two passes to print facing page supplemental information for SAMGs
 | |
| 						//	First pass gets pagination for the step sections and stores the associated supplemental information ids in 
 | |
| 						//		the list StepSectPageBreaksForSupInfo off of the section object
 | |
| 						//	Second pass prints the supplemental information pdfs using the list generated in the first pass to know where to do the
 | |
| 						//		supplemental information page breaks & then merges in those pages when printing the step sections.
 | |
| 						SupInfoPrintType = E_SupInfoPrintType.DoPageBreaks;
 | |
| 						retstr = Print(_MyItem as ProcedureInfo, pdfFolder, false, false);
 | |
| 						if (retstr == null) return null;
 | |
| 						SupInfoPrintType = E_SupInfoPrintType.Merge;
 | |
| 					}
 | |
| 					retstr = Print(_MyItem as ProcedureInfo, pdfFolder + @"\PageNumberPass1", false, false);
 | |
| 					if (retstr == null) return null;
 | |
| 					BeforePageNumberPdf = retstr;
 | |
| 					BeforePageNumber2Pdf = null; // C2017-018 Initialize Pass 2 PDF Name
 | |
| 					ProcedureInfo.RefreshPageNumTransitions(_MyItem as ProcedureInfo);
 | |
| 					_MyReaderHelper = new ReaderHelper(this);
 | |
| 					retstr = Print(_MyItem as ProcedureInfo, pdfFolder, makePlacekeeper, makeContinuousActionSummary);
 | |
| 					if (TransPageNumProblems.Count > 0)
 | |
| 					{
 | |
| 						if (BatchPrint || (MessageBox.Show("Page Number Transitions may be fixed if a second pass is performed.  Do you want to perform a second pass?", "Page Number Transition Errors", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes))
 | |
| 						{
 | |
| 							DirectoryInfo di1 = new DirectoryInfo(pdfFolder + @"\PageNumberPass2");
 | |
| 							if (!di1.Exists) di1.Create();
 | |
| 							FileInfo fi = new FileInfo(retstr);
 | |
| 							// Save Pass 2 PDF Name
 | |
| 							FileInfo fidest = new FileInfo(BeforePageNumber2Pdf = di1.FullName + @"\" + fi.Name);
 | |
| 							if (fidest.Exists) fidest.Delete();
 | |
| 							try
 | |
| 							{
 | |
| 								fi.MoveTo(di1.FullName + @"\" + fi.Name);
 | |
| 							}
 | |
| 							catch (Exception ex)
 | |
| 							{
 | |
| 								_MyLog.ErrorFormat("{0} During Save {1}", ex.GetType().FullName, ex.Message);
 | |
| 							}
 | |
| 							ClearTransPageNumProblems();
 | |
| 							RefreshPageNumber(_MyItem);
 | |
| 							ProcedureInfo.RefreshPageNumTransitions(_MyItem as ProcedureInfo);
 | |
| 							_MyReaderHelper = new ReaderHelper(this);
 | |
| 							retstr = Print(_MyItem as ProcedureInfo, pdfFolder, makePlacekeeper, makeContinuousActionSummary);
 | |
| 						}
 | |
| 					}
 | |
| 					return retstr;
 | |
| 				}
 | |
| 			}
 | |
| 			return "";
 | |
| 		}
 | |
| 
 | |
| 		private void RefreshPageNumber(ItemInfo _MyItem)
 | |
| 		{
 | |
| 			// set all page numbers for all items under the passed in procedure item
 | |
| 			_MyItem.PageNumber = _MyItem.PageNumberNextPass;
 | |
| 			if (_MyItem.MyContent.ContentPartCount > 0)			
 | |
| 			{
 | |
| 				foreach (PartInfo pi in _MyItem.MyContent.ContentParts)
 | |
| 				{
 | |
| 					foreach (ItemInfo ii in pi.MyItems)
 | |
| 						RefreshPageNumber(ii);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		internal string BuildMSWordPDF(SectionInfo section)
 | |
| 		{
 | |
| 			DateTime tStart = DateTime.Now;
 | |
| 			string MSWordFile = null;
 | |
| 			if (section.MyContent.ContentEntryCount == 1)
 | |
| 			{ 
 | |
| 				MSWordToPDF.DocReplace = DocReplace;
 | |
| 				MSWordFile = MSWordToPDF.GetDocPdf(section, PrintOverride.TextColor);
 | |
| 				MSWordToPDF.DocReplace = null;
 | |
| 				GC.Collect(); // memory garbage collection
 | |
| 				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)
 | |
| 			{
 | |
| 				if (cb.PdfDocument.PageSize.Height > cb.PdfDocument.PageSize.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 PdfLayer _PROMSVersionLayer; //C2018-009 print PROMS version
 | |
| 		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);
 | |
| 				_PROMSVersionLayer = new PdfLayer("PROMS Version", cb.PdfWriter); //C2018-009 print PROMS version
 | |
| 				_PROMSVersionLayer.SetPrint("PROMS Version", true);
 | |
| 			}
 | |
| 		}
 | |
| 		public static int ProcPageCount = -1;				// Used to count page numbers in each pdf. This will be used if/when pdfs are merged together.
 | |
| 		private void CloseDocument(string fileName)
 | |
| 		{
 | |
| 			int profileDepth = ProfileTimer.Push(">>>> CloseDocument");
 | |
| 			try
 | |
| 			{
 | |
| 				ProcPageCount = MyContentByte.PdfWriter.CurrentPageNumber - 1;
 | |
| 				MyContentByte.PdfDocument.Close();
 | |
| 				MyContentByte = null;
 | |
| 			}
 | |
| 			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 _MyContentByte = null;
 | |
| 		public PdfContentByte MyContentByte
 | |
| 		{
 | |
| 			get { return _MyContentByte; }
 | |
| 			set
 | |
| 			{ 
 | |
| 				_MyContentByte = value;
 | |
| 				if(value != null)MyReaderHelper.LoadTree(MyItem);
 | |
| 			}
 | |
| 		}
 | |
| 		public void NewPage()
 | |
| 		{
 | |
| 			string path = Volian.Base.Library.vlnStackTrace.StackToStringLocal(2, 1);
 | |
| 			NewPage(false);
 | |
| 		}
 | |
| 		public void NewPage(bool sectionChange)
 | |
| 		{
 | |
| 			// the first time we come in here we already printed the first page.
 | |
| 			// we are now setting up the page size for the next page
 | |
| 			iTextSharp.text.Rectangle rct = MyReaderHelper.MyPromsPrinter.MyContentByte.PdfDocument.PageSize;
 | |
| 			// B2019-166 Only check for Word margins if the section changed 
 | |
| 			//           - was getting next section's page margins prematurely (while still processing the a multi-page section)
 | |
| 			//           - this was changing the margins/orientation of other pages in the same Word section.
 | |
| 			if (_MyHelper != null && sectionChange)
 | |
| 			{
 | |
| 				SectionInfo currentSection = _MyHelper.MySection;
 | |
| 				SectionInfo nextSection = GetNextSection(currentSection); // _MyHelper.MySection.NextItem as SectionInfo;
 | |
| 				//SectionConfig sc = (nextSection ?? currentSection).MyConfig as SectionConfig;
 | |
| 				// If we are changing to a different section, then get the config from the nextSection
 | |
| 				// else we are still printing in the same section so get the config from the current section
 | |
| 				SectionConfig sc = ((!sectionChange || nextSection == null)? currentSection.MyConfig : nextSection.MyConfig) as SectionConfig;
 | |
| 				bool wordMargins = (sc != null && sc.Section_WordMargin == "Y");
 | |
| 				if (wordMargins)
 | |
| 				{
 | |
| 					if (nextSection != null && (sectionChange) && !nextSection.IsStepSection)	//change to a word section
 | |
| 						{
 | |
| 						LastWordSection = nextSection;
 | |
| 						_PageCountOfWordSection = 1;
 | |
| 						MyReaderHelper.MySectionInfo = LastWordSection;
 | |
| 						//ShowNeedForPageSize();
 | |
| 						rct = MyReaderHelper.GetSize(LastWordSection, 1);
 | |
| 					}
 | |
| 					else if (!currentSection.IsStepSection)	//current section is a word section
 | |
| 					{
 | |
| 						if (currentSection != LastWordSection)
 | |
| 						{
 | |
| 							LastWordSection = currentSection;
 | |
| 							_PageCountOfWordSection = 1;
 | |
| 						}
 | |
| 						else
 | |
| 							if (!_MyHelper.OnBlankPage) _PageCountOfWordSection++;	// B2018-049: supplemental printing throws off page sizes
 | |
| 						MyReaderHelper.MySectionInfo = LastWordSection;
 | |
| 						//ShowNeedForPageSize();
 | |
| 						rct = MyReaderHelper.GetSize(LastWordSection, _PageCountOfWordSection);
 | |
| 					}
 | |
| 				}
 | |
| 				else // don't use Word margins
 | |
| 				{
 | |
| 					rct = PDFPageSize.UsePaperSize(MyItem.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
 | |
| 				}
 | |
| 				// C2018-004 create meta file for baseline compares
 | |
| 				if (currentSection.IsStepSection)
 | |
| 					Volian.Base.Library.BaselineMetaFile.WriteLine("{0}", rct);
 | |
| 				else
 | |
| 					Volian.Base.Library.BaselineMetaFile.WriteLine("UseWordMargins={0} {1} ", (wordMargins)?"Y":"N", rct);
 | |
| 				//Console.WriteLine("\"{0}\"\t\"{1}\"\t\"{2}\"\t\"{3}\"\t{4}"
 | |
| 				//  , currentSection == null ? "" : currentSection.DisplayNumber + " " + currentSection.DisplayText
 | |
| 				//  , nextSection == null ? "" : nextSection.DisplayNumber + " " + nextSection.DisplayText
 | |
| 				//  , sectionChange, wordMargins,_PageCountOfWordSection);
 | |
| 			}
 | |
| 			// Bug Fix:  B2016-135  when using a large page size word section, that large page size was being used for the foldout page
 | |
| 			//           save this for the next section which will be the large page size word section.
 | |
| 			// Bug Fix:  B2018-049  supplemental printing throws off page sizes  (need to do same thing as fix for foldouts)
 | |
| 			// Bug Fix:  B2019-165 (Byron/Braidwood) also don't do this if the current section has Don't Include Duplex Foldout checkbox checked (automation tab of section properties)
 | |
| 			if ((_MyFoldoutReader.Count > 0) && (_MyHelper != null && !((_MyHelper.MySection.MyConfig as SectionConfig).Section_DontIncludeDuplexFoldout) || (_MyHelper != null && _MyHelper.MySection != null && _MyHelper.MySection.MyProcedure.ProcHasSupInfoData)))
 | |
| 				MyContentByte.PdfDocument.SetPageSize(NxtRCT);
 | |
| 			else
 | |
| 				MyContentByte.PdfDocument.SetPageSize(rct);
 | |
| 			NxtRCT = rct;
 | |
| 			MyContentByte.PdfDocument.NewPage();
 | |
| 		}
 | |
| 		private static bool _BaselineTesting = false;  // Is the baseline being run (/P Commandline Parameter)
 | |
| 		public static bool BaselineTesting
 | |
| 		{
 | |
| 			get { return PromsPrinter._BaselineTesting; }
 | |
| 			set { PromsPrinter._BaselineTesting = value; }
 | |
| 		}
 | |
| 		private iTextSharp.text.Rectangle NxtRCT = PageSize.LETTER;
 | |
| 		private SectionInfo GetNextSection(SectionInfo currentSection)
 | |
| 		{
 | |
| 			if (currentSection.Sections != null)
 | |
| 				return currentSection.Sections[0].GetSectionInfo();
 | |
| 			if (currentSection.NextItem != null)
 | |
| 				return currentSection.NextItem.GetSectionInfo();
 | |
| 			ItemInfo parent = currentSection.ActiveParent as ItemInfo;
 | |
| 			while (parent != null && parent.NextItem == null)
 | |
| 				parent = parent.ActiveParent as ItemInfo;
 | |
| 			if (parent == null) return null;
 | |
| 			return parent.NextItem.GetSectionInfo();
 | |
| 		}
 | |
| 		private SectionInfo _PreviousWordSection = null;
 | |
| 		public SectionInfo PreviousWordSection
 | |
| 		{
 | |
| 			get { return _PreviousWordSection; }
 | |
| 			set { _PreviousWordSection = value; }
 | |
| 		}
 | |
| 		private SectionInfo _LastWordSection = null;
 | |
| 		public SectionInfo LastWordSection
 | |
| 		{
 | |
| 			get { return _LastWordSection; }
 | |
| 			set 
 | |
| 			{
 | |
| 				PreviousWordSection = _LastWordSection;
 | |
| 				_LastWordSection = value; 
 | |
| 			}
 | |
| 		}
 | |
| 		private int _PageCountOfWordSection = 0;
 | |
| 		//private void ShowNeedForPageSize()
 | |
| 		//{
 | |
| 		//  if(PreviousWordSection != null && PreviousWordSection != LastWordSection)
 | |
| 		//    Console.WriteLine("Switch From {0}.{1} ",PreviousWordSection.DisplayNumber,PreviousWordSection.DisplayText);
 | |
| 		//  Console.WriteLine("To {0}.{1} Page: {2}",LastWordSection.DisplayNumber,LastWordSection.DisplayText,_PageCountOfWordSection);
 | |
| 		//  PreviousWordSection = LastWordSection;
 | |
| 		//}
 | |
| 		private PdfContentByte OpenDoc(string outputFileName, iTextSharp.text.Rectangle rect)
 | |
| 		{
 | |
| 			PdfWriter writer=null;
 | |
| 			iTextSharp.text.Document document = new iTextSharp.text.Document(rect);
 | |
| 			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 MyContentByte = 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;
 | |
| 			}
 | |
| 			MyContentByte = writer.DirectContent;
 | |
| 			return MyContentByte;
 | |
| 		}
 | |
| 		//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, bool makeContinuousActionSummary)
 | |
| 		{
 | |
| 			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>();
 | |
| 			VlnItextFont.RegisterFontFolder(); //B2019-174 register the font folder so that symbols will display on auto TOC
 | |
| 			if (myProcedure.Sections != null)
 | |
| 			{
 | |
| 				int cnt = 0;
 | |
| 				foreach (SectionInfo mySection in myProcedure.Sections)
 | |
| 				{
 | |
| 					//C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
 | |
| 					if ((myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts && (mySection.MyConfig as SectionConfig).Section_IsFoldout == "Y")
 | |
| 						|| (myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.AlternateFloatingFoldout && (mySection.MyConfig as SectionConfig).Section_IsFoldout == "Y"))
 | |
| 					{
 | |
| 						// 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, false);
 | |
| 						_MyFoldoutReader.Add(foldoutPdf != null ? new PdfReader(foldoutPdf) : null);
 | |
| 						cnt++;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			OnStatusChanged("Print " + myProcedure.DisplayNumber, PromsPrinterStatusType.Start);
 | |
| 			string outputFileName = pdfFolder + "\\" + Prefix + PDFFile; // RHM20150506 Multiline ItemID TextBox
 | |
| 			
 | |
| 			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, makeContinuousActionSummary);
 | |
| 			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.MyConfig as SectionConfig).Section_IsFoldout == "Y")) //C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
 | |
| 					{
 | |
| 						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 PdfReader readerWord;
 | |
| 		private string PrintProcedureOrFoldout(ProcedureInfo myProcedure, SectionInfo myFoldoutSection, string outputFileName, bool makePlacekeeper, bool makeContinuousActionSummary)
 | |
| 		{
 | |
| 			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);
 | |
| 			iTextSharp.text.Rectangle rct = PDFPageSize.UsePaperSize(myProcedure.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
 | |
| 			if (myProcedure.Sections != null && !myProcedure.Sections[0].IsStepSection && !doingFoldout) // B2019-166 also don't do this if doing a foldout else it will use the margins set in word
 | |
| 			{
 | |
| 				SectionInfo si = myProcedure.Sections[0] as SectionInfo;
 | |
| 				SectionConfig sc = si.MyConfig as SectionConfig;
 | |
| 				bool wordMargins = (sc != null && sc.Section_WordMargin == "Y");
 | |
| 				if (wordMargins)
 | |
| 				{
 | |
| 					string pdfFile =BuildMSWordPDF(si);
 | |
| 					try
 | |
| 					{
 | |
| 						PdfReader reader = new PdfReader(pdfFile);
 | |
| 						rct = reader.GetPageSizeWithRotation(1);
 | |
| 					}
 | |
| 					catch (Exception ex)
 | |
| 					{
 | |
| 						MessageBox.Show(ex.Message, ex.GetType().FullName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
 | |
| 						_MyLog.Warn(string.Format("Error of ReadPDf [{0}],{1}.{2}",si.ItemID,si.DisplayNumber,si.DisplayText),ex);
 | |
| 						throw new Exception("Error in readPDF", ex);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			PdfContentByte cb = OpenDoc(outputFileName, rct);
 | |
| 			if (cb == null)
 | |
| 			{
 | |
| 				ProfileTimer.Pop(profileDepth);
 | |
| 				return null;
 | |
| 			}
 | |
| 				SetupProperties(cb.PdfDocument, myProcedure);
 | |
| 			OnStatusChanged("Before NewPage", PromsPrinterStatusType.Before);
 | |
| 			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;
 | |
| 			bool firstStepSec = true;
 | |
| 			foreach (SectionInfo mySection in myProcedure.Sections)
 | |
| 			{
 | |
| 				NeedSupInfoBreak = true;
 | |
| 				bool isFoldoutSection = (mySection.MyConfig as SectionConfig).Section_IsFoldout == "Y"; //C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
 | |
| 				if (((isFoldoutSection && myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts)
 | |
| 											|| (myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.AlternateFloatingFoldout && isFoldoutSection))
 | |
| 											!= 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.CreatingSupInfoPage = false;
 | |
| 					_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.Trim();//CreateFileName(myProcedure.DisplayNumber);
 | |
| 						FileInfo VEPromsFile = new FileInfo(procedureFileName);
 | |
| 						if (VEPromsFile.Exists && !doingFoldout)
 | |
| 						{
 | |
| 							_MyHelper.BackgroundFile = procedureFileName;
 | |
| 							float x = 0;
 | |
| 							float y = 0;
 | |
| 							if (!(mySection.ActiveFormat.Name.ToUpper().StartsWith("WST") || _MyHelper.Back32BitPROMS)) // compare folder contains PROMS generated PDF
 | |
| 							{
 | |
| 								// X value below = 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:
 | |
| 								// These values adjust if overlay is 16bit versus 32bit.  This is
 | |
| 								// used so that the comparison is an exact match. Use 0,0 if comparing to another 32bit
 | |
| 								// pdf, i.e. won't process the following 2 lines of code.
 | |
| 								x = 2 * 72F / (float)myProcedure.ActiveFormat.PlantFormat.FormatData.Font.CPI;
 | |
| 								y = -9.5F;
 | |
| 							}
 | |
| 							x += 72F * VlnSettings.GetCommandFloat("X", 0);
 | |
| 							y -= 72F * VlnSettings.GetCommandFloat("Y", 0);
 | |
| 							_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.PROMSVersionLayer = _PROMSVersionLayer; //C2018-009 print PROMS version
 | |
| 					}
 | |
| 					_MyHelper.Rev = _Rev;
 | |
| 					_MyHelper.Watermark = _Watermark;
 | |
| 					// C2019-039 Remove automatic zoom on Overlay PDFs
 | |
| 					//_MyHelper.DoZoomOMatic = DebugOutput;
 | |
| 					_MyHelper.OriginalPageBreak = OriginalPageBreak;
 | |
| 					_MyHelper.PROMSVersion = _PromsVersion; //C2018-009 print PROMS version
 | |
| 					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;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				_MyHelper.FinalMessageSectionID = finalMessageSectionID; // set VlnSvgPageHelper with the finalMessageSectionID
 | |
| 
 | |
| 				if (mySection.IsAutoTOCSection)
 | |
| 				{
 | |
| 					if (((cb.PdfWriter.CurrentPageNumber % 2 == 0 && !_MyHelper.CreatingFoldoutPage) || myProcedure.ProcHasSupInfoData) && InsertBlankPages) // Bug Fix: B2016-181 - add blank page if page count is even
 | |
| 					{
 | |
| 						InsertBlankPage(cb);
 | |
| 					}
 | |
| 					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];
 | |
| 							// B2019-165 Don't print the duplex foldout (on the back of the page) if the Don't Include Duplex Foldout check box was checked in section properties
 | |
| 							if (firstStep.FoldoutIndex() > -1 && (mySection.MyPrevious == null || !((mySection.MyPrevious.MyConfig as SectionConfig).Section_DontIncludeDuplexFoldout)))
 | |
| 								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
 | |
| 									InsertBlankPage(cb);
 | |
| 									//_MyLog.InfoFormat("NewPage Begin Step Sect blank {0}", cb.PdfWriter.CurrentPageNumber);
 | |
| 								}
 | |
| 							}
 | |
| 							else
 | |
| 							{
 | |
| 								// If the procedure has supplemental facing pages, but this section does not & it's the first section,
 | |
| 								// need a blank 'facing page'.  Sections after the first will get blank 'facing page' in print's pagination logic
 | |
| 								if (SupInfoPrintType==E_SupInfoPrintType.Merge && !mySection.HasSupInfoSteps && firstStepSec && InsertBlankPages)
 | |
| 								{
 | |
| 									InsertBlankPage(cb);
 | |
| 								}
 | |
| 							}
 | |
| 						}
 | |
| 						firstStepSec = false;
 | |
| 						CreateStepPdf(mySection, cb);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						CreateWordDocPdf(cb, mySection);
 | |
| 					}
 | |
| 				}
 | |
| 				_MyHelper.PrintedSectionPage = 0;
 | |
| 			}
 | |
| 			if (_MyHelper != null && _MyHelper.BackgroundFile != null)
 | |
| 			{
 | |
| 				_MyHelper.MySvg = null;
 | |
| 				while (cb.PdfWriter.CurrentPageNumber <= _MyHelper.BackgroundPageCount)
 | |
| 				{
 | |
| 					iTextSharp.text.Font font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 30, iTextSharp.text.Font.NORMAL, new iTextSharp.text.Color(PrintOverride.TextColor));
 | |
| 					PrintTextMessage(cb, "No Proms Output", _TextLayer, font);
 | |
| 					NewPage();
 | |
| 					//_MyLog.InfoFormat("NewPage 2 {0}", cb.PdfWriter.CurrentPageNumber);
 | |
| 					if (DebugPagination.IsOpen) DebugPagination.WriteLine("{0:D6},'{1}'",
 | |
| 						_MyHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, "No PROMS Output");
 | |
| 					//C2018-015 add debug pagination to meta file
 | |
| 					if (BaselineMetaFile.IsOpen) BaselineMetaFile.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(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)
 | |
| 					MyPlacekeeper = new Placekeeper(_MyHelper.MyPlacekeepers, pkFont);
 | |
| 			}
 | |
| 			// Generate the Continuous Action Summary
 | |
| 			if (_MyHelper != null && makeContinuousActionSummary)
 | |
| 			{
 | |
| 				// Set the font for the Continue Action Summary
 | |
| 				VE_Font pkFont = myProcedure.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.ContinuousActionSummaryData.Font; // uses font defined in the format or uses what is definced in BaseAll format
 | |
| 				if (_MyHelper.MyContActSteps.Count > 0)
 | |
| 					MyContActSummary = new ContinuousActionSummary(_MyHelper.MyContActSteps, pkFont);
 | |
| 			}
 | |
| 			_MyHelper = null;
 | |
| 			ProfileTimer.Pop(profileDepth);
 | |
| 			return outputFileName;
 | |
| 		}
 | |
| 
 | |
| 		public void InsertBlankPage(PdfContentByte cb)
 | |
| 		{
 | |
| 			_MyHelper.OnBlankPage = true;
 | |
| 			string baselinemsg = "==Insert Blank Page==";
 | |
| 			if (_BlankPageText != null && _BlankPageText != "")		// C2019-004: Allow user to define duplex blank page text
 | |
| 			{
 | |
| 				string bsfontfamily = MyItem.ActiveFormat.PlantFormat.FormatData.StepDataList[0].Font.Family;
 | |
| 				int bsfontsize = 26;
 | |
| 				iTextSharp.text.Font font = FontFactory.GetFont(bsfontfamily, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, bsfontsize, iTextSharp.text.Font.NORMAL, new iTextSharp.text.Color(PrintOverride.TextColor));
 | |
| 				PrintTextMessage(cb, _BlankPageText, _TextLayer, font);
 | |
| 				// B2019-019: Add the blank page message to the baseline output file.
 | |
| 				baselinemsg = string.Format("==Insert Blank Page With Message \"{0}\"==", _BlankPageText);
 | |
| 			}
 | |
| 			else
 | |
| 				cb.PdfDocument.Add(new iTextSharp.text.Table(1));
 | |
| 			NewPage();
 | |
| 			Volian.Base.Library.BaselineMetaFile.WriteLine(baselinemsg);
 | |
| 		}
 | |
| 
 | |
| 		private void SetupProperties(PdfDocument document, ProcedureInfo myProcedure)
 | |
| 		{
 | |
| 			document.AddTitle(string.Format("{0} {1}",myProcedure.DisplayNumber,myProcedure.DisplayText));
 | |
| 			document.AddSubject(myProcedure.SearchDVPath);
 | |
| 			document.AddCreator(string.Format("{0} {1}",Application.ProductName, Application.ProductVersion));
 | |
| 			document.AddAuthor(Volian.Base.Library.VlnSettings.UserID);
 | |
| 		}
 | |
| 		private Placekeeper _MyPlacekeeper = null;
 | |
| 
 | |
| 		public Placekeeper MyPlacekeeper
 | |
| 		{
 | |
| 			get { return _MyPlacekeeper; }
 | |
| 			set { _MyPlacekeeper = value; }
 | |
| 		}
 | |
| 
 | |
| 		private ContinuousActionSummary _MyContActSummary = null;
 | |
| 
 | |
| 		public ContinuousActionSummary MyContActSummary
 | |
| 		{
 | |
| 			get { return _MyContActSummary; }
 | |
| 			set { _MyContActSummary = value; }
 | |
| 		}
 | |
| 
 | |
| 		public void CreateWordDocPdf(PdfContentByte cb, SectionInfo mySection)
 | |
| 		{
 | |
| 			if (mySection.PageNumber == -1)			// If page num transition goes to a section, need the pagenumber of section.
 | |
| 			{
 | |
| 				if ((mySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DontCountFoldoutPgs) == E_DocStructStyle.DontCountFoldoutPgs)
 | |
| 					mySection.PageNumber = _MyHelper.CurrentPageNumberNoFoldouts;
 | |
| 				else
 | |
| 					mySection.PageNumber = _MyHelper.CurrentPageNumber;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if ((mySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DontCountFoldoutPgs) == E_DocStructStyle.DontCountFoldoutPgs)
 | |
| 					mySection.PageNumberNextPass = _MyHelper.CurrentPageNumberNoFoldouts;
 | |
| 				else
 | |
| 					mySection.PageNumberNextPass = _MyHelper.CurrentPageNumber;
 | |
| 			}
 | |
| 			int profileDepth = ProfileTimer.Push(">>>> CreateWordDocPdf");
 | |
| 			if (_MyHelper.MySection != mySection) // C2018-004 create meta file for baseline compares - assigning MySection again will reprocess the Page List
 | |
| 				_MyHelper.MySection = mySection;
 | |
| 			try
 | |
| 			{
 | |
| 				OnStatusChanged("Get Section", PromsPrinterStatusType.GetSection);
 | |
| 				int sectPageCount = 0;
 | |
| 				float locEndOfWordDoc = 0;
 | |
| 				float pdfSize = 0;
 | |
| 				using (PdfInfo myPdf = PdfInfo.Get(mySection,false))
 | |
| 				{
 | |
| 					if (myPdf == null) // B2017-218 Handle invalid word sections
 | |
| 					{
 | |
| 						cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED), 20);
 | |
| 						cb.SetTextMatrix(cb.PdfDocument.Left+200,cb.PdfDocument.Bottom+cb.PdfDocument.Top / 2);
 | |
| 						cb.ShowText("Word Section Invalid");
 | |
| 						// C2018-004 create meta file for baseline compares
 | |
| 						Volian.Base.Library.BaselineMetaFile.WriteLine("!!Word Section Invalid: ID {0} \"{1}\" \"{2}\"",mySection.ItemID, mySection.DisplayNumber, mySection.DisplayText);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						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 (this.MyReaderHelper != null)
 | |
| 					{
 | |
| 						bool doimport2 = true;
 | |
| 						PdfImportedPage fgPage = null;
 | |
| 						try
 | |
| 						{
 | |
| 							fgPage = this.MyReaderHelper.GetPage(mySection, ii + 1);
 | |
| 						}
 | |
| 						catch (Exception ex)
 | |
| 						{
 | |
| 							Console.WriteLine(ex);
 | |
| 							doimport2 = false;
 | |
| 						}
 | |
| 						OnStatusChanged("Read MSWord", PromsPrinterStatusType.ReadMSWord);
 | |
| 						if (doimport2)
 | |
| 						{
 | |
| 							if (((!didFoldout && _MyFoldoutReader.Count > 0) || mySection.MyProcedure.ProcHasSupInfoData) && cb.PdfWriter.CurrentPageNumber > 1 && 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
 | |
| 								InsertBlankPage(cb);
 | |
| 								//_MyLog.InfoFormat("NewPage 3 blank {0}", cb.PdfWriter.CurrentPageNumber);
 | |
| 							}
 | |
| 							float yoff = 0;
 | |
| 							if (_MyHelper.DidFirstPageDocStyle) yoff = origYoff - (float)mySection.MyDocStyle.Layout.TopMargin;
 | |
| 							// C2018-004 create meta file for baseline compares
 | |
| 							Volian.Base.Library.BaselineMetaFile.WriteLine("WD Height={0} Width={1} scPgCnt={2} locEnd={3} pdfSz={4} xOff={5} yOff={6} ScPgNum {7}", fgPage.Height, fgPage.Width, sectPageCount, locEndOfWordDoc, pdfSize, (float)(mySection.MyDocStyle.Layout.MSWordXAdj ?? 0.0), (float)(mySection.MyDocStyle.Layout.MSWordYAdj ?? 0.0) + yoff, pageNumber);
 | |
| 							AddImportedPageToLayer(cb.PdfWriter.DirectContent, _MSWordLayer, fgPage, (float)(mySection.MyDocStyle.Layout.MSWordXAdj ?? 0), (float)(mySection.MyDocStyle.Layout.MSWordYAdj ?? 0) + yoff);
 | |
| 							// B2019-102 Handle PDF Destinations for Word Sections
 | |
| 							if (ii == 0 && _MyHelper.MyPromsPrinter.SaveLinks)
 | |
| 							{
 | |
| 								ColumnText ct = new ColumnText(cb);
 | |
| 								iTextSharp.text.Font font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12, iTextSharp.text.Font.NORMAL, new iTextSharp.text.Color(PrintOverride.TextColor));
 | |
| 								Chunk chk = new Chunk(mySection.DisplayNumber, font);
 | |
| 								chk.SetLocalDestination(string.Format("ItemID={0}", mySection.ItemID));
 | |
| 								//Console.WriteLine("++++ ItemID={0}", mySection.ItemID);
 | |
| 								//float x1 = cb.PdfDocument.PageSize.Width / 2;
 | |
| 								//float y1 = cb.PdfDocument.PageSize.Height ; // 1.8f;
 | |
| 								float height = 12 * 1.5F;
 | |
| 								// B2019-102 Locate the chunk below the bottom of the page
 | |
| 								ct.SetSimpleColumn(0, -height, chk.GetWidthPoint() * 1.01F, -2*height );
 | |
| 								ct.AddElement(new Phrase(chk));
 | |
| 								cb.SetColorFill(new iTextSharp.text.Color(PrintOverride.TextColor));
 | |
| 								int status = ct.Go();
 | |
| 								if(status > 1)
 | |
| 									_MyLog.WarnFormat("\r\n.-.-.-. Failed to add a PDF destination for {0}", mySection.ShortPath);
 | |
| 							}
 | |
| 
 | |
| 							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);
 | |
| 								float adjMsgY = 0;
 | |
| 								if ((float)mySection.MyDocStyle.End.Flag < 0)		// Adjust this many lines down the page.
 | |
| 								{
 | |
| 									adjMsgY = (float)(-(float)mySection.MyDocStyle.End.Flag * vlnPrintObject.SixLinesPerInch);
 | |
| 									if (ylocation - adjMsgY > mySection.MyDocStyle.Layout.FooterLength) ylocation = ylocation - adjMsgY;
 | |
| 								}
 | |
| 								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, 200, 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;
 | |
| 			NewPage(ii == sectPageCount-1);		// 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)
 | |
| 			{
 | |
| 				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 = PDFPageSize.PaperSizePoints(myProcedure.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
 | |
| 			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, false); // add all of the marked sections and sub-sections to the table of contents
 | |
| 			if (textLayer != null) cb.EndLayer();
 | |
| 			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();
 | |
| 			VEPROMS.CSLA.Library.DisplayText toctxt = new VEPROMS.CSLA.Library.DisplayText(txt, tOfCData.Font, false);
 | |
| 			System.Drawing.Font myFont = toctxt.TextFont.WindowsFont;
 | |
| 			if (overrideFont != null)
 | |
| 			{
 | |
| 				toctxt = new VEPROMS.CSLA.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, bool didSubSecLineSpacing)
 | |
| 		{
 | |
| 			// 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;
 | |
| 			string lastTOCGroupHeading = "";
 | |
| 			if (ii.Sections != null)
 | |
| 			{
 | |
| 				int sectCnt = 0; // keep count of which section/sub-section we are processing
 | |
| 				bool doSubY = false;
 | |
| 				// C2018-004 create meta file for baseline compares
 | |
| 				Volian.Base.Library.BaselineMetaFile.WriteLine("TOC Ystart {0} LeftMar {1} ScNmPos {2} ScTtlPos {3} ScPgPos {4}", yPageStart, leftMargin, secNumPos, secTitlePos, secPagePos);
 | |
| 				foreach (SectionInfo mySection in ii.Sections)
 | |
| 				{
 | |
| 					sectCnt++;
 | |
| 					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")))
 | |
| 					{
 | |
| 						// 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 (didSubSecLineSpacing && sectCnt == 1 && indentOffset > 0) // processing first sub-section and we are indenting B2016-205
 | |
| 						{
 | |
| 							// processed last sub-section so use the main section line spacing (most times is double spaced)
 | |
| 							yLocation -= (float)(tOfC.TofCLineSpacingSub ?? 1) * vlnPrintObject.SixLinesPerInch;
 | |
| 							yLocation += (float)(tOfC.TofCLineSpacing ?? 1) * vlnPrintObject.SixLinesPerInch;
 | |
| 						}
 | |
| 						// The Group Title logic was added for V.C. Summer and Farley(new writer guide format)
 | |
| 						// It allows the user to enter a Table of Contents Grouping Title on the Section Property (under automation)
 | |
| 						// The grouping title will print if the same title wasn't last printed
 | |
| 						string tocGrpHeading = sc.Section_TOC_Group_Title; // returns a "" if no title was entered
 | |
| 						float yBottomMargin = yPageStart - (float)tocSection.MyDocStyle.Layout.PageLength + (2 * vlnPrintObject.SixLinesPerInch);
 | |
| 						bool doGroupHeading = false;
 | |
| 						if (tocGrpHeading != lastTOCGroupHeading && tocGrpHeading.Length > 0)
 | |
| 						{
 | |
| 							doGroupHeading = true;
 | |
| 							if (lastTOCGroupHeading != "")
 | |
| 								yLocation += vlnPrintObject.SixLinesPerInch;
 | |
| 							lastTOCGroupHeading = tocGrpHeading;
 | |
| 						}
 | |
| 						// 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.
 | |
| 						bool didGrp = false;
 | |
| 						string tmptxt = mySection.MyContent.Number == null || mySection.MyContent.Number == "" ? " " : mySection.DisplayNumber;// B2017-019 - process "<u>" in section number
 | |
| 						if (tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCRemoveGrpNameInSects
 | |
| 							&& tocGrpHeading.Length > 0 && tmptxt.ToUpper().Contains(tocGrpHeading))
 | |
| 						{
 | |
| 							tmptxt = tmptxt.Replace(tocGrpHeading, "");
 | |
| 							didGrp = true;
 | |
| 						}
 | |
| 						if (tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCRemoveGrpNameInSects
 | |
| 							&& lastTOCGroupHeading.Length > 0 && tmptxt.ToUpper().Contains(lastTOCGroupHeading))
 | |
| 						{
 | |
| 							tmptxt = tmptxt.Replace(lastTOCGroupHeading, "");
 | |
| 							didGrp = true;
 | |
| 						}
 | |
| 						string rtfText = GetRtfToC(tmptxt, tOfC);
 | |
| 						Paragraph myparagraphSecNum = vlnPrintObject.RtfToParagraph(rtfText);
 | |
| 						float width = 0;
 | |
| 						foreach (Chunk chkt in myparagraphSecNum.Chunks)
 | |
| 							width += chkt.GetWidthPoint();
 | |
| 						float numwidth = width;
 | |
| 						Rtf2Pdf.Offset = new PointF(0, 2.5F);
 | |
| 
 | |
| 						// 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;
 | |
| 
 | |
| 						// logic put in for V.C. Summer who wants to their auto table of contents to print "OPERATOR ACTIONS" (set in the format) instead of "Procedure Steps"
 | |
| 						// - note that Summer didn't want to change the section title because they want transition to say "procedure step" for the section title. 03/08/2016
 | |
| 						string tocSecTitle = mySection.FormattedDisplayText;// B2017-019 - process "<u>" in section title
 | |
| 						tocSecTitle= ConvertSpecialChars(tocSecTitle, ii.ActiveFormat.PlantFormat.FormatData); // B2019-172 process symbol characters
 | |
| 						if (tocSecTitle.ToUpper() == "PROCEDURE STEPS" && tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCProcedureStepsTitle != "")
 | |
|  							tocSecTitle = tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCProcedureStepsTitle;
 | |
| 
 | |
| 						// 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(tocSecTitle, tOfC, ovrFont);
 | |
| 						}
 | |
| 						else
 | |
| 							rtfText = GetRtfToC(tocSecTitle, tOfC);
 | |
| 						Paragraph myparagraphSecTitle = vlnPrintObject.RtfToParagraph(rtfText); // section title
 | |
| 						width = secPagePos - adjSecTitlePos - 6;
 | |
| 						float savTitleWid = width;
 | |
| 						// for South Texas Table of Contents
 | |
| 						// if there is no section number (we put a blank in tmptxt) then move the section title over to the section number position
 | |
| 						if (doGroupHeading) // see if the group title and the first item under it will fit on the page  B2016-216
 | |
| 						{
 | |
| 							VE_Font grpingFont = new VE_Font(tOfC.Font.Family, (int)tOfC.Font.Size, (E_Style)tOfC.Font.Style | E_Style.Underline, (float)tOfC.Font.CPI);
 | |
| 							string rtfGrpingText = GetRtfToC(tocGrpHeading, tOfC, grpingFont);
 | |
| 							Paragraph myparagraphGrpTitle = vlnPrintObject.RtfToParagraph(rtfGrpingText);
 | |
| 							float w = secPagePos - 6;
 | |
| 							int lnaftergroup = ((tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCLineSpacingSub ?? 0) > 0) ? 1 : 2;
 | |
| 							float yLocAfterGrpTitleAndFirstItem = yLocation + (lnaftergroup * vlnPrintObject.SixLinesPerInch) + vlnPrintObject.GetHeight(cb, myparagraphGrpTitle, string.Empty, w, false) + vlnPrintObject.GetHeight(cb, myparagraphSecTitle, string.Empty, savTitleWid, false);
 | |
| 							// if group heading and first item under it does not fit on the page, do a page break
 | |
| 							if ((yPageStart - yLocAfterGrpTitleAndFirstItem) < yBottomMargin)
 | |
| 							{
 | |
| 								NewPage();
 | |
| 								_MyHelper.ResetSvg();   // needed to reset so that PSNotFirst pagelist justify flag gets used for BGE
 | |
| 								yLocation = lastyLocation = 0;
 | |
| 							}
 | |
| 							//if (yLocation > 0) yLocation += vlnPrintObject.SixLinesPerInch;// commented out for B2016-200 // for two blank line between last TOC title and the new grouping title
 | |
| 							float rtnval = Rtf2Pdf.TextAt(cb, myparagraphGrpTitle, leftMargin + secNumPos, yPageStart - yLocation, w, height, "", yBottomMargin); // print the Group Title
 | |
| 							yLocation += vlnPrintObject.SixLinesPerInch; // for two blank line between last TOC title and the new grouping title - added for B2016-200
 | |
| 							yLocation += (lnaftergroup * vlnPrintObject.SixLinesPerInch); // new line
 | |
| 						}
 | |
| 						// Print the section title
 | |
| 						float retval = Rtf2Pdf.TextAt(cb, myparagraphSecTitle, leftMargin + ((tOfC.TofCSecNumPos == tOfC.TofCSecTitlePos && tmptxt.Equals(" "))? secNumPos : adjSecTitlePos), yPageStart - yLocation, width, height, "", yBottomMargin);
 | |
| 						if (retval == 0)		// couldn't fit, flags need for a page break.	
 | |
| 						{
 | |
| 							NewPage();
 | |
| 							_MyHelper.ResetSvg();   // needed to reset so that PSNotFirst pagelist justify flag gets used for BGE
 | |
| 							yLocation = lastyLocation = 0;
 | |
| 							retval = Rtf2Pdf.TextAt(cb, myparagraphSecTitle, 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, myparagraphSecNum, leftMargin + secNumPos + indentOffset, yPageStart - yLocation, numwidth * 1.3F, height, "", yBottomMargin);
 | |
| 
 | |
| 						//float lSpace = (float)(tOfC.TofCLineSpacing ?? 1) * 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.
 | |
| 						// Only do this if the title is not empty (the code was meant for if title spans more than a line)
 | |
| 						if (retval != ttlRetval && mySection.MyContent.Text != null && mySection.MyContent.Text != "") 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 myparagraphSecTitle.Chunks)
 | |
| 									width += chkt.GetWidthPoint();
 | |
| 
 | |
| 								// get height - if two lines high, need width of 2nd line for adding
 | |
| 								// space characters
 | |
| 								float heightTtl = vlnPrintObject.GetHeight(cb, myparagraphSecTitle, string.Empty, 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;
 | |
| 								// If the page number is Right justified, need less space characters ('.') so that page number
 | |
| 								// doesn't have the last space character overwriting the 1st digit:
 | |
| 								int endJust = (tOfC.TofCPageNumAlign.ToUpper() == "RIGHT") ? 18 : 6;
 | |
| 
 | |
| 								float endSpace = leftMargin + secPagePos - endJust;
 | |
| 								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); // out the leader dots
 | |
| 								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);
 | |
| 						}
 | |
| 						//If the format wants single spacing within subsections (2nd level and lower), then need to figure out
 | |
|  						// spacing (vcb1 table of contents)
 | |
| 						//bool dosuby = (((tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCLineSpacingSub ?? 1) > 0)
 | |
| 						//	&& (mySection.MyParent.IsSection && ((mySection.Sections != null && mySection.Sections.Count > 0) || (level > 0 && mySection.NextItem != null))))
 | |
| 						//	|| didGrp;
 | |
| 						doSubY = (((tocSection.ActiveFormat.PlantFormat.FormatData.SectData.AccSectionData.TableOfContentsData.TofCLineSpacingSub ?? 1) > 0)
 | |
| 							&& (mySection.MyParent.IsSection && (/* mySection.Sections == null && */ sectCnt < ii.Sections.Count))) // B2016-205
 | |
| 							|| didGrp;
 | |
| 						if (doSubY)
 | |
| 							yLocation += (float)(tOfC.TofCLineSpacingSub ?? 1) * vlnPrintObject.SixLinesPerInch;
 | |
| 						else
 | |
| 							yLocation += (float)(tOfC.TofCLineSpacing ?? 1) * vlnPrintObject.SixLinesPerInch;
 | |
| 					}
 | |
| 					float savYLoc = yLocation;
 | |
| 					yLocation = AddSectionToTOC(tocSection, mySection, tOfC, cb, yPageStart, yLocation, doSubY);
 | |
| 					if (savYLoc == yLocation) // nothing was outputted i.e. the subsections are not included on the TOC // B2016-205
 | |
| 					{
 | |
| 						if (doSubY && sectCnt == ii.Sections.Count)
 | |
| 						{
 | |
| 							// processed last sub-section so use the main section line spacing (most times is double spaced)
 | |
| 							yLocation -= (float)(tOfC.TofCLineSpacingSub ?? 1) * vlnPrintObject.SixLinesPerInch;
 | |
| 							yLocation += (float)(tOfC.TofCLineSpacing ?? 1) * vlnPrintObject.SixLinesPerInch;
 | |
| 						}
 | |
| 				}
 | |
| 				}
 | |
| 			}
 | |
| 			return yLocation;
 | |
| 		}
 | |
| 		// B2019-172 This will add the RTF font commands around the symbol characters
 | |
| 		//           This was copied for DisplaySearch and modified - added the FormatData parameter
 | |
| 		private string ConvertSpecialChars(string str, FormatData fmtData)
 | |
| 		{
 | |
| 			string rtnVal = str;
 | |
| 			rtnVal = rtnVal.Replace("\u00A0", @"\u160?"); //convert \u00A0 to a hard space (\u00A0 shows as a blank in the search text field)
 | |
| 			rtnVal = rtnVal.Replace("\n", @"\line "); //B2018-020 SQL content record has "\line " for the hard return
 | |
| 			// Bug fix B2014-057
 | |
| 			// if we are searching for a symbol character in all procedure sets MyDocVersion is null
 | |
| 			// when MyDocVersion is null, get the symbol list directly from the PROMS base format (BaseAll.xml)
 | |
| 			if (fmtData != null && fmtData.SymbolList != null)
 | |
| 			{
 | |
| 				SymbolList sl = fmtData.SymbolList;
 | |
| 				if (sl != null)
 | |
| 				{
 | |
| 					foreach (Symbol sym in sl)
 | |
| 					{
 | |
| 						string rplace = string.Format(sym.Unicode < 256 ? @"\'{0:X2}" : @"\u{0}?", sym.Unicode);  // bug fix B2014-057 we were not including the ? in the replace
 | |
| 						rtnVal = rtnVal.Replace(((char)sym.Unicode).ToString(), rplace);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return rtnVal;
 | |
| 		}
 | |
| 
 | |
| 		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, (tOfC.TofCPageNumAlign.ToUpper() == "RIGHT") ? Element.ALIGN_RIGHT : 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, iTextSharp.text.Font font)
 | |
| 		{
 | |
| 			if (textLayer != null) cb.BeginLayer(textLayer);
 | |
| 			float fontSize = font.Size;
 | |
| 			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; // 1.8f;
 | |
| 			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;
 | |
| 			if (SupInfoPrintType == E_SupInfoPrintType.DoPageBreaks)
 | |
| 			{
 | |
| 				section.StepSectPageBreaksForSupInfo.Clear();
 | |
| 				section.StepSectPageBreaks.Clear();
 | |
| 			}
 | |
| 			// 792: 72 * 11 inches - TopRow - Top is high value for 8.5x11 paper, 842 for A4 paper
 | |
| 			float _PointsPerPage = PDFPageSize.PaperSizePoints(myItemInfo.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
 | |
| 			float yTopMargin = _PointsPerPage - (float)myItemInfo.MyDocStyle.Layout.TopMargin;
 | |
| 			yTopMargin -= _MyHelper.AdjustTopMarginForMultiLinePageListItems;
 | |
| 			// the following line was modified to comment out the - 2 * SixLinesPerInch. this fixed a pagination problem with WCN EMG E-3.
 | |
| 			// The change mentioned above caused the bottom message to print without a line separating it from step text (if the text was long
 | |
| 			// enough to go to the bottom of page).  A fix for this problem, B2017-103, is to use a format variable to define
 | |
| 			// how many lines will go above the continue message.  It was done this way so that it fixes the format/data that the problem
 | |
| 			// was found in, i.e. Ginna Rev2 SAMG, SAG-3 step 7. This change won't affect other plants/formats but if the problem occurs
 | |
| 			// the format value can be used to adjust the location of bottom message.  However, this could adversely affect pagination and
 | |
| 			// each plant/format needs to be done on a case by base basis.
 | |
| 			float yBottomMargin = Math.Max(0, yTopMargin - (float)myItemInfo.MyDocStyle.Layout.PageLength - (myItemInfo.MyDocStyle.Continue.Bottom.LocAdj==null?0:(int)myItemInfo.MyDocStyle.Continue.Bottom.LocAdj));
 | |
| 			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);
 | |
| 					_MyHelper.IsWatermarkLandscape = true;			// B2019-145: watermark on landscape page
 | |
| 				}
 | |
| 			}
 | |
| 			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";
 | |
| 			//if (myParagraph.MyItemInfo.InList(15906))
 | |
| 			//{
 | |
| 			//	CPSGen myGen = new CPSGen(myParagraph);
 | |
| 			//	myGen.Generate("TestCPSGEN.xml");
 | |
| 			//}
 | |
| 			float localYPageStart = 0;
 | |
| 			float yPageStart = yTopMargin;
 | |
| 			if (myItemInfo.HasChildren || myItemInfo.MyDocVersion.DocVersionConfig.SelectedSlave > 0 || (myItemInfo.ActiveFormat.PlantFormat.FormatData.Express && myItemInfo.MyDocStyle.OptionalSectionContent))
 | |
| 			{
 | |
| 				// if there is supplemental information associated with this section... generate the pdf.  This pdf will be used to place
 | |
| 				// supplemental information on facing pages
 | |
|                 // B2017-267  Put in the DocStyle setting "AdjustTopMarginOnStepContinuePages" for Farley who uses the "PSOnlyFirst" in some of their pagelists so that a section title is printed only on the first page of the section.
 | |
|                 //            This will adjust the top margin when the section title is not printed on the other pages.
 | |
|                 yTopMargin += myItemInfo.MyDocStyle.AdjustTopMarginOnStepContinuePages;
 | |
| 				if (SupInfoPrintType == E_SupInfoPrintType.Merge && myParagraph.SupInfoSection != null && myParagraph.SupInfoSection.ChildrenBelow != null && myParagraph.SupInfoSection.ChildrenBelow.Count > 0)
 | |
| 					GenerateSuppInfoPdf(myParagraph.SupInfoSection, yTopMargin, yBottomMargin);
 | |
| 				localYPageStart = myParagraph.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin);
 | |
| 				if (myParagraph.MyPlaceKeeper != null)
 | |
| 					_MyHelper.MyPlacekeepers.Add(myParagraph.MyPlaceKeeper);  // add this step text to the PlaceKeeper (Calvert Cliffs)
 | |
| 				if (myParagraph.MyContAct != null)
 | |
| 					_MyHelper.MyContActSteps.Add(myParagraph.MyContAct); // add this step to the Continuous Action Summary
 | |
| 			}
 | |
| 			else if (!myItemInfo.MyDocStyle.OptionalSectionContent)
 | |
| 			{
 | |
| 				SectionInfo si = myItemInfo.ActiveSection as SectionInfo;
 | |
| 				if (si.IsSeparatePagination()) // Don't output this message for continuous sections
 | |
| 				{
 | |
| 					// This was causing overlap of this message with previous sections
 | |
| 					iTextSharp.text.Font font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 30, iTextSharp.text.Font.NORMAL, new iTextSharp.text.Color(PrintOverride.TextColor));
 | |
| 					PrintTextMessage(cb, "No Section Content", _TextLayer, font);
 | |
| 				}
 | |
| 			}
 | |
| 			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;
 | |
| 					// B2017-201 if si is null we need to get it via the ItemID
 | |
| 					if (si == null)
 | |
| 						si = SectionInfo.Get(nxtItem.ItemID); //ActiveSection 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;
 | |
| 				}
 | |
| 				NewPage(true);		// 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.BottomMessage.Count != 0)
 | |
| 				{
 | |
| 					_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);
 | |
| 			_MyHelper.IsWatermarkLandscape = false;
 | |
| 		}
 | |
| 
 | |
| 		private void GenerateSuppInfoPdf(vlnParagraph vlnParagraph, float yTopMargin, float yBottomMargin)
 | |
| 		{
 | |
| 			ReaderHelper savMyReaderHelper = MyReaderHelper;
 | |
| 			PdfContentByte savMyContentByte = MyContentByte;
 | |
| 			VlnSvgPageHelper savMyHelper = _MyHelper;
 | |
| 			if (SupInfoPdfPage == null) SupInfoPdfPage = new Dictionary<int, int>();
 | |
| 			else SupInfoPdfPage.Clear();
 | |
| 			string SupInfoPdfName = Volian.Base.Library.VlnSettings.TemporaryFolder + @"\SupInfo" + vlnParagraph.MyItemInfo.ItemID.ToString() + @".pdf";
 | |
| 			iTextSharp.text.Rectangle pageSize = PDFPageSize.UsePaperSize(MyItem.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
 | |
| 			PdfContentByte cb = OpenDoc(SupInfoPdfName, pageSize);
 | |
| 			if (cb == null) return;
 | |
| 			VlnSvgPageHelper myPageHelper = new VlnSvgPageHelper(vlnParagraph.MyItemInfo as SectionInfo, this, null, 0);
 | |
| 			cb.PdfWriter.PageEvent = myPageHelper;
 | |
| 			myPageHelper.AllowAllWatermarks = AllowAllWatermarks;
 | |
| 			myPageHelper.MyPdfWriter = cb.PdfWriter;
 | |
| 			myPageHelper.CreatingFoldoutPage = false;
 | |
| 			myPageHelper.CreatingSupInfoPage = true;
 | |
| 			myPageHelper.MyPdfContentByte = cb;
 | |
| 			myPageHelper.ChangeBarDefinition = MyChangeBarDefinition;
 | |
| 			float yPageStart = yTopMargin;
 | |
| 			vlnParagraph._yPageStartForSupInfo = yTopMargin;
 | |
| 			SupInfoAjustGroupings(vlnParagraph,cb);
 | |
| 			SupInfoPrintType = E_SupInfoPrintType.SupInfoPdfPrint;
 | |
| 			vlnParagraph.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin);
 | |
| 			SupInfoPrintType = E_SupInfoPrintType.Merge;
 | |
| 			try
 | |
| 			{
 | |
| 				cb.PdfDocument.Close();
 | |
| 				cb = null;
 | |
| 			}
 | |
| 			catch (Exception ex)
 | |
| 			{
 | |
| 				Console.WriteLine("{0} - {1}", ex.GetType().Name, ex.Message);
 | |
| 			}
 | |
| 			_MyHelper = savMyHelper;
 | |
| 			MyContentByte = savMyContentByte;
 | |
| 			MyReaderHelper = savMyReaderHelper;
 | |
| 		}
 | |
| 		#region ShrinkSupInfoGroupAtATime
 | |
| 		private Dictionary<float, float> _AdjustForParagraphShrinkage;
 | |
| 		private float _LastOffset;
 | |
| 		private float _LastBottom;
 | |
| 		/// <summary>
 | |
| 		/// Adjust the font size so that the Supplemental Information will fit on a single page.
 | |
| 		/// </summary>
 | |
| 		/// <param name="vlnParagraph">supinfo paragraphs</param>
 | |
| 		/// <param name="cb">pdfcontentbyte</param>
 | |
| 		private void SupInfoAjustGroupings(vlnParagraph vlnParagraph, PdfContentByte cb)
 | |
| 		{
 | |
| 			// Get groups of SupInfo paragraphs
 | |
| 			List<List<vlnParagraph>> supInfoGroups = FindSupInfoGroups(vlnParagraph);
 | |
| 			float pageLength = (float)vlnParagraph.MyItemInfo.MyDocStyle.Layout.PageLength;
 | |
| 			// Process Each Group of SupInfo paragraphs 
 | |
| 			foreach (List<vlnParagraph> grp in supInfoGroups)
 | |
| 			{
 | |
| 				// Initialize font decrement
 | |
| 				float decrement = 2f;
 | |
| 				float fontSize = grp[0].IParagraph.Leading; // current font size
 | |
| 				float mpglen = MeasureSupInfoGroupLength(grp, cb,pageLength); // Measure the length of the group of supinfo paragraphs
 | |
| 				// If the group does not fit on a page then reduce the font size
 | |
| 				if (mpglen > pageLength)
 | |
| 				{
 | |
| 					float newFontSize=fontSize;
 | |
| 					// reduce the font size by _Decrement until the entire grouping fits on one page
 | |
| 					while (mpglen > pageLength) // While the measured supinfo group length is greatere than the page length
 | |
| 					{
 | |
| 						newFontSize = fontSize - decrement;
 | |
| 						float scaler = newFontSize / fontSize;// Calculate the reduction 
 | |
| 						ReduceSupInfoGroupFontSize(grp, scaler, cb); // Apply the smaller font size
 | |
| 						fontSize = newFontSize; // adjust the base font size
 | |
| 						mpglen = MeasureSupInfoGroupLength(grp, cb, pageLength);// Measure the length of the group of supinfo paragraphs
 | |
| 					}
 | |
| 					// Binary Search to find proper font size within .1
 | |
| 					while (decrement > .1f)
 | |
| 					{
 | |
| 						decrement = decrement / 2f; //Reduce the decrement by half
 | |
| 						if (mpglen > pageLength) // If the measured length is too big
 | |
| 							newFontSize -= decrement;// Reduce the font size
 | |
| 						else
 | |
| 							newFontSize += decrement;//Otherwise increase the font size
 | |
| 						float scaler = newFontSize / fontSize;// Calculate the reduction
 | |
| 						ReduceSupInfoGroupFontSize(grp, scaler, cb);// apply the new font size
 | |
| 						fontSize = newFontSize;// adjust the base font size
 | |
| 						mpglen = MeasureSupInfoGroupLength(grp, cb, pageLength);// Measure the length of the group of supinfo paragraphs
 | |
| 					}
 | |
| 					if (mpglen > pageLength) //If the measured lenght is greater than the page length reduce the font size
 | |
| 					{
 | |
| 						newFontSize -= decrement;// Reduce the font size
 | |
| 						float scaler = newFontSize / fontSize;// Calculate the reduction
 | |
| 						ReduceSupInfoGroupFontSize(grp, scaler, cb);// apply the new font size
 | |
| 						fontSize = newFontSize;// adjust the base font size
 | |
| 						mpglen = MeasureSupInfoGroupLength(grp, cb, pageLength);// Measure the length of the group of supinfo paragraphs
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Method to apply a multiplier to the font size to a group of supinfo paragraphs
 | |
| 		/// </summary>
 | |
| 		/// <param name="grp">group of SupInfo paragraphs</param>
 | |
| 		/// <param name="scaler">multiplier for font size</param>
 | |
| 		/// <param name="cb">The PDFContentByte which is needed to calculate the adjusted the paragraph height</param>
 | |
| 		private void ReduceSupInfoGroupFontSize(List<vlnParagraph> grp, float scaler, PdfContentByte cb)
 | |
| 		{
 | |
| 			foreach (vlnParagraph pg in grp) // For each paragraph and children apply the scaler
 | |
| 			{
 | |
| 				// When adjusting the font size if the change causes the paragraph to change due to the number of characters
 | |
| 				// per line these changes will impact the paragraphs below the affected paragraph
 | |
| 				// This is kept in a dictionary.  The key is the vertical offset to the affected paragraph.
 | |
| 				// The value is the impact on the paragraph height.
 | |
| 				_AdjustForParagraphShrinkage = new Dictionary<float, float>();
 | |
| 				// Apply the scaler to each paragraph
 | |
| 				ReduceSupInfoGroupFontSize(pg, scaler, cb);
 | |
| 			}
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Method to apply a multiplier to the font size to a supinfo paragraph and children
 | |
| 		/// </summary>
 | |
| 		/// <param name="pg">supinfo paragraph</param>
 | |
| 		/// <param name="scaler">font multiplier</param>
 | |
| 		/// <param name="cb">pdfcontentbyte</param>
 | |
| 		private void ReduceSupInfoGroupFontSize(vlnParagraph pg, float scaler, PdfContentByte cb)
 | |
| 		{
 | |
| 			float hBefore = pg.Height;// Save initial paragraph height
 | |
| 			AdjustSupInfoTable(pg, scaler,cb);
 | |
| 				NewSupInfoFixChunks(pg, scaler);// Apply multiplier to font size
 | |
| 				pg.IParagraph.Leading = scaler * pg.IParagraph.Leading; // Adjust leading (line spacing)
 | |
| 			// B2017-112: Don't do the font size change if images.
 | |
| 			// B2017-116: Don;t do the font size change for RTF Raw
 | |
| 				if (pg.ImageText == null && !pg.MyItemInfo.IsRtfRaw)
 | |
| 				{
 | |
| 					float hAfter = pg.GetParagraphHeight(cb, pg.IParagraph, "", pg.Width); // Calculate new paragraph height
 | |
| 					pg.Height = hAfter; // Save new Height;
 | |
| 					pg.YBottomMost += hAfter - hBefore; // Adjust YbottomMost for font size and leading
 | |
| 					float hleading = hBefore * scaler; // Calcuate leading change
 | |
| 					// If the change in font size effects the paragraph height due to word wrapping save the impact to adjust 
 | |
| 					// Offsets below
 | |
| 					if ((hleading > hAfter + 1 && scaler < 1f) || (hleading < hAfter + 1 && scaler > 1f))
 | |
| 					{
 | |
| 						if (!_AdjustForParagraphShrinkage.ContainsKey(pg.YOffset))
 | |
| 						{
 | |
| 							_AdjustForParagraphShrinkage.Add(pg.YOffset, hleading - hAfter);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				else  // Adjust the Image Size B2017-112 And B2017-116
 | |
| 				{
 | |
| 					pg.ImageScaler *= scaler;
 | |
| 					pg.Height *= scaler;
 | |
| 					pg.Width *= scaler;
 | |
| 				}
 | |
| 				float yoBefore = pg.YOffset;// Save the offset before
 | |
| 				float yoAfter = pg.YOffset = NewSupInfoFixOffset(pg, scaler);// Calculate the offset after
 | |
| 				pg.YBottomMost += yoAfter - yoBefore;// Adjust YbottomMost for changes to yOffset
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenAbove)// Process Children Above
 | |
| 				ReduceSupInfoGroupFontSize(cpg, scaler, cb);
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenBelow)// Process Children Below
 | |
| 				ReduceSupInfoGroupFontSize(cpg, scaler, cb);
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenLeft)// Process Children Left
 | |
| 				ReduceSupInfoGroupFontSize(cpg, scaler, cb);
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenRight)// Process Children Right
 | |
| 				ReduceSupInfoGroupFontSize(cpg, scaler, cb);
 | |
| 			foreach (vlnPrintObject po in pg.PartsAbove) // Process Parts Above (headers)
 | |
| 				NewSupInfoFixParts(po, scaler);
 | |
| 			foreach (vlnPrintObject po in pg.PartsBelow) // Process Parts Below (unknown)
 | |
| 				NewSupInfoFixParts(po, scaler);
 | |
| 			foreach (vlnPrintObject po in pg.PartsLeft) // Process Parts Left (Tabs)
 | |
| 				NewSupInfoFixParts(po, scaler);
 | |
| 			foreach (vlnPrintObject po in pg.PartsRight) // Process Parts Right (unknown)
 | |
| 				NewSupInfoFixParts(po, scaler);
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Adjust the Table Fonts to shrink the sup info text
 | |
| 		/// </summary>
 | |
| 		/// <param name="pg">vlnParagraph potentially containing a vlnTable</param>
 | |
| 		/// <param name="scaler">multiplier</param>
 | |
| 		/// <param name="cb">pdfContentByte</param>
 | |
| 		private void AdjustSupInfoTable(vlnParagraph pg, float scaler, PdfContentByte cb)
 | |
| 		{
 | |
| 			// Adjust the table if it exists
 | |
| 			if (pg.MyGrid != null)
 | |
| 			{
 | |
| 				// Create lists of heights before and after shrinking sup info
 | |
| 				Dictionary<int, float> beforeRowHeight = new Dictionary<int, float>();
 | |
| 				Dictionary<int, float> afterRowHeight = new Dictionary<int, float>();
 | |
| 				for (int i = 0; i < pg.MyGrid.RowTop.GetLength(0)-1; i++)
 | |
| 				{
 | |
| 					beforeRowHeight.Add(i, scaler * (pg.MyGrid.RowTop[i+1] - pg.MyGrid.RowTop[i]));
 | |
| 					afterRowHeight.Add(i, 0);
 | |
| 				}
 | |
| 				// Adjust font size for each cell.
 | |
| 				foreach (vlnCell cell in pg.MyGrid.MyCells)
 | |
| 				{
 | |
| 					float x = cell.MyTable.ColLeft[cell.c1];
 | |
| 					float w = cell.MyTable.ColLeft[cell.c2 + 1] - x;
 | |
| 					float hBefore = scaler * pg.GetParagraphHeight(cb,cell.MyPara,"",w);
 | |
| 					foreach (Chunk chk in cell.MyPara.Chunks)
 | |
| 						chk.Font.Size = scaler * chk.Font.Size;
 | |
| 					float hAfter = 1.075F * pg.GetParagraphHeight(cb,cell.MyPara,"",w);// 1.075 is a magic number that worked for Ginna.  Otherwise decenders overlapped the bottom line of the cell.
 | |
| 					cell.HContent = hAfter;
 | |
| 					// Save tthe height after adjusting the font size to account for changes in word wrap.
 | |
| 					afterRowHeight[cell.r1]=Math.Max(hAfter,afterRowHeight[cell.r1]);
 | |
| 				}
 | |
| 				for (int i = 0; i < pg.MyGrid.RowTop.GetLength(0)-1; i++)
 | |
| 				{
 | |
| 					pg.MyGrid.RowTop[i+1] = scaler * pg.MyGrid.RowTop[i+1];// Adjust for leading
 | |
| 					pg.MyGrid.RowTop[i+1] += (afterRowHeight[i]-beforeRowHeight[i]); //Adjust for word wrapping
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Adjust YOffset for Print Objects 
 | |
| 		/// </summary>
 | |
| 		/// <param name="vpo">Print Object (tab, paragraph, etc.)</param>
 | |
| 		/// <param name="scaler">multiplier</param>
 | |
| 		/// <returns></returns>
 | |
| 		private float NewSupInfoFixOffset(vlnPrintObject vpo, float scaler)
 | |
| 		{
 | |
| 			float fixOffSet = 0;
 | |
| 			// determine impact of paragraphs above due to word-wrap
 | |
| 			foreach (float off in _AdjustForParagraphShrinkage.Keys)
 | |
| 				if (off < vpo.YOffset)
 | |
| 					fixOffSet += _AdjustForParagraphShrinkage[off];
 | |
| 			// combine this impact with the scaler on the YOffset
 | |
| 			return scaler * vpo.YOffset - fixOffSet;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Adjust Font Size and offset for Parts
 | |
| 		/// </summary>
 | |
| 		/// <param name="po">PrintObject</param>
 | |
| 		/// <param name="scaler">Multiplier</param>
 | |
| 		private void NewSupInfoFixParts(vlnPrintObject po, float scaler)
 | |
| 		{
 | |
| 			if (po.IParagraph == null) return;  // B2017-132 check for NULL reference (happend printing Bryon SAMGS with sup info pages)
 | |
| 			// Adjust the font size by the multiplier
 | |
| 			foreach (Chunk chk in po.IParagraph.Chunks)
 | |
| 				chk.Font.Size = scaler * chk.Font.Size;
 | |
| 			po.IParagraph.Leading = scaler * po.IParagraph.Leading;// Apply the multiplier to the leading (line spacing)
 | |
| 			po.YOffset = NewSupInfoFixOffset(po,scaler);// Adjust the YOffset
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Adjust the Font Size
 | |
| 		/// </summary>
 | |
| 		/// <param name="vlnParagraph">Paragraph</param>
 | |
| 		/// <param name="scaler">Multiplier</param>
 | |
| 		private void NewSupInfoFixChunks(vlnParagraph vlnParagraph, float scaler)
 | |
| 		{
 | |
| 			// Adjust the font size by the multiplier
 | |
| 			foreach (Chunk chk in vlnParagraph.IParagraph.Chunks)
 | |
| 				chk.Font.Size = scaler * chk.Font.Size;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Measure the Length of the Group
 | |
| 		/// </summary>
 | |
| 		/// <param name="grp">Group of SupInfo Paragraphs</param>
 | |
| 		/// <param name="cb">pdfContentByte</param>
 | |
| 		/// <param name="pagelength">Page Length</param>
 | |
| 		/// <returns>Length</returns>
 | |
| 		private float MeasureSupInfoGroupLength(List<vlnParagraph> grp, PdfContentByte cb, float pagelength)
 | |
| 		{
 | |
| 			_LastBottom = 0;
 | |
| 			_LastOffset = 12;// 24; // account for the Sup Info header (two lines)
 | |
| 			float fontSize = grp[0].IParagraph.Leading; // current font size
 | |
| 			// For each SupInfo Paragraph calculate length
 | |
| 			foreach (vlnParagraph pg in grp)
 | |
| 			{
 | |
| 				MeasureSupInfoGroupLength(pg, cb);// Measure a SupInfo Paragraph and children
 | |
| 				_LastOffset += _LastBottom;
 | |
| 				_LastBottom = 0;
 | |
| 			}
 | |
| 			//Console.WriteLine("MeasureSupInfoGroupLength {0} {1} {2} {3}", grp[0].MyItemInfo.ItemID, _LastOffset, fontSize, pagelength);
 | |
| 			return _LastOffset;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Measure the height of a supinfo paragraph and children
 | |
| 		/// </summary>
 | |
| 		/// <param name="pg">SupInfo paragraph</param>
 | |
| 		/// <param name="cb">pdfContentByte</param>
 | |
| 		private void MeasureSupInfoGroupLength(vlnParagraph pg, PdfContentByte cb)
 | |
| 		{
 | |
| 			_LastBottom = pg.YBottomMost;
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenAbove) // Measure Children Above
 | |
| 				MeasureSupInfoGroupLength(cpg, cb);
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenBelow) // Measure Children Below
 | |
| 				MeasureSupInfoGroupLength(cpg, cb);
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenLeft) // Measure Children Left
 | |
| 				MeasureSupInfoGroupLength(cpg, cb);
 | |
| 			foreach (vlnParagraph cpg in pg.ChildrenRight) // Measure Children Right
 | |
| 				MeasureSupInfoGroupLength(cpg, cb);
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Find Groups of SupInfo Paragraphs
 | |
| 		/// </summary>
 | |
| 		/// <param name="vlnParagraph">SupInfo Paragraph</param>
 | |
| 		/// <returns>List of supinfo paragraph groups</returns>
 | |
| 		private List<List<vlnParagraph>> FindSupInfoGroups(vlnParagraph vlnParagraph)
 | |
| 		{
 | |
| 			List<List<vlnParagraph>> supInfoGroups;
 | |
| 			supInfoGroups = new List<List<vlnParagraph>>();
 | |
| 			foreach (vlnParagraph pg in vlnParagraph.ChildrenBelow)
 | |
| 			{
 | |
| 				SectionInfo supInfoSect = (pg.MyItemInfo.ActiveSection != null) ? pg.MyItemInfo.ActiveSection as SectionInfo : null;
 | |
| 				if (supInfoSect != null && supInfoSect.StepSectPageBreaksForSupInfo != null && supInfoSect.StepSectPageBreaksForSupInfo.Contains(pg.MyItemInfo.ItemID)) // C2018-003 fixed use of getting the active section
 | |
| 					supInfoGroups.Add(new List<vlnParagraph>()); // add a grouping since a page break exists
 | |
| 				if (supInfoGroups.Count == 0)
 | |
| 				{
 | |
| 					supInfoGroups.Add(new List<vlnParagraph>()); // add a grouping since a page break exists
 | |
| 					_MyLog.WarnFormat("SupInfo Print Groups: {0}, {1}", pg.MyItemInfo.ItemID, pg.MyItemInfo.ShortPath);
 | |
| 				}
 | |
| 				supInfoGroups[supInfoGroups.Count - 1].Add(pg); // add paragraph to the last grouping
 | |
| 			}
 | |
| 				return supInfoGroups;
 | |
| 		}
 | |
| 		#endregion //ShrinkSupInfoGroupAtATime
 | |
| 
 | |
| 		
 | |
| 		public void DoSupInfoPage(PdfContentByte cb, string str, PdfLayer textLayer, VlnSvgPageHelper myPageHelper, int itemid, bool insertBlankPages)
 | |
| 		{
 | |
| 			// see if the ID is in the facing page pdf - if so, get the page:
 | |
| 			if (SupInfoPdfPage == null || SupInfoPdfPage.Count < 1) return;
 | |
| 			int getpage = 0;
 | |
| 			if (SupInfoPdfPage.ContainsKey(itemid)) getpage = SupInfoPdfPage[itemid];
 | |
| 			if (getpage < 0)
 | |
| 			{
 | |
| 				InsertBlankPage(cb);
 | |
| 				return;
 | |
| 			}
 | |
| 			PdfImportedPage sipage = null;
 | |
| 			try
 | |
| 			{
 | |
| 				string SupInfoPdfName = Volian.Base.Library.VlnSettings.TemporaryFolder + @"\SupInfo" + myPageHelper.MySection.ItemID.ToString() + @".pdf";
 | |
| 				PdfReader pdfreader = new PdfReader(SupInfoPdfName);
 | |
| 				sipage = cb.PdfWriter.GetImportedPage(pdfreader, getpage+1);
 | |
| 				AddImportedPageToLayer(cb.PdfWriter.DirectContent, textLayer, sipage, 0, 0);
 | |
| 				DoingFacingPage = true;
 | |
| 				myPageHelper.ResetSvg();
 | |
| 				NewPage();
 | |
| 				DoingFacingPage = false;
 | |
| 				myPageHelper.ResetSvg();
 | |
| 				pdfreader.Close();
 | |
| 			}
 | |
| 			catch (Exception ex)
 | |
| 			{
 | |
| 				Console.WriteLine(ex);
 | |
| 			}
 | |
| 		}
 | |
| 		public 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.
 | |
| 				InsertBlankPage(cb);
 | |
| 			}
 | |
| 
 | |
| 			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);
 | |
| 					foreach (iTextSharp.text.pdf.PdfAnnotation.PdfImportedLink il in _MyFoldoutReader[foldoutindx].GetLinks(1))
 | |
| 					{
 | |
| 						if(!il.IsInternal() )
 | |
| 							cb.PdfWriter.AddAnnotation(il.CreateAnnotation(cb.PdfWriter));
 | |
| 					}
 | |
| 			
 | |
| 					if (DebugPagination.IsOpen) DebugPagination.WriteLine("{0:D6},'{1}',{2}",
 | |
| 					myPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, "Foldout", 1);
 | |
| 					//if (BaselineMetaFile.IsOpen) BaselineMetaFile.WriteLine("!! {0:D6},'{1}',{2}",
 | |
| 					//myPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, "Foldout", 1);
 | |
| 				}
 | |
| 			}
 | |
| 			//_MyLog.InfoFormat("DoFoldoutPage {0}", cb.PdfWriter.CurrentPageNumber);
 | |
| 			//PrintTextMessage(cb, "Foldout for: " + str, textLayer);
 | |
| 			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 ReaderHelper
 | |
| 	{
 | |
| 		private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 | |
| 		private Dictionary<string, PdfImportedPage> dicPage = new Dictionary<string, PdfImportedPage>();
 | |
| 		private Dictionary<string, iTextSharp.text.Rectangle> dicSize = new Dictionary<string, iTextSharp.text.Rectangle>();
 | |
| 		private PromsPrinter _MyPromsPrinter;
 | |
| 		public PromsPrinter MyPromsPrinter
 | |
| 		{
 | |
| 			get { return _MyPromsPrinter; }
 | |
| 			set { _MyPromsPrinter = value; }
 | |
| 		}
 | |
| 		private SectionInfo _MySectionInfo;
 | |
| 		public SectionInfo MySectionInfo
 | |
| 		{
 | |
| 			get { return _MySectionInfo; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_MySectionInfo == null || value.ItemID != _MySectionInfo.ItemID)
 | |
| 				{
 | |
| 					_MySectionInfo = value;
 | |
| 					//MyPdfFile = _MyPromsPrinter.BuildMSWordPDF(MySectionInfo);
 | |
| 					//try
 | |
| 					//{
 | |
| 					//  MyReader = MyPdfFile != null ? new PdfReader(MyPdfFile) : null;
 | |
| 					//  string key = string.Empty;
 | |
| 					//  for (int i = 1; i <= MyReader.NumberOfPages; i++)
 | |
| 					//  {
 | |
| 					//    key = string.Format("{0}.{1}", MySectionInfo.ItemID, i);
 | |
| 					//    dicPage.Add(key, MyPromsPrinter.MyContentByte.PdfWriter.GetImportedPage(MyReader, i));
 | |
| 					//    dicSize.Add(key, MyReader.GetPageSizeWithRotation(i));
 | |
| 					//  }
 | |
| 					//}
 | |
| 					//catch (Exception ex)
 | |
| 					//{
 | |
| 					//  MyReader = null;
 | |
| 					//}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		private string _MyPdfFile;
 | |
| 		public string MyPdfFile
 | |
| 		{
 | |
| 			get { return _MyPdfFile; }
 | |
| 			set { _MyPdfFile = value; }
 | |
| 		}
 | |
| 		private int _DocID;
 | |
| 		public int DocID
 | |
| 		{
 | |
| 			get { return _DocID; }
 | |
| 			set { _DocID = value; }
 | |
| 		}
 | |
| 		private PdfReader _MyReader;
 | |
| 		public PdfReader MyReader
 | |
| 		{
 | |
| 			get { return _MyReader; }
 | |
| 			set { _MyReader = value; }
 | |
| 		}
 | |
| 		public ReaderHelper(PromsPrinter pp)
 | |
| 		{
 | |
| 			MyPromsPrinter = pp;
 | |
| 			//this.LoadTree(pp.MyItem);
 | |
| 		}
 | |
| 		public PdfImportedPage GetPage(SectionInfo sectInfo, int pageNumber)
 | |
| 		{
 | |
| 			string key = string.Format("{0}.{1}", sectInfo.ItemID, pageNumber);
 | |
| 			return dicPage[key];
 | |
| 		}
 | |
| 		public iTextSharp.text.Rectangle GetSize(SectionInfo sectInfo, int pageNumber)
 | |
| 		{
 | |
| 			string key = string.Format("{0}.{1}", sectInfo.ItemID, pageNumber);
 | |
| 			if(dicSize.ContainsKey(key))
 | |
| 				return dicSize[key];
 | |
| 			return PDFPageSize.UsePaperSize(sectInfo.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
 | |
| 		}
 | |
| 		public void LoadTree(ItemInfo ii)
 | |
| 		{
 | |
| 			dicPage = new Dictionary<string, PdfImportedPage>();
 | |
| 			dicSize = new Dictionary<string, iTextSharp.text.Rectangle>();
 | |
| 				LoadSectionTree(ii);
 | |
| 		}
 | |
| 		private void LoadSectionTree(ItemInfo ii)
 | |
| 		{
 | |
| 			foreach (SectionInfo si in ii.Sections)
 | |
| 			{
 | |
| 				if (si.IsStepSection)
 | |
| 				{
 | |
| 					if(si.Sections != null)LoadSectionTree(si);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					MyPdfFile = _MyPromsPrinter.BuildMSWordPDF(si);
 | |
| 					if (MyPdfFile != null)
 | |
| 					{
 | |
| 						try
 | |
| 						{
 | |
| 							FileInfo fi = new FileInfo(MyPdfFile);
 | |
| 							if (fi.Length == 0 ) // B2017-218 Handle invalid word sections
 | |
| 							{
 | |
| 								if(!PromsPrinter.BaselineTesting) //B2018-071 Output a message box unless baseline testing is being performed.
 | |
| 								MessageBox.Show(si.DisplayNumber + " " + si.DisplayText + " is not valid", "Invalid Word Section", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
 | |
| 								return;
 | |
| 							}
 | |
| 							MyReader = MyPdfFile != null ? new PdfReader(MyPdfFile) : null;
 | |
| 							string key = string.Empty;
 | |
| 							for (int i = 1; i <= MyReader.NumberOfPages; i++)
 | |
| 							{
 | |
| 								key = string.Format("{0}.{1}", si.ItemID, i);
 | |
| 								dicPage.Add(key, MyPromsPrinter.MyContentByte.PdfWriter.GetImportedPage(MyReader, i));
 | |
| 								iTextSharp.text.Rectangle rectgl = MyReader.GetPageSizeWithRotation(i);
 | |
| 								// If the word page is set to landscape, but the document style is not landscape, then flip the height and width (put back to portrait)
 | |
| 								if (!((si.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_WordContentLandscaped) == E_DocStructStyle.DSS_WordContentLandscaped) && rectgl.Height < rectgl.Width)
 | |
| 									rectgl = new iTextSharp.text.Rectangle(rectgl.Height, rectgl.Width);
 | |
| 								dicSize.Add(key, rectgl);
 | |
| 									//dicSize.Add(key, MyReader.GetPageSizeWithRotation(i));
 | |
| 							}
 | |
| 						}
 | |
| 						catch (Exception ex)
 | |
| 						{
 | |
| 							if (_MyPromsPrinter.DocReplace == null)
 | |
| 							MessageBox.Show(ex.Message, ex.GetType().FullName, MessageBoxButtons.OK, MessageBoxIcon.Error);
 | |
| 							_MyLog.Warn(string.Format("Error in LoadSectionTree [{0}],{1}.{2}", si.ItemID, si.DisplayNumber, si.DisplayText), ex);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	//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; }
 | |
| 	//  }
 | |
| 	//}
 | |
| }
 |