Add a Using statement when we temporarily create a RichTextBox to ensure the Window Handle is free’d. Also use method from VE_Font to get a font reference (uses dictionary so redundant Window Handles are not created) B2017-117
		
			
				
	
	
		
			394 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			394 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Text;
 | 
						|
using System.Drawing;
 | 
						|
using LBWordLibrary;
 | 
						|
using VEPROMS.CSLA.Library;
 | 
						|
using System.Text.RegularExpressions;
 | 
						|
 | 
						|
namespace Volian.Print.Library
 | 
						|
{
 | 
						|
	public class Placekeeper : IDisposable
 | 
						|
	{
 | 
						|
		private LBApplicationClass _WordApp;
 | 
						|
		private LBDocumentClass _WordDoc;
 | 
						|
		private LBSelection _WordSel;
 | 
						|
		private LBTable _WordTbl;
 | 
						|
		private const string TheQuickBrownFox = "The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.";
 | 
						|
		private VE_Font _pkFont;
 | 
						|
		public Placekeeper()
 | 
						|
		{
 | 
						|
			_WordApp = new LBApplicationClass();
 | 
						|
			_WordDoc = _WordApp.Documents.Add();
 | 
						|
			_WordSel = _WordApp.Selection;
 | 
						|
			_pkFont = new VE_Font("Arial", 11, E_Style.None, 12); // Calvert uses Arial for their Placekeepers.
 | 
						|
		}
 | 
						|
		public void Visible()
 | 
						|
		{
 | 
						|
			_WordApp.Visible = true;
 | 
						|
			_WordApp.Activate();
 | 
						|
		}
 | 
						|
		//public Placekeeper(pkParagraph myPlacekeeper)
 | 
						|
		//{
 | 
						|
		//  _WordApp = new LBApplicationClass();
 | 
						|
		//  _WordDoc = _WordApp.Documents.Add();
 | 
						|
		//  _WordSel = _WordApp.Selection;
 | 
						|
		//  _WordApp.Visible = true;
 | 
						|
		//  AddTable();
 | 
						|
		//  AddHeader();
 | 
						|
		//  AddSectionHeader(myPlacekeeper.MyParagraph.MyItemInfo.DisplayNumber, myPlacekeeper.MyParagraph.MyItemInfo.DisplayText);
 | 
						|
		//  foreach (pkParagraph pgh in myPlacekeeper.MyChildren)
 | 
						|
		//  {
 | 
						|
		//    AddHighLevelStep(pgh.MyParagraph.MyItemInfo.MyTab.CleanText, pgh.MyParagraph.MyItemInfo.DisplayText, pgh.MyParagraph.MyItemInfo.FormatStepType==9 ? "C" : "", pgh.MyParagraph.MyItemInfo.PageNumber.ToString());
 | 
						|
		//    if (pgh.MyChildren.Count > 0)
 | 
						|
		//    {
 | 
						|
		//      StartSubStep();
 | 
						|
		//      foreach (pkParagraph cpgh in pgh.MyChildren)
 | 
						|
		//      {
 | 
						|
		//        ContinueSubStep(cpgh.MyParagraph.MyItemInfo.DisplayText, 1);
 | 
						|
		//        foreach (pkParagraph ccpgh in cpgh.MyChildren)
 | 
						|
		//          ContinueSubStep(ccpgh.MyParagraph.MyItemInfo.DisplayText, 2);
 | 
						|
		//      }
 | 
						|
		//      FinishSubstep("", "");
 | 
						|
		//    }
 | 
						|
		//  }
 | 
						|
		//}
 | 
						|
		public Placekeeper(pkParagraphs myPlacekeepers, VE_Font pkFont)
 | 
						|
		{
 | 
						|
			_WordApp = new LBApplicationClass();
 | 
						|
			_WordDoc = _WordApp.Documents.Add();
 | 
						|
			_WordSel = _WordApp.Selection;
 | 
						|
			//_WordApp.Visible = true;
 | 
						|
			_pkFont = pkFont;
 | 
						|
			AddTable();
 | 
						|
			AddHeader();
 | 
						|
			foreach (pkParagraph myPlacekeeper in myPlacekeepers)
 | 
						|
			{
 | 
						|
				if(myPlacekeepers.Count > 1)
 | 
						|
					AddSectionHeader(myPlacekeeper.MyParagraph.MyItemInfo.DisplayNumber, myPlacekeeper.MyParagraph.MyItemInfo.FormattedDisplayText);
 | 
						|
				foreach (pkParagraph pgh in myPlacekeeper.MyChildren)
 | 
						|
				{
 | 
						|
					foreach (pkParagraph pghC in pgh.MyCautionsAndNotes)
 | 
						|
					{
 | 
						|
						StepConfig sc = pghC.MyParagraph.MyItemInfo.MyConfig as StepConfig;
 | 
						|
						string doneStr = (sc.Step_Placekeeper.ToUpper() == "C")? "C":"";
 | 
						|
						string NoteCautionTab = "NOTE:  ";
 | 
						|
						if (pghC.MyParagraph.MyItemInfo.IsCaution) NoteCautionTab = "CAUTION:  ";
 | 
						|
						AddCautionOrNote(NoteCautionTab, pghC.MyParagraph.MyItemInfo.FormattedDisplayText, doneStr, (pghC.MyParagraph.MyItemInfo.PageNumber+1).ToString());
 | 
						|
					}
 | 
						|
					AddHighLevelStep(pgh.MyParagraph.MyItemInfo.MyTab.CleanText, pgh.MyParagraph.MyItemInfo.FormattedDisplayText, pgh.MyParagraph.MyItemInfo.FormatStepType == 9 ? "C" : "", (pgh.MyParagraph.MyItemInfo.PageNumber + 1).ToString());
 | 
						|
					if (pgh.MyChildren.Count > 0)
 | 
						|
					{
 | 
						|
						bool conAct = false;
 | 
						|
						StartSubStep();
 | 
						|
						AddChildren(pgh, 1, ref conAct);
 | 
						|
						FinishSubstep((conAct)?"C":"", "");
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
			RepeatHeader();
 | 
						|
		}
 | 
						|
 | 
						|
		private void AddChildren(pkParagraph pgh, int level, ref bool conAct)
 | 
						|
		{
 | 
						|
			foreach (pkParagraph cpgh in pgh.MyChildren)
 | 
						|
			{
 | 
						|
				
 | 
						|
				if (cpgh.MyCautionsAndNotes.Count > 0)
 | 
						|
					AddNotesOrCautions(cpgh,level, ref conAct);
 | 
						|
				if (!conAct)
 | 
						|
					conAct = IsContinuousActionPlacekeeper(conAct, cpgh);
 | 
						|
				ContinueSubStep(cpgh.MyParagraph.MyItemInfo.FormattedDisplayText, level);
 | 
						|
				AddChildren(cpgh, level+1, ref conAct);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private void AddNotesOrCautions(pkParagraph pgh, int level, ref bool conAct)
 | 
						|
		{
 | 
						|
			foreach (pkParagraph cpgh in pgh.MyCautionsAndNotes)
 | 
						|
			{
 | 
						|
				if (!conAct)
 | 
						|
					conAct = IsContinuousActionPlacekeeper(conAct, cpgh);
 | 
						|
				ContinueNoteOrCaution(cpgh.MyParagraph.MyItemInfo, level);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private static bool IsContinuousActionPlacekeeper(bool conAct, pkParagraph pkPar)
 | 
						|
		{
 | 
						|
			StepConfig sc = pkPar.MyParagraph.MyItemInfo.MyConfig as StepConfig;
 | 
						|
			conAct = (sc.Step_Placekeeper.ToUpper() == "C");
 | 
						|
			return conAct;
 | 
						|
		}
 | 
						|
 | 
						|
		private void ContinueNoteOrCaution(ItemInfo ii, int level)
 | 
						|
		{
 | 
						|
			string NoteCautionTab = "NOTE:  ";
 | 
						|
			if (ii.IsCaution) NoteCautionTab = "CAUTION:  ";
 | 
						|
			if (!_FirstLine) _WordSel.TypeParagraph();
 | 
						|
			_FirstLine = false;
 | 
						|
			SetIndent(.33F + (.31F * level), -.31F);
 | 
						|
			WriteCell(NoteCautionTab + ii.FormattedDisplayText, false, false);
 | 
						|
		}
 | 
						|
		public void BuildSample()
 | 
						|
		{
 | 
						|
			_WordSel.TypeText("Placekeeper");
 | 
						|
			_WordSel.TypeParagraph();
 | 
						|
			_WordApp.Visible = true;
 | 
						|
			AddTable();
 | 
						|
			AddHeader();
 | 
						|
			AddSectionHeader("Section VI", "Title for section VI");
 | 
						|
			AddHighLevelStep("A.", TheQuickBrownFox, "C", "5");
 | 
						|
			AddSubStep(TheQuickBrownFox, "C", "");
 | 
						|
			AddCautionOrNote("NOTE:", "The Note text has a hanging indent on all but the first line of text", "", "");
 | 
						|
			AddHighLevelStep("B.", TheQuickBrownFox, "C", "7");
 | 
						|
			StartSubStep();
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 1);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 2);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 2);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 3);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 3);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 2);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 1);
 | 
						|
			FinishSubstep("", "");
 | 
						|
			AddHighLevelStep("C.", TheQuickBrownFox, "C", "8");
 | 
						|
			StartSubStep();
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 1);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 2);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 2);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 3);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 3);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 2);
 | 
						|
			ContinueSubStep(TheQuickBrownFox, 1);
 | 
						|
			FinishSubstep("", "");
 | 
						|
			RepeatHeader();
 | 
						|
		}
 | 
						|
 | 
						|
		private void RepeatHeader()
 | 
						|
		{
 | 
						|
			_WordTbl.Rows.First.Select();
 | 
						|
			_WordSel.Rows.HeadingFormat = -1;
 | 
						|
		}
 | 
						|
		private bool _FirstSection = true;
 | 
						|
		private void AddTable()
 | 
						|
		{
 | 
						|
			_FirstSection = true;
 | 
						|
			_WordTbl = _WordDoc.Tables.Add(_WordSel.Range, 1, 4, 1, 0);
 | 
						|
			_WordTbl.TopPadding = 6F;
 | 
						|
			_WordTbl.BottomPadding = 6F;
 | 
						|
			LBColumn col = _WordTbl.Columns.First;
 | 
						|
			//col.SetWidth(12F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			//col = col.Next;
 | 
						|
			col.SetWidth(72 * .91F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			col = col.Next;
 | 
						|
			col.SetWidth(72 * 4.1F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			col = col.Next;
 | 
						|
			//col.SetWidth(72 * .81F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			col.SetWidth(72 * .76F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			col = col.Next;
 | 
						|
			//col.SetWidth(72 * .81F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			col.SetWidth(72 * .76F, LBWdRulerStyle.wdAdjustNone);
 | 
						|
			_WordTbl.Rows.AllowBreakAcrossPages = 0;
 | 
						|
		}
 | 
						|
		private void AddHeader()
 | 
						|
		{
 | 
						|
			//Advance();
 | 
						|
			WriteCell("START", true, true);
 | 
						|
			SetIndent(0.32F, -0F);
 | 
						|
			WriteCell("FUNCTION", true, true);
 | 
						|
			WriteCell("DONE", true, true);
 | 
						|
			WriteCell("PAGE", true, false);
 | 
						|
		}
 | 
						|
		private void AddSectionHeader(string number, string title)
 | 
						|
		{
 | 
						|
			if (!_FirstSection)
 | 
						|
			{
 | 
						|
				Advance(5);
 | 
						|
				_WordSel.MoveLeft(LBWdUnits.wdCell, 1, false);
 | 
						|
				_WordSel.SelectRow();
 | 
						|
				_WordSel.Cells.Merge();
 | 
						|
			}
 | 
						|
			_FirstSection = false;
 | 
						|
			Advance(2);
 | 
						|
			SetIndent(0, 0);
 | 
						|
			WriteCell("SECTION " + number, true, false);
 | 
						|
			WriteCell("   " + title, false, true);
 | 
						|
			Advance();
 | 
						|
		}
 | 
						|
		private float GetTextWidth(string txt)
 | 
						|
		{
 | 
						|
			// follow through in fixing an Out of Window Handles bug, use new function to see if 
 | 
						|
			// we can retrieve the font from a dictionary instead a doing a New and using another
 | 
						|
			// window handle B2017-117
 | 
						|
			//System.Drawing.Font font = new System.Drawing.Font(_pkFont.Family, (float)_pkFont.Size);
 | 
						|
			System.Drawing.Font font = VE_Font.GetWinSysFont(_pkFont.Family, (float)_pkFont.Size);
 | 
						|
			iTextSharp.text.Font iFont = Volian.Svg.Library.VolianPdf.GetFont(font);
 | 
						|
			float w = 0;
 | 
						|
			foreach (char c in txt)
 | 
						|
			{
 | 
						|
				w += iFont.BaseFont.GetWidthPointKerned(c.ToString(), (float)_pkFont.Size);
 | 
						|
			}
 | 
						|
			// indented text didn't always line up doing it this way
 | 
						|
			//float w = iFont.BaseFont.GetWidthPointKerned(txt, (float)_pkFont.Size);
 | 
						|
			return w;
 | 
						|
		}
 | 
						|
		private void AddHighLevelStep(string number, string text, string done, string page)
 | 
						|
		{
 | 
						|
			// if the text contains prerequisite steps,
 | 
						|
			// parse out the step numbers and place them in the first column
 | 
						|
			if (text.Contains(@"\{Prerequisite Step: "))
 | 
						|
			{
 | 
						|
				string prereqToken = @"\{Prerequisite Step: ";
 | 
						|
				string preqStp = "";
 | 
						|
				int idx = text.IndexOf(prereqToken);
 | 
						|
				while (idx >= 0)
 | 
						|
				{
 | 
						|
					int parseStart = idx+prereqToken.Length;
 | 
						|
					int endx = text.IndexOf(@"\}",parseStart);
 | 
						|
					int parseLen =  endx - parseStart;
 | 
						|
					preqStp += "("+text.Substring(parseStart, parseLen) + "), ";
 | 
						|
					text = text.Remove(idx, endx+2 - idx);
 | 
						|
					idx = text.IndexOf(prereqToken);
 | 
						|
				}
 | 
						|
				Advance(1);
 | 
						|
				preqStp = preqStp.Substring(0, preqStp.Length - 2); // remove ending ", "
 | 
						|
				WriteCell(preqStp, false, true);
 | 
						|
			}
 | 
						|
			else
 | 
						|
				Advance(2);
 | 
						|
			if (text.Contains("\x05")) // hanging indent character
 | 
						|
			{
 | 
						|
				string[] parts = text.Split("\x05".ToCharArray());
 | 
						|
				float ind = (GetTextWidth(number) + GetTextWidth(parts[0])) / 72f;
 | 
						|
				SetIndent(ind, -ind);
 | 
						|
				WriteCell(number + parts[0] + parts[1], false, true);
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				SetIndent(.33F, -.33F);
 | 
						|
				WriteCell(number + text, false, true);
 | 
						|
			}
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(done, false, true);
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(page, false, false);
 | 
						|
		}
 | 
						|
		private void AddSubStep(string text, string done, string page)
 | 
						|
		{
 | 
						|
			Advance(2);
 | 
						|
			SetIndent(.64F, -.31F);
 | 
						|
			//_WordSel.InsertSymbol(8226, _WordSel.Font, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
 | 
						|
			WriteCell("\u2022" + "\t" + text, false, true);
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(done, false, true);
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(page, false, false);
 | 
						|
		}
 | 
						|
		private bool _FirstLine = false;
 | 
						|
		private void StartSubStep()
 | 
						|
		{
 | 
						|
			_FirstLine = true;
 | 
						|
			Advance(2);
 | 
						|
			SetIndent(.64F, -.31F);
 | 
						|
		}
 | 
						|
		private void ContinueSubStep(string text, int level)
 | 
						|
		{
 | 
						|
			if(!_FirstLine) _WordSel.TypeParagraph();
 | 
						|
			_FirstLine = false;
 | 
						|
			SetIndent(.33F + (.31F * level), -.31F);
 | 
						|
			WriteCell("\u2022" + "\t" + text, false, false);
 | 
						|
		}
 | 
						|
		private void FinishSubstep(string done, string page)
 | 
						|
		{
 | 
						|
			Advance();
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(done, false, true);
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(page, false, false);
 | 
						|
		}
 | 
						|
		private void AddCautionOrNote(string type, string text, string done, string page)
 | 
						|
		{
 | 
						|
			Advance(2);
 | 
						|
			SetIndent(.33F, -.33F);
 | 
						|
			WriteCell(type, true, false);
 | 
						|
			WriteCell("  " + text, false, true);
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(done, false, true);
 | 
						|
			SetAlignment(LBWdParagraphAlignment.wdAlignParagraphCenter, LBWdCellVerticalAlignment.wdCellAlignVerticalBottom);
 | 
						|
			WriteCell(page, false, false);
 | 
						|
		}
 | 
						|
		static Regex rgx = new Regex(@"\\(b|ul|up[1-9]|dn0|up0|dn[1-9]|b0|ulnone)( |$|(?=\\))");
 | 
						|
		private void WriteRTF(string text)
 | 
						|
		{
 | 
						|
			//if (text.Contains("\\"))
 | 
						|
			//	Console.WriteLine("here");
 | 
						|
			Match m = rgx.Match(text);
 | 
						|
			while (m.Success)
 | 
						|
			{
 | 
						|
				if (m.Index > 0)
 | 
						|
					_WordSel.TypeText(text.Substring(0,m.Index));
 | 
						|
				switch (m.Groups[1].Value)
 | 
						|
				{
 | 
						|
					case "b": // bold on
 | 
						|
						_WordSel.Font.Bold = 1;
 | 
						|
						break;
 | 
						|
					case "b0": // bold off
 | 
						|
						_WordSel.Font.Bold = 0;
 | 
						|
						break;
 | 
						|
					case "ul": // underline on
 | 
						|
						_WordSel.Font.Underline = LBWdUnderline.wdUnderlineSingle;
 | 
						|
						break;
 | 
						|
					case "ulnone": // underline off
 | 
						|
						_WordSel.Font.Underline = LBWdUnderline.wdUnderlineNone;
 | 
						|
						break;
 | 
						|
					case "dn0": // superscript off
 | 
						|
						_WordSel.Font.Superscript = 0;
 | 
						|
						break;
 | 
						|
					case "up0": // subscript off
 | 
						|
						_WordSel.Font.Subscript = 0;
 | 
						|
						break;
 | 
						|
					default:
 | 
						|
						if (m.Groups[1].Value.StartsWith("dn"))// subscript on
 | 
						|
						_WordSel.Font.Subscript = 1;
 | 
						|
						else // superscript on
 | 
						|
						_WordSel.Font.Superscript = 1;
 | 
						|
						break;
 | 
						|
 | 
						|
				}
 | 
						|
				text = text.Substring(m.Index+m.Length);
 | 
						|
				m = rgx.Match(text);
 | 
						|
			}
 | 
						|
			_WordSel.TypeText(text);
 | 
						|
		}
 | 
						|
		private void WriteCell(string text, bool bold, bool advance)
 | 
						|
		{
 | 
						|
			_WordSel.Font.Name = _pkFont.Family;//"Arial";
 | 
						|
			_WordSel.Font.Bold = bold ? 1 : 0;
 | 
						|
			//_WordSel.TypeText(text);
 | 
						|
			WriteRTF(text);
 | 
						|
			if (advance) Advance();
 | 
						|
		}
 | 
						|
		private void SetIndent(float left, float first)
 | 
						|
		{
 | 
						|
			_WordSel.ParagraphFormat.LeftIndent = left * 72;
 | 
						|
			_WordSel.ParagraphFormat.FirstLineIndent = first * 72;
 | 
						|
		}
 | 
						|
		private void SetAlignment(LBWdParagraphAlignment hAlign, LBWdCellVerticalAlignment vAlign)
 | 
						|
		{
 | 
						|
			_WordSel.ParagraphFormat.Alignment = hAlign;
 | 
						|
			_WordSel.Cells.VerticalAlignment = vAlign;
 | 
						|
		}
 | 
						|
		private void Advance(int count)
 | 
						|
		{
 | 
						|
			_WordSel.MoveRight(LBWdUnits.wdCell, count, false);
 | 
						|
		}
 | 
						|
		private void Advance()
 | 
						|
		{
 | 
						|
			Advance(1);
 | 
						|
		}
 | 
						|
		public void Dispose()
 | 
						|
		{
 | 
						|
			_WordApp.Quit(false);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |