SourceCode/PROMS/Volian.Print.Library/vlnParagraph.cs1.bak

1996 lines
83 KiB
Plaintext

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Text.RegularExpressions;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;
using Itenso.Rtf;
using Itenso.Rtf.Parser;
using Itenso.Rtf.Interpreter;
using Itenso.Rtf.Support;
using Volian.Controls.Library;
using VEPROMS.CSLA.Library;
using Volian.Base.Library;
namespace Volian.Print.Library
{
public partial class vlnParagraphs : List<vlnParagraph>
{
private vlnParagraph _Parent;
public vlnParagraph Parent
{
get { return _Parent; }
set { _Parent = value; }
}
public vlnParagraphs(vlnParagraph parent)
{
_Parent = parent;
}
public float Add(PdfContentByte cb, ItemInfoList itemInfoList, float xoff, float yoff, float yoffRight, int rnoLevel, int maxRNO, FormatInfo formatInfo)
{
int? bxIndex = null;
vlnBox box = null;
float yTop = yoff;
foreach (ItemInfo childItemInfo in itemInfoList)
{
// if this is a caution/note and it has a caution/note substep, do it before this caution/note, so that
// it comes above it.
if (childItemInfo.Cautions != null && (childItemInfo.IsCaution || childItemInfo.IsNote))
yoff = Add(cb, childItemInfo.Cautions, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo);
if (childItemInfo.Notes != null && (childItemInfo.IsCaution || childItemInfo.IsNote))
yoff = Add(cb, childItemInfo.Notes, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo);
int? bxIndx = childItemInfo.FormatStepData==null?-1:childItemInfo.FormatStepData.StepLayoutData.STBoxindex;
if (bxIndx != -1 && (bxIndex != bxIndx || childItemInfo.FormatStepData.BoxIt))
{
if (childItemInfo.FormatStepData.BoxIt) // this is a boxed HLS
{
box = new vlnBox();
box.MyBox = new Box();
box.DefBox = vlnBox.BoxThin;
StepSectionLayoutData ssld = formatInfo.MyStepSectionLayoutData;
int colR = int.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[childItemInfo.ColumnMode]);
int widS = vlnPrintObject.ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
box.DefEnd = (float)(ssld.ColS + colR + widS + (60/4.8));
box.YOffset = yoff - .75F * vlnPrintObject.SixLinesPerInch;
}
else if (bxIndex == null) // First boxed step
{
box = new vlnBox();
box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
if (box.MyBox != null)
{
box.YOffset = yoff;
int ln = 1; // a format flag determines whether there is a space before the note/caution.
if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
yoff += ln * vlnPrintObject.SixLinesPerInch;
}
}
else // Change Box Style
{
if (box != null) box.Height = yoff - box.YOffset; // new height, with children
box = new vlnBox();
box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
box.YOffset = yoff;
int ln = 1; // a format flag determines whether there is a space before the note/caution.
if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
yoff += ln * vlnPrintObject.SixLinesPerInch;
}
bxIndex = bxIndx;
}
if (childItemInfo is SectionInfo) formatInfo = (childItemInfo as SectionInfo).LocalFormat ?? formatInfo;
if (rnoLevel < maxRNO && childItemInfo.RNOs != null) yoff = Math.Max(yoff, yoffRight);
vlnParagraph para = new vlnParagraph(Parent, cb, childItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo);
if (box != null && box.MyParent == null)
{
box.MyParent = para;
para.PartsContainer.Add(box);
}
Add(para);
// para.YBottomMost will have y for bottom of any substeps that are also enclosed in the box.
if (childItemInfo.IsStep && childItemInfo.MyHLS.FormatStepData.UseSmartTemplate && para.ChildrenBelow.Count>0 && para.ChildrenBelow[0].YBottomMost > para.YBottomMost)
yoff = para.ChildrenBelow[0].YBottomMost;
else
yoff = para.YBottomMost;
if (childItemInfo.FormatStepData != null && childItemInfo.FormatStepData.BoxIt)
{
box.Height = yoff - box.YOffset - (1.1F * vlnPrintObject.SixLinesPerInch);
box = null; // if doing boxed steps, only do single sibling at a time.
}
}
if (box != null && box.MyBox != null)
{
box.Height = yoff - box.YOffset; // new height, with children
yoff += 2 * vlnPrintObject.SixLinesPerInch;
}
return yoff;
}
public float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
{
foreach (vlnParagraph child in this)
{
yPageStart = child.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
}
return yPageStart;
}
}
public partial class vlnParagraph : vlnPrintObject
{
private vlnTable _MyGrid;
public vlnTable MyGrid
{
get { return _MyGrid; }
set { _MyGrid = value; }
}
public float SectYPageStart = 0;
private bool _IsWordDocPara = false;
public bool IsWordDocPara
{
get { return _IsWordDocPara; }
set { _IsWordDocPara = value; }
}
public float ParagraphToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
{
if (Processed) return yPageStart;
//float localYPageStart = yPageStart;
Processed = true;
if (_PartsAbove != null && _PartsAbove.Count > 0) yPageStart = PartsAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
if (MyItemInfo.IsHigh && MyItemInfo.MyDocStyle.SpecialStepsFoldout) yPageStart -= SixLinesPerInch;
float yLocation = CalculateYOffset(yPageStart, yTopMargin);
if (MyItemInfo.HasChangeBar && MyPageHelper.ChangeBarDefinition.MyChangeBarType != PrintChangeBar.Without) MyPageHelper.AddChangeBar(DoChangeBar(cb, MyItemInfo, MyPageHelper, XOffset, yLocation, MyPageHelper.MaxRNO, MyItemInfo.ActiveFormat), cbMess);
float retval = yLocation;
if (MyItemInfo.IsFigure)
{
yLocation -= (SixLinesPerInch * MyPageHelper.YMultiplier);
if (ImageText != null)
retval = DrawFigure(cb, yBottomMargin, yLocation);
else
retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
}
else if (!MyItemInfo.IsStepSection
|| (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
&& !MyItemInfo.MyDocStyle.CancelSectTitle
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)) // Don't ouput the Step Section title
{
bool doprint = true;
// if this is a section, then check the section config for printable header too.
if (MyItemInfo.IsSection)
{
SectionConfig sch = MyItemInfo.MyConfig as SectionConfig;
if (!(MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
&& !MyItemInfo.MyDocStyle.CancelSectTitle
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
&&
((sch != null && sch.Section_PrintHdr != "Y") || !MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections)) doprint = false;
}
if (MyItemInfo.MyContent.MyGrid != null)
retval = DrawGrid(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
else
if (doprint)retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
if (MyItemInfo.IsHigh)
{
MyPageHelper.PageBookmarks.Add(MyItemInfo, MyItemInfo.MyTab.CleanText + " " + MyItemInfo.DisplayText,
new PdfDestination(PdfDestination.FITBH, yLocation + YVeryTop - YTopMost + SixLinesPerInch));
}
}
if (MyItemInfo.IsSection)
{
SectionConfig sc = MyItemInfo.MyConfig as SectionConfig;
if (sc != null && sc.Section_TOC == "Y")
{
string tocKey = string.Format("TOC{0}", MyItemInfo.ItemID);
if (MyPageHelper.MyTOCPageCounts.ContainsKey(tocKey))
{
PageCount pc = MyPageHelper.MyTOCPageCounts[tocKey];
pc.Total = MyPageHelper.CurrentPageNumber;
pc.DrawTemplates();
}
}
}
//Height = yLocation - retval;
if (_PartsLeft != null && _PartsLeft.Count > 0) yPageStart = PartsLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
if (_PartsRight != null && _PartsRight.Count > 0) yPageStart = PartsRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
if (_PartsBelow != null && _PartsBelow.Count > 0) yPageStart = PartsBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
if (_PartsContainer != null && _PartsContainer.Count > 0) yPageStart = PartsContainer.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
//if (localYPageStart != yPageStart) DebugText.WriteLine("ParToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, localYPageStart, yPageStart);
return yPageStart;
}
private float DrawGrid(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
{
//DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.ShortPath, FormattedText);
DebugText.WriteLine("{0},'{1}','{2}','<<END>>',{3}", MyItemInfo.ItemID, MyItemInfo.ShortPath,MyItemInfo.MyContent.Text,XOffset);
float retval = Rtf2Pdf.GridAt(cb, MyGrid, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
return retval;
}
private float DrawText(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
{
DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, FormattedText);
//Console.WriteLine("{0},{1},'{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, IParagraph.Content);
float retval = yLocation;
// Check if only one line, i.e. "Height < (1.2F * IParagraph.Leading". The Leading can be for six or seven lines per inch, so the 1.2
// multiplier accounts for both.
if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData.CenterOneLineOnly && MyItemInfo.MyPrevious == null && MyItemInfo.NextItem == null && Height < (1.2F * IParagraph.Leading))
IParagraph.Alignment = Element.ALIGN_CENTER;
if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData.StepPrintData.Justify == "Center")
IParagraph.Alignment = Element.ALIGN_CENTER;
retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin);
if (retval == 0) // problem occurred - paragraph was not able to be printed on page
{ // pagination logic needs to be fixed.
ForcePagination(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation, ref retval);
}
return retval;
}
private static List<string> myAttributes =new List<string>();
private static void AddAttribute(string attr)
{
if (myAttributes.Contains(attr))
return;
//Console.WriteLine("Attribute = \"{0}\"", attr);
myAttributes.Add(attr);
}
private void CheckAttributes(System.Collections.Hashtable attributes)
{
foreach (string attr in attributes.Keys)
{
AddAttribute(attr);
}
}
private string FormattedText
{
get
{
bool subscript = false;
//if (_MyItemInfo.ItemID == 467)
// Console.Write("");
StringBuilder sb = new StringBuilder();
//if (IParagraph.Chunks.Count > 1)
// Console.WriteLine("{0} Chunks", IParagraph.Chunks.Count);
foreach (Chunk chk in IParagraph.Chunks)
{
string prefix = "";
string suffix = "";
CheckAttributes(chk.Attributes);
if (chk.Font.BaseFont != null && chk.Font.BaseFont.PostscriptFontName.ToUpper().Contains("BOLD"))
{
prefix += "\xD5";
suffix = "\xD6" + suffix;
}
if (chk.Attributes.ContainsKey("SUBSUPSCRIPT"))
{
float sup = (float)(chk.Attributes["SUBSUPSCRIPT"]);
if (sup > 0)
{
prefix += "\xA6";
suffix = "\xD1" + suffix;
}
else if (sup < 0)
{
prefix += "\xD1";
suffix = "\xA6" + suffix;
}
}
if (chk.Attributes.ContainsKey("UNDERLINE"))
{
prefix += "\x16";
suffix = "\x16" + suffix; ;
}
sb.Append(prefix + chk.Content + suffix);
}
string retval = sb.ToString();
retval = retval.Replace("\xD1\xA6", "");// Remove Multiple Superscript commands in a row
retval = retval.Replace("\xA6\xD1", "");// Remove Multiple Superscript commands in a row
retval = retval.Replace("\xD6\xD5", "");
retval = retval.Replace("\xD6\x16\xD5", "\x16");
return retval;
}
}
//private bool _TextDebug = false; //true; this will turn on a writeline with debug in DrawText()
private float DrawFigure(PdfContentByte cb, float yBottomMargin, float yLocation)
{
float retval = yLocation;
if (ImageText != null)
{
string[] vals = ImageText.Split("\n".ToCharArray());
ProcedureInfo proc = MyItemInfo.MyProcedure;
DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo;
ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst;
ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]);
if (roImage != null)
{
iTextSharp.text.Image it_image = iTextSharp.text.Image.GetInstance(roImage.Content);
retval = Rtf2Pdf.FigureAt(cb, it_image, XOffset + MyItemInfo.FormatStepData.Font.CharsToTwips, yLocation, Width * MyPageHelper.YMultiplier, Height * MyPageHelper.YMultiplier, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
}
}
return retval;
}
private string DebugInfo
{
get
{
return string.Format("DebugID = {0}, ID={1} Type={2} TypeName='{3}' StepLevel={4} DBSequence={5}", DebugId, MyItemInfo.ItemID, MyItemInfo.FormatStepType, MyItemInfo.FormatStepData==null?"NoStepData":MyItemInfo.FormatStepData.Type, MyItemInfo.StepLevel, MyItemInfo.DBSequence);
}
}
public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
{
if (IsWordDocPara)
{
PdfReader tmp = null;
string tmpstr = null;
SectionInfo si = SectionInfo.Get(MyItemInfo.ItemID);
cb.PdfDocument.NewPage();
MyPageHelper.MyPromsPrinter.CreateWordDocPdf(cb, si, ref tmp, ref tmpstr);
Processed = true;
return yPageStart;
}
float yLocalypagestart = yPageStart;
// yPageStart is offset into roll; YTopMost is offset of topmost of this paragraph.
float yLocation = yPageStart - YTopMost;
DebugText.WriteLine("ToPdf1:{0},'{1}',{2},{3},{4},{5}", MyItemInfo.ItemID, MyItemInfo.ShortSearchPath, XOffset, yLocation, yPageStart, YTopMost);
int paginate = Paginate(yLocation, yTopMargin, yBottomMargin);
bool firstHighLevelStep = MyItemInfo.IsHigh && (MyItemInfo.MyPrevious == null);
switch (paginate)
{
case 0: // No page break
if (MyItemInfo.IsSection)
{
SectionInfo si = MyItemInfo as SectionInfo;
MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
}
break;
case 1: // Break on High Level Step
OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
cb.PdfDocument.NewPage();
DebugText.WriteLine("Paginate1");
if (MyItemInfo.IsSection)
{
SectionInfo si = MyItemInfo as SectionInfo;
MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
}
// Only do foldout page if not done for section break, i.e. check the there's a previous step.
if (MyItemInfo.MyPrevious != null && (MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
PromsPrinter.DoFoldoutPage(cb, "HLS", MyPageHelper.TextLayer, MyPageHelper);
yPageStart = yTopMargin + YTopMost;
DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
MyPageHelper.YMultiplier = 1;
break;
case 2: // Break within a Step
OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
DocStyle docstyle = MyItemInfo.MyDocStyle;
string myMsg = docstyle.Continue.Bottom.Message;
if (myMsg != null && myMsg != "")
{
if (myMsg.IndexOf(@"%d") > -1)
myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanText.Trim());
if (myMsg.IndexOf(@"%2d") > -1)
myMsg = myMsg.Replace(@"%2d", MyItemInfo.MyHLS.MyTab.CleanText.Trim(" .".ToCharArray()).PadLeft(2));
float msg_yLocation = 0;
if (myMsg.Contains("{par}"))
{
myMsg = myMsg.Replace("{par}", "");
msg_yLocation = -SixLinesPerInch;
}
switch (docstyle.Continue.Bottom.Location)
{
case E_ContBottomLoc.EndOfText: // place continue string at end of text
case E_ContBottomLoc.BtwnTextAndBottom: // place continue string between end of text & bottom of page
Console.WriteLine("Not done yet");
break;
case E_ContBottomLoc.BottomOfPage: // place continue message at bottom of page
//msg_yLocation = yBottomMargin + 2 * SixLinesPerInch + (float)docstyle.Layout.FooterLength; // 2 lines above bottom margin
msg_yLocation = msg_yLocation + yBottomMargin + (float)docstyle.Layout.FooterLength;
break;
default:
Console.WriteLine("**** BOTTOM CONTINUE MESSAGE NOT CODED*****");
break;
}
MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Bottom.Margin ?? 0, msg_yLocation, docstyle.Continue.Bottom.Font);// MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
}
cb.PdfDocument.NewPage();
DebugText.WriteLine("Paginate2");
if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
PromsPrinter.DoFoldoutPage(cb, "Break within Step", MyPageHelper.TextLayer, MyPageHelper); // temporary foldout
// If there is a box, adjust the yTopMost to include it.
float yTopMost = YTopMost;
//if (YVeryTop < yTopMost) Console.WriteLine("{0},{1},{2}", MyItemInfo.DBSequence, yTopMost, YVeryTop);
yTopMost = Math.Min(yTopMost,YVeryTop);
yPageStart = yTopMargin + yTopMost;// -2 * SixLinesPerInch;
DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
if (EmptyTopMostPart) yPageStart += SixLinesPerInch;
myMsg = docstyle.Continue.Top.Message;
if (myMsg != null && myMsg != "")
{
yPageStart -= 2 * SixLinesPerInch;// Allow two lines for top continue message
if (myMsg.IndexOf(@"%d") > -1)
myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanTextNoSymbols.Trim(" .".ToCharArray()));
MyPageHelper.TopMessage = new vlnText(cb, this, myMsg, myMsg, docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Top.Margin ?? 0, yTopMargin + 0.1F, docstyle.Continue.Top.Font);// MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
}
MyPageHelper.YMultiplier = 1;
break;
case 3: // Break on High Level Step (SevenLinesPerInch)
if (!firstHighLevelStep)
{
OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
cb.PdfDocument.NewPage(); // HLS (7 lpi) breakif (MyItemInfo.IsSection)
DebugText.WriteLine("Paginate3");
if (MyItemInfo.IsSection)
{
SectionInfo si = MyItemInfo as SectionInfo;
MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
}
if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
PromsPrinter.DoFoldoutPage(cb, "HLS (7 lpi) break", MyPageHelper.TextLayer, MyPageHelper);
}
if (MyItemInfo.MyParent != null && MyItemInfo.MyParent.IsStepSection &&
MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
&& !MyItemInfo.MyDocStyle.CancelSectTitle
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
yPageStart = yPageStart; // if printing the section title, we already have the y location
else
yPageStart = yTopMargin + YTopMost;
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
break;
}
yPageStart = ChildrenAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
yPageStart = ChildrenLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
// If this is a high level step, the format may have specified that the step should be printed with
// extra space between it and the previous step. The 16bit code uses the value of the extra space
// from the high level step format regardless of what type of high level step it is. Also, if there
// is caution or note above it, this space is not added:
yPageStart -= ((!MyItemInfo.IsHigh || ChildrenAbove == null) ? 0 : MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[2].StepLayoutData.STExtraSpace ?? 0);
yPageStart = ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
yPageStart = ChildrenRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
yPageStart = ChildrenBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
if (MyItemInfo.IsHigh && MyItemInfo.NextItem == null) // last hls, add the 'end' message, if there is one
{
DocStyle docstyle = MyItemInfo.MyDocStyle;
string myMsg = (docstyle.End == null) ? null : docstyle.End.Message;
if (myMsg != null)
{
// If the flag is 0 or 1, just put the end message out right below this vlnParagraph:
float msg_yLocation = CalculateYLocation(yPageStart - YBottomMost, yTopMargin);
// use the 'flag' to position the message.
if (docstyle.End.Flag > 2) // >2 position at an absolute location defined by docstyle.End.Flag.
{
msg_yLocation = yTopMargin - (float)(docstyle.End.Flag * SixLinesPerInch);
}
if (myMsg.Contains("{Section Number}")) myMsg = myMsg.Replace("{Section Number}", MyItemInfo.ActiveSection.DisplayNumber);
// center the message.
float wtpm = (float)docstyle.Layout.PageWidth - (float)docstyle.Layout.LeftMargin;
float centerpos = XOffsetBox + (float)docstyle.Layout.LeftMargin + (wtpm - (myMsg.Length * MyItemInfo.FormatStepData.Font.CharsToTwips)) / 2;
MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, centerpos, msg_yLocation, docstyle.End.Font);
}
}
if (yLocalypagestart != yPageStart) DebugText.WriteLine("ToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, yLocalypagestart, yPageStart);
return yPageStart;
}
private vlnParagraph TopMostChild
{
get
{
if (ChildrenAbove.Count>0) return ChildrenAbove[0].TopMostChild;
return this;
}
}
private bool EmptyTopMostPart
{
get
{
if (TopMostChild.PartsAbove.Count == 0) return false;
foreach (vlnPrintObject po in TopMostChild.PartsAbove)
{
vlnHeader hd = po as vlnHeader;
if (hd == null) return false;
if (hd.Text != "") return false;
}
return true;
}
}
private void OutputOtherPageSteps(PdfContentByte cb, float YTopMost, float yPageStart, float yTopMargin, float yBottomMargin)
{
// Find any items remaining in MyPageHelper.MyParagraphs that should be printed on this page.
vlnParagraphs process = new vlnParagraphs(null);
foreach (vlnParagraph vPara in MyPageHelper.MyParagraphs.Values)
{
//if (!vPara.Processed && ((vPara.YOffset + vPara.Height) < YTopMost))
if (!vPara.Processed && ((vPara.YOffset) < YTopMost))
process.Add(vPara);
}
foreach (vlnParagraph vPara in process)
{
vPara.ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
}
}
private float _YVeryTop = -1;
public float YVeryTop
{
get
{
if (_YVeryTop == -1)
{
_YVeryTop = YTop;
_YVeryTop = VeryTop(PartsAbove,_YVeryTop);
_YVeryTop = VeryTop(PartsContainer,_YVeryTop);
}
return _YVeryTop;
}
}
private float VeryTop(vlnPrintObjects parts, float yVeryTop)
{
if (parts != null)
foreach (vlnPrintObject part in parts)
if (part.YOffset < yVeryTop)
yVeryTop = part.YOffset;
return yVeryTop;
}
/// <summary>
/// This gets the height of the step with it's Caution's, Notes and potentially any First Substeps
/// </summary>
/// <returns></returns>
private float GetFirstPieceSize()
{
vlnParagraph paraLast = GetFirstPieceLastPart();
float retval = (paraLast.YBottom) - YTopMost;
//Console.WriteLine(MyItemInfo.DBSequence);
return retval;
}
public override float YBottom
{
get
{
float bottom = YOffset + Height;
if (PartsBelow != null)
{
foreach (vlnPrintObject part in PartsBelow)
{
float partBottom = part.YBottom;
bottom = Math.Max(partBottom, bottom);
}
}
return bottom;
}
}
public float YBottomText
{
get
{
return YOffset + Height;
}
}
private vlnParagraph GetFirstPieceLastPart()
{
vlnParagraph para = this;
if (!MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PaginateOnFirstSubstep && ChildrenBelow != null && ChildrenBelow.Count > 0)
{
para = ChildrenBelow[0].GetFirstPieceLastPart();
}
if (ChildrenRight != null && ChildrenRight.Count > 0)
{
foreach(vlnParagraph paraRight in ChildrenRight)
{
vlnParagraph paraRightLast = paraRight.GetFirstPieceLastPart();
if (paraRightLast.YBottom > para.YBottom)
para = paraRightLast;
}
}
return para;
}
/// <summary>
/// Find items from previous page (yLocation less than yTop) and remove them from the list.
/// yTop is the new starting location on the next page for this step.
/// </summary>
/// <param name="myList"></param>
/// <param name="yTop"></param>
private void RemoveProcessedParagraphs(StepLevelList myList, float yTop)
{
// the two CleanUpLists are used to remove items from
// the original list because list items cannot be removed in a
// 'foreach'.
List<int> CleanupListStepLevel = new List<int>();
foreach(int stepLevel in myList.Keys)
{
List<float> CleanupListYLocation = new List<float>();
SortedList<float, float> AdjustYLocation = new SortedList<float,float>();
foreach (float yLocation in myList[stepLevel].Keys)
{
if (-yLocation <= yTop)
CleanupListYLocation.Add(yLocation);
else
AdjustYLocation.Add(-yLocation, yLocation); // order in ascending order
}
foreach (float yLocation in CleanupListYLocation)
myList[stepLevel].Remove(yLocation);
foreach (float yLocation in AdjustYLocation.Keys)
{
vlnParagraph para = myList[stepLevel][-yLocation];
myList[stepLevel].Remove(-yLocation);
// shift yLocation by yTop to work with items whose locations
// are defined from the top of the new page rather than
// from the beginning of the step.
// Note that yLocation is negative to have items in descending
// order so that adding yTop decrements their values.
myList[stepLevel].Add(yTop-yLocation, para);
}
if (myList[stepLevel].Count == 0)
CleanupListStepLevel.Add(stepLevel);
}
foreach (int stepLevel in CleanupListStepLevel)
myList.Remove(stepLevel);
}
/// <summary>
/// Builds a list of paragraphs by StepLevel and yLocation in descending order.
/// </summary>
/// <param name="yTopMost"></param>
/// <param name="myList"></param>
private void BuildLocationList(float yTopMost, ParagraphLocations myLocations)
{
foreach (vlnParagraph child in ChildrenAbove)
child.BuildLocationList(yTopMost, myLocations);
foreach (vlnParagraph child in ChildrenLeft)
child.BuildLocationList(yTopMost, myLocations);
// Add a list entry consisting of StepLevel, yoffset from the beginning of this step, paragraph itself
myLocations.Add(this, yTopMost);
foreach (vlnParagraph child in ChildrenRight)
child.BuildLocationList(yTopMost, myLocations);
foreach (vlnParagraph child in ChildrenBelow)
child.BuildLocationList(yTopMost, myLocations);
}
private int COL_WID_ADJ = 6; // adjusts for incorrect use of WidSTable when breaking a line (it breaks 6 chars too short)
public vlnParagraph(vlnParagraph parent, PdfContentByte cb, ItemInfo itemInfo, float xoff, float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo)
{
float savCheckListBottomMost = 0;
//int[] problemIDs = { 889 };
//List<int> lProblemIDs = new List<int>(problemIDs);
//if (lProblemIDs.Contains(itemInfo.ItemID))
// Console.WriteLine("Found Item {0}", itemInfo.ItemID);formatInfochecko
MyParent = parent;
// The following code determines the last paragraph for an RNO
// MyTopRNO finds the Top paragraph for an RNO
if (itemInfo.IsInRNO)
{
if (rnoLevel <= maxRNO && itemInfo.IsRNOPart) // Not top level RNO
MyTopRNO = this;
else
MyTopRNO = MyParent.MyTopRNO;
if(MyTopRNO != null) MyTopRNO.LastRNO = this;
}
MyContentByte = cb;
MyPageHelper.MyParagraphs.Add(itemInfo.ItemID, this);
MyItemInfo = itemInfo;
XOffset = xoff;
if (!MyItemInfo.IsStep && !MyItemInfo.IsStepSection)
{
IsWordDocPara = true;
// special case - this is a 'Word Doc' paragraph. The Processed flag is used to know
// that steps need put out on a page for the pagination logic, and since there are no steps
// we don't want to have to worry about putting this out for pagination logic.
Processed = true;
return;
}
// Set any position adjustment (defined in the format on a per type basis)
yoff += (MyItemInfo.FormatStepData == null) ? 0 : MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0;
YTopMost = YOffset = yoff;
vlnTab mytab = null;
bool doSectTab = false;
// if this substep has a caution or note as its parent, then there may have been a special indent done on the
// substep... check the CautionOrNoteSubstepIndent value, this is the additional indent amount in number
// of characters.
if (itemInfo.MyParent.IsCaution || itemInfo.MyParent.IsNote)
XOffset += 72 * (itemInfo.FormatStepData.CautionOrNoteSubstepIndent == null ? 0 : (float)itemInfo.FormatStepData.CautionOrNoteSubstepIndent / (float)itemInfo.FormatStepData.Font.CPI);
if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate &&
itemInfo.FormatStepData.StepLayoutData.AlignWithParentTab
|| (itemInfo.Steps != null && itemInfo.Steps.Count > 0 && itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab))
itemInfo.MyTab = null;
if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && itemInfo.MyTab.Text != "")
{
float localXOffset = XOffset;
bool doprint = true;
if (itemInfo.IsSection)
{
SectionConfig sch = MyItemInfo.MyConfig as SectionConfig;
if (!(MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
&& !MyItemInfo.MyDocStyle.CancelSectTitle
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
&&
((sch != null && sch.Section_PrintHdr != "Y") || !MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections)) doprint = false;
}
if (doprint && itemInfo.IsSection && !itemInfo.MyDocStyle.CancelSectTitle && itemInfo.MyTab.Text.ToUpper() != "FOLDOUT")
{
doSectTab = true;
if (itemInfo.IsStepSection && formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Just == "PSLeft")
{
float offset = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
if (formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos != null)
{
// determine level of metasections. This level will be used to calculate the
// indent. DO I NEED THIS HERE????
int level = 0;
ItemInfo iilvl = itemInfo;
while (!iilvl.IsProcedure)
{
level++;
iilvl = iilvl.MyParent;
}
level = level <= 2 ? 1 : level - 1;
if (level == 1)
offset += (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos;
else
offset += (level-1) * ((float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos-(float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos);
}
localXOffset = offset;
}
}
if (!itemInfo.IsSection || doSectTab)
{
mytab = new vlnTab(cb, this, itemInfo.MyTab.Text, itemInfo.MyTab.CleanText, localXOffset, yoff, itemInfo.MyTab.MyFont, doSectTab, StepRTB.MySymbolFontName, itemInfo.MyTab.RemovedStyleUnderline);
PartsLeft.Add(mytab);
if (mytab.MyMacro != null) PartsLeft.Add(mytab.MyMacro);
}
}
AdjustWidth(itemInfo, maxRNO, formatInfo, mytab);
AdjustXOffsetForTab(itemInfo, maxRNO, formatInfo, mytab);
if (itemInfo.Cautions != null && !(itemInfo.IsCaution || itemInfo.IsNote))
yoff = ChildrenAbove.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
if (itemInfo.Notes != null && !(itemInfo.IsCaution || itemInfo.IsNote))
yoff = ChildrenAbove.Add(cb, itemInfo.Notes, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
YTop = yoff;
if (itemInfo.MyHeader != null && itemInfo.MyHeader.Text != null && !doSectTab)
yoff += SetHeader(this, cb, itemInfo, formatInfo);
YOffset = yoff;
if (mytab != null && mytab.SeparateBullet)
{
string identB = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.IdentB;
vlnText myBullet = new vlnText(cb, this, identB, identB, XOffset - 12, YOffset, MyItemInfo.FormatStepData.TabData.Bullet.Font);
myBullet.Rtf = myBullet.Rtf.Replace("\u25CF", @"\f1\u9679?\f0 ");
PartsLeft.Add(myBullet);
}
if (itemInfo.IsRNOPart)
{
// there may be other places that double space, but this supports it for RNOs (the DoubleRNOspace flag)
if (rnoLevel > maxRNO && itemInfo.FormatStepData.DoubleSpace) yoff = YOffset = yoff + SixLinesPerInch;
}
AddMacros(itemInfo, mytab);
if (mytab != null)
{
mytab.YOffset = yoff;
if (mytab.MyMacro != null) mytab.MyMacro.YOffset = yoff;
}
float yForCheckoff = yoff; //0; - default checkoff row is same as FIRST line of text
// if dropCheckoff is true, then the checkoff is place on the same of row as the LAST line of text
bool dropCheckoff = itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.DropCheckOff;
if (itemInfo.MyContent.MyGrid != null)
{
VlnFlexGrid myFlexGrid = new VlnFlexGrid(1,1);
myFlexGrid.LoadGrid(itemInfo);
MyGrid = new vlnTable(myFlexGrid, cb);
Height = MyGrid.Height;
Width = MyGrid.Width;
//yForCheckoff = yoff + Height - SixLinesPerInch;
if (dropCheckoff)
yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text
yoff += (Height + (2 * SixLinesPerInch));
CalculateXOffset(itemInfo, maxRNO, formatInfo);
}
else if (itemInfo.IsFigure) // if a figure we've got to determine the size:
{
string erMsg = null;
if (itemInfo.MyContent.Text != null)
{
ProcedureInfo proc = itemInfo.MyProcedure;
// DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo;
DocVersionInfo dvi = proc.MyDocVersion;
ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst;
rofst.docVer = dvi;
ROFSTLookup lookup = rofst.ROFSTLookup;
string linkInfoText = itemInfo.MyContent.Text.Replace(@"\v ", "");
if (linkInfoText.Contains("?"))
erMsg = "RO was not found during data migration.";
else
{
Match m = Regex.Match(linkInfoText, @"(.*)[#]Link:([A-Za-z]*):(.*)");
string[] subs = m.Groups[3].Value.Split(" ".ToCharArray());
string roid = subs[1];
string val = lookup.GetRoValue(subs[1]);
if (val == null) val = lookup.GetRoValue(subs[1].Substring(0, 12));
if (val != null)
{
string[] vals = val.Split("\n".ToCharArray());
Width = Int32.Parse(vals[3], System.Globalization.NumberStyles.AllowHexSpecifier) * MyItemInfo.FormatStepData.Font.CharsToTwips;
int lines = Int32.Parse(vals[2], System.Globalization.NumberStyles.AllowHexSpecifier);
Height = lines * SixLinesPerInch;
//yForCheckoff = yoff + Height - SixLinesPerInch;
if (dropCheckoff)
yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text
yoff += (Height + (2 * SixLinesPerInch));
try
{
ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]);
if (roImage != null)
ImageText = val;
else
erMsg = string.Format("Image {0} does not exist.", vals[0]);
}
catch (Exception ex)
{
erMsg = string.Format("Image {0} does not exist, error = {1}.", vals[0], ex.Message);
}
}
}
if (erMsg != null) Rtf = GetRtf(erMsg, itemInfo.ActiveFormat.PlantFormat.FormatData.Font);
CalculateXOffset(itemInfo, maxRNO, formatInfo);
}
}
else
{
Rtf = GetRtf(itemInfo);
// Need the following with some modifications for WCNCKL format:
if (Rtf.Contains("{Backspace}"))
{
XOffset -= 22;
Width += 24;
Rtf = Rtf.Replace("{Backspace}", "");
}
if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate)
{
if (itemInfo.FormatStepData.StepLayoutData.AlignWithParentTab
|| (itemInfo.Steps != null && itemInfo.Steps.Count > 0 && itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab))
{
int stplevl = TheStepLevel(itemInfo);
if (stplevl >= 0 && MyItemInfo.MyHLS.FormatStepData.VertPos[stplevl] > 0)
XOffset = float.Parse(MyItemInfo.MyHLS.FormatStepData.VertPos.Split(",".ToCharArray())[stplevl]) + (float)itemInfo.MyDocStyle.Layout.LeftMargin;
}
}
if (itemInfo.IsTablePart) // Not for grid, this is for old-style tables.
{
Width = GetTableWidth(cb, IParagraph, MyItemInfo.MyDocStyle.Layout.PageWidth);
CalculateXOffset(itemInfo, maxRNO, formatInfo);
}
else
if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null) XOffset += (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0);
bool printMetaHdr = false;
if (itemInfo.Steps != null && itemInfo.IsSection && itemInfo.Sections != null && itemInfo.Sections.Count > 0)
{
SectionConfig sc = itemInfo.MyConfig as SectionConfig;
if ((sc != null && sc.Section_PrintHdr == "Y") && itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections) printMetaHdr = true;
}
// If WCN checklists, the substeps are printed in a row, need to keep track of the 'longest' in
// y direction (bottommost) across the row.
if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate && (TheStepLevel(itemInfo)>0))
{
// do I need to get max of savCheckListBottomMost & (yoff+Height+SixLinesPerInch)
savCheckListBottomMost = yoff + Height + SixLinesPerInch;
}
// Get Y offset for regular steps, or if section title is output or if not within row (not last column of
// text) for wcn checklist, i.e. .
if ((!itemInfo.IsStepSection && !itemInfo.MyHLS.FormatStepData.UseSmartTemplate)
|| printMetaHdr ||
(formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
&& !MyItemInfo.MyDocStyle.CancelSectTitle
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
// In WCN Checklist: I don't have children or if I have children the first child doesn't alignwithparent.
|| (!itemInfo.IsStepSection && itemInfo.MyHLS.FormatStepData.UseSmartTemplate
&& ((itemInfo.Steps == null || itemInfo.Steps.Count == 0)
|| !itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab)))
{
yoff += Height;
yoff += AdjustForBlankLines();
if (dropCheckoff)
yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text
}
}
CheckOff co = itemInfo.GetCheckOffStep();
if (co != null)
{
//float xloc_co = (float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation + (float)itemInfo.MyDocStyle.Layout.LeftMargin;
float xloc_co = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation != null)
xloc_co += (float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation;
PartsRight.Add(new vlnMacro(xloc_co, yForCheckoff, co.Macro));
}
float yOffRight = yoff;
float RnoOffset = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
if (rnoLevel < maxRNO && itemInfo.RNOs != null) yOffRight = ChildrenRight.Add(cb, itemInfo.RNOs, XOffset + RnoOffset, YTop, YTop, rnoLevel + 1, maxRNO, formatInfo);
// Need code to determine if the table will overlap the Right Column if it does then
// use YOffRight rather than yoff
if (itemInfo.Tables != null)
{
bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
if(!aerTableOrFigure && itemInfo.RNOLevel == 0) // Centered Table
yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yOffRight, yOffRight, rnoLevel, maxRNO, formatInfo);
else // AER or RNO Table
yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
}
// Look for the meta section case where the 'Editable' flag is set to 'N', which means that
// these steps should not be printed:
bool printsteps = true;
if (itemInfo.Steps != null && itemInfo.IsSection && itemInfo.Sections!=null && itemInfo.Sections.Count>0)
{
SectionConfig sc = itemInfo.MyConfig as SectionConfig;
if (sc != null && sc.SubSection_Edit != "Y") printsteps = false;
}
if (itemInfo.Steps != null && printsteps) yoff = ChildrenBelow.Add(cb, itemInfo.Steps, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
if (itemInfo.Sections != null) yoff = ChildrenBelow.Add(cb, itemInfo.Sections, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
if (itemInfo.Procedures != null) yoff = ChildrenBelow.Add(cb, itemInfo.Procedures, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
if (rnoLevel >= maxRNO && itemInfo.RNOs != null) yoff = ChildrenBelow.Add(cb, itemInfo.RNOs, XOffset, yoff, yoff, rnoLevel + 1, maxRNO, formatInfo);
yoff = Math.Max(yoff, yOffRight);
// TODO - use RNOSepAfterAER flag too:
string tmpRnoSepStr = formatInfo.MyStepSectionPrintData.RNOSepString;
if (rnoLevel < maxRNO && itemInfo.RNOs != null && tmpRnoSepStr != null)
{
vlnParagraph rno = ChildrenRight[0];
vlnParagraph bottomChild = BottomChild;
float xsep = MyHighLevelParagraph.XOffset + RnoOffset;
vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff, formatInfo, bottomChild==null?true:bottomChild.MyItemInfo.HasChangeBar);
// TODO: May need to handle more than one RNO column for RNO Separator
if (rno.LastRNO.MyItemInfo.HasChangeBar == false && bottomChild != null && bottomChild.MyItemInfo.HasChangeBar)
bottomChild.PartsBelow.Add(myRnoSep);
else
rno.LastRNO.PartsBelow.Add(myRnoSep);
yoff += myRnoSep.Height + SixLinesPerInch;
}
YBottomMost = yoff;
// For WCN Checklist, the substeps are in rows of data. The YBottomMost is the bottom most for
// the row.
if (savCheckListBottomMost != 0 && savCheckListBottomMost>YBottomMost) YBottomMost = savCheckListBottomMost;
}
private int TheStepLevel(ItemInfo itemInfo)
{
if (itemInfo.IsHigh) return -1;
int lev = 0;
ItemInfo ii = itemInfo;
while (!ii.MyParent.IsHigh)
{
lev++;
ii = ii.MyParent;
}
return lev;
}
private string SectionHasCheckOffHeader(ItemInfo itemInfo, ref VE_Font font)
{
// If the passed in itemInfo is not a section, get it's parent section. This may be a subsection, so
// it will be found here, versus using 'MyActiveSection'.
while (!itemInfo.IsSection)
{
itemInfo = itemInfo.MyParent;
}
// See if this section has a checkoffheading index - this value, if set is stored in the config field.
// -1 flags no entries in the format's CheckOffHeaderList & 0 flags the first
// entry which is always '{NO HEADING}'. So only continue if it's greater than 0.
SectionInfo si = SectionInfo.Get(itemInfo.ItemID); // sometimes the itemInfo isn't a section info
int sindx = si.CheckOffHeadingIndex();
// If there is a checkoff header for this section, see if this section has subsections.
// If this has a header but no subsections, put out the header.
// Else if this section has a header AND subsections, don't put it out...
// the subsection's checkoff header will be processed (or lack there of).
bool doCheckoffHeader = sindx > 0 && (itemInfo.Sections == null || itemInfo.Sections.Count == 0);
// if doing it, then grab the string from the format.... CHECK if this works for subsection, it is
// getting ActiveSection which may return the top section, not subsections.
if (doCheckoffHeader && itemInfo.SectionCheckOffHeader != "")
{
font = itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList[sindx].Font;
return itemInfo.SectionCheckOffHeader;
}
return null;
}
private void DoCheckOffHeader(PdfContentByte cb, ItemInfo itemInfo, float yLocation, float yTopMargin, float yPageStart)
{
// CheckOffHeaders are handled in two different ways:
// 1) Where the pagelist item puts them - this is at the 'top' of the page, when the current section on the
// page has a checkoff header defined. Support for this is here AND in the VlnSvgPageHelper pagelist code.
// 2) If a continuous section, and it doesn't start at 'top' of the page, then the checkoff header is
// printed on the same line as the continuous section. Support for this is here, the check off header is added
// to the 'PartRight' off of the section's VlnParagraph.
// First see if there is any checkoff data in the format file and that there
// is a pagelist item for the checkoff header.
if (itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList.Count <= 0) return;
if (MyPageHelper.PageListCheckOffHeader == null) return;
VE_Font font = null;
ItemInfo mySectionInfo = itemInfo.MyActiveSection;
ItemInfo mySubSectionInfo = itemInfo;
// If the passed in itemInfo is not a section, get it's parent section. This may be a subsection, so
// it will be found here, versus using 'MyActiveSection' which is the topmost section. The passed in
// item may be a regular step, i.e. if a page break had occurred.
if (!itemInfo.IsSection)
{
while (!mySubSectionInfo.IsSection)
{
mySubSectionInfo = mySubSectionInfo.MyParent;
}
}
else
mySubSectionInfo = (mySectionInfo.Sections == null)?null:mySectionInfo.Sections[0];
if (mySectionInfo == mySubSectionInfo) mySubSectionInfo = null;
// The following duplicates the 16bit logic. The 16bit logic only put out a header if:
// there is no subsection and section has a header (from config);
// OR there is a subsection and the first subsection has a header.
// For locating the header in 16bit logic:
// If no subsections, output with section
// If subsections and continuous section, put out on same line as subsection. (done here)
// If subsections and starts at top of page, (on top of page, use pagelist code in VlnSvgPageHelper)
// Get SectionInfos to access specific section config items...
SectionInfo si = SectionInfo.Get(mySectionInfo.ItemID);
int sindx = si.CheckOffHeadingIndex();
SectionInfo subi = mySubSectionInfo == null ? null : SectionInfo.Get(mySubSectionInfo.ItemID);
int subindx = subi==null?-1:subi.CheckOffHeadingIndex();
// if there is no subsections & the main section doesn't use a header OR
// if there is a subsection, & it does not use a header... Return.
if ((subi==null&&sindx < 1) || (subi!=null&&subindx<1)) return;
// figure out location now:
// if step, it uses pagelist logic to locate it (this is a page break condition).
// if continuous, put out with subsection if there is one, otherwise section.
// otherwise, use pagelist logic.
bool usePageListCOHdr = false;
if (itemInfo.IsStep)
usePageListCOHdr = true;
else if (subi == null) //no subsection
{
if ((yPageStart - YOffset) == yTopMargin) usePageListCOHdr = true;
}
else
{
if (mySectionInfo == itemInfo && ((yPageStart - YOffset) == yTopMargin)) usePageListCOHdr = true;
if (!usePageListCOHdr && mySubSectionInfo != itemInfo) return;
}
// grab the string from the format, depending on whether it should get it from the section or subsection.
string cohead = (mySubSectionInfo!=null)?mySubSectionInfo.SectionCheckOffHeader:mySectionInfo.SectionCheckOffHeader;
if (cohead == "" || cohead == null) return;
// PageListCheckOffHeader is an svgtext - but really we only need the x/y location for this (pagelist support)
// The actual text is from the checkoff header selection in the section config.
if (cohead != MyPageHelper.PageListLastCheckOffHeader)
{
font = mySectionInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList[sindx].Font;
float chkOffY = CalculateYLocation(YTopMost, yTopMargin);
if (MyPageHelper.YMultiplier != 1)
{
chkOffY = -1 + yTopMargin - (yTopMargin - yLocation) * MyPageHelper.YMultiplier;
if (Rtf != null)
IParagraph.Leading = _SevenLinesPerInch;
}
if (!usePageListCOHdr)
{
vlnText myCOHead = new vlnText(cb, this, cohead, cohead, MyPageHelper.PageListCheckOffHeader.X.Value + (float)MyItemInfo.MyDocStyle.Layout.LeftMargin, chkOffY, font);
PartsRight.Add(myCOHead);
}
else
MyPageHelper.PageListTopCheckOffHeader = cohead;
MyPageHelper.PageListLastCheckOffHeader = cohead;
}
}
internal vlnParagraph BottomChild
{
get
{
float bottomChildYBottomText = YBottomText;
vlnParagraph bottomChild = this;
foreach (vlnParagraph child in ChildrenRight)
{
vlnParagraph grandChild = child.BottomChild;
if (grandChild != null && grandChild.YBottomText > bottomChildYBottomText) bottomChild = grandChild;
if (grandChild != null && grandChild.YBottomText == bottomChildYBottomText && grandChild.MyItemInfo.HasChangeBar) bottomChild = grandChild;
bottomChildYBottomText = bottomChild.YBottomText;
}
foreach (vlnParagraph child in ChildrenBelow)
{
vlnParagraph grandChild = child.BottomChild;
if (grandChild != null && grandChild.YBottomText > bottomChildYBottomText) bottomChild = grandChild;
if (grandChild != null && grandChild.YBottomText == bottomChildYBottomText && grandChild.MyItemInfo.HasChangeBar) bottomChild = grandChild;
bottomChildYBottomText = bottomChild.YBottomText;
}
return bottomChild;
}
}
private void CalculateXOffset(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo)
{
bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
vlnParagraph hls1 = MyParent;
while (hls1.MyParent != null && !hls1.MyItemInfo.IsHigh) hls1 = hls1.MyParent;
float colR = float.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[itemInfo.ColumnMode]);
float xLowerLimit = hls1.XOffset;
float xUpperLimit = hls1.XOffset + hls1.Width + colR * itemInfo.ColumnMode;
float TableCenterPos = float.Parse(formatInfo.MyStepSectionLayoutData.TableCenterPos.Split(",".ToCharArray())[itemInfo.ColumnMode]);
if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel)
{
float pageWidth = ((float)itemInfo.MyActiveSection.MyDocStyle.Layout.PageWidth); //* (float)MyItemInfo.FormatStepData.Font.CPI / 12;
float leftMargin = ((float)itemInfo.MyActiveSection.MyDocStyle.Layout.LeftMargin); //* (float)MyItemInfo.FormatStepData.Font.CPI / 12;
XOffset = leftMargin + (pageWidth - leftMargin - Width) / 2;
}
else
{
// Determine center of hls
XOffset = hls1.XOffset + hls1.Width / 2;
// Determine left edge of the table by subtracting 1/2 of its width.
XOffset -= Width / 2;
if (aerTableOrFigure || itemInfo.RNOLevel != 0) // AER or RNO
XOffset = MyParent.XOffset + MyParent.Width / 2 - Width / 2;
else if (TableCenterPos != 0)
XOffset = TableCenterPos;
else // Centered Table or Figure
{
// Add in 1/2 of the width of all RNO columns
XOffset += (colR * itemInfo.ColumnMode) / 2;
if (!aerTableOrFigure)
{
// 05/14/12 - 16bit code adjusts the center depending upon the CPI of the table font.
// Start with XOffset of table, then calculate the XOffset adjusted for the table font,
// based on the default CPI of 12. Adjust the XOffset by the difference of these
// two numbers.
XOffset -= (XOffset - (XOffset * (float)MyItemInfo.FormatStepData.Font.CPI / 12));
}
XOffset -= 12; // This makes the 16bit & 32bit align very closely.
}
// 05/14/12 - The PosAdjust is a format flag from 16bit. For WCN2, it appears that this amount equals
// the amount of difference from a 10 CPI to a 12 CPI font. See comment above.
if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null)
XOffset += (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0);
}
// if the XOffset < High Level Step Text's XOffset, then align with the High Level Step Text
if (XOffset < xLowerLimit && Width < (xUpperLimit - xLowerLimit))
XOffset = xLowerLimit;
// if the right margin exceeds the right edge of the rightmost RNO, then adjust right edge to match.
if (XOffset + Width > xUpperLimit)
XOffset = xUpperLimit - Width;
// because of the above, if it pushes beyond the left margin, use the left margin.
if (XOffset < (float)itemInfo.MyDocStyle.Layout.LeftMargin)
XOffset = XOffsetBox = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
}
private float AdjustForBlankLines()
{
if (MyItemInfo.MyDocStyle.SpecialStepsFoldout) return 0;
int everyNLines = MyItemInfo.FormatStepData == null ? 1 : MyItemInfo.FormatStepData.StepLayoutData.EveryNLines ?? 1;
if (MyItemInfo.Ordinal % everyNLines == 0 || MyItemInfo.NextItem == null) return SixLinesPerInch;
return 0;
}
private void AddMacros(ItemInfo itemInfo, vlnTab mytab)
{
float y = YOffset;
float x = mytab == null ? XOffset : mytab.XOffset + mytab.TabOffset;
List<Macro> myMacros = itemInfo.MyMacros;
if (myMacros != null)
{
foreach (Macro myMacro in myMacros)
{
PartsLeft.Add(new vlnMacro(x, y, myMacro.MacroDef));
}
}
}
// HLP Change bar flags in format file:
// Locations: With Text, Outside Box, AER on Left RNO on Right, To The Left of Text
// Text: Date & Change ID, Revision Number, Change ID, None, Custom (use input data)
// Flag AERChgBarMsgRNOChgBarNoMsg and AERMsgRNONoMsg are NOT Used in 16-bit.
private string cbMess = null;
private vlnChangeBar DoChangeBar(PdfContentByte cb, ItemInfo itemInfo, VlnSvgPageHelper myPageHelper, float xoff, float yoff, int maxRNO, FormatInfo formatInfo) //, vlnChangeBar myCB)
{
// find column for the change bar based on format flags - this is code from 16-bit
// if AbsoluteFixedChangeColumn
// if FixedAERChangeColumn
// if col>ColsS+ColR+COL_WID+ADJ
// FixedChangeColumn
// else
// AERLeftChangeBarLocation()
// else
// FixedChangeColumn
// else
// ChangeBarLocation()
ChangeBarData cbd = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData;
float cols = formatInfo.MyStepSectionLayoutData.ColS ?? 0;
float colr = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
// FixedChangeColumn + - Column location for change bars
// 0 - Separate AER and RNO change bars to the right of the text
// -10 to -1 - Change bars on left (specify # of columns from the text)
// <-10 - AER change bars on the left and RNO change bars on the right.
// FixedAERChangeColumn overrides the -5 default setting in chgbar.c, value is converted to a negative by the code
float col = (cbd.AbsoluteFixedChangeColumn) ?
((cbd.FixedAERChangeColumn ?? 0) > 0) ?
(xoff > (cols + colr + COL_WID_ADJ)) ?
cbd.FixedChangeColumn ?? 0 : AERLeftChangeBarLocation(formatInfo) :
cbd.FixedChangeColumn ?? 0 : ChangeBarLocation(xoff, this, formatInfo, maxRNO);
if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.ChgID)
cbMess = itemInfo.MyContent.UserID;
else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.DateChgID)
{
string fmtDate = itemInfo.MyContent.DTS.ToShortDateString();
if (fmtDate.Length != 10) // need to add zeros
{
if (fmtDate.IndexOf("/") == 1)
fmtDate = "0" + fmtDate;
if (fmtDate.IndexOf("/", 3) == 1)
fmtDate = fmtDate.Substring(0, 3) + "0" + fmtDate.Substring(3, fmtDate.Length - 3);
}
cbMess = itemInfo.MyContent.UserID + @"\n" + fmtDate;
}
else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.RevNum)
cbMess = myPageHelper.Rev;
else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.UserDef)
cbMess = myPageHelper.ChangeBarDefinition.MyChangeBarMessage;
int msgAlign = Element.ALIGN_LEFT;
if (myPageHelper.ChangeBarDefinition.MyChangeBarLoc == PrintChangeBarLoc.LeftOfText ||
(myPageHelper.ChangeBarDefinition.MyChangeBarLoc == PrintChangeBarLoc.AERleftRNOright &&
!itemInfo.IsInRNO)) msgAlign = Element.ALIGN_RIGHT;
return new vlnChangeBar(cb, this, (float)itemInfo.MyDocStyle.Layout.LeftMargin + (col * itemInfo.FormatStepData.Font.CharsToTwips), yoff, msgAlign);
}
private int ChangeBarLocation(float c, vlnParagraph paragraph, FormatInfo formatInfo, int maxRNO)
{
int fixedChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedChangeColumn ?? 0;
float cols = formatInfo.MyStepSectionLayoutData.ColS ?? 0;
int colr = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
float tmpc = c;
if (MyItemInfo.IsCaution || MyItemInfo.IsNote)
{
// Temporary fix for change bars on Notes and Cautions where the FixedChgCol < -10
tmpc = (float)formatInfo.MyStepSectionLayoutData.ColT + (float)formatInfo.MyStepSectionLayoutData.WidT; // end position of Caution / Note
int typ = (int)(MyItemInfo.MyContent.Type % 10000);
int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
if (bxIndx != null)
{
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
if (bx != null)
tmpc = (float)bx.Start + (float)bx.End; // end position of a boxed Caution / Note
}
}
// if this is a caution or note, put the change bar to the right of the text:
//if ((paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote) && fixedChgCol < -10) return -fixedChgCol;
if ((fixedChgCol == 0))// && paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote)
//if ((fixedChgCol==0) || paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote)
{
float rightEdge = (paragraph.XOffset + paragraph.Width + 5);
rightEdge-=(float)paragraph.MyItemInfo.MyDocStyle.Layout.LeftMargin;
rightEdge = rightEdge/paragraph.MyItemInfo.FormatStepData.Font.CharsToTwips;
return (int)rightEdge;
}
if (fixedChgCol < -10 || fixedChgCol >= 0)
return ((fixedChgCol > 0) ? fixedChgCol :
(fixedChgCol == 0) ? (int)c + 1 :
(tmpc > (cols + colr + COL_WID_ADJ)) ? -fixedChgCol :
//(c > (cols + colr + COL_WID_ADJ) || (MyItemInfo.IsCaution || MyItemInfo.IsNote)) ? -fixedChgCol :
AERLeftChangeBarLocation(formatInfo));
else
return (int)(fixedChgCol + (((c < cols + Width + colr) || TableTest()
|| MyItemInfo.IsCaution || MyItemInfo.IsNote) ? 0 : cols + colr)); // || (GetColumnMode() == 0)) ? 0 : cols + colr));
/* Change bars to left of text -- ColS+WidS+ColR is the end of RNO col*/
}
/*
** Centered tables whose width exceeds the end of the RNO column should
** still have their change bars printed on the left. This procedure checks
** to make sure the step is a table and that it is not an RNO.
*/
private bool TableTest()
{
return false;
//return ((s->Type == TABLE || s->Type == BORDERLESSTABLE) &&
//!(strchr((char *)&s->dbseq[2],RNO_MARKER)));
}
private float GetBottomYoff(float bottomY)
{
foreach (vlnParagraph child in ChildrenBelow)
{
if (child.YOffset > bottomY) bottomY = child.YOffset;
bottomY = child.GetBottomYoff(bottomY);
}
return bottomY;
}
private int AERLeftChangeBarLocation(FormatInfo formatInfo)
{
// use -5 default unless it is format specified
int fixedAERChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedAERChangeColumn ?? 0;
return (fixedAERChgCol != 0) ?
(fixedAERChgCol > 100) ?
(fixedAERChgCol % 100) : -fixedAERChgCol : -5;
}
private StringBuilder _RtfSB = null;
// return rtf and use for tab and other text
public string GetRtf(ItemInfo itemInfo)
{
_RtfSB = new StringBuilder();
DisplayText vlntxt = new DisplayText(itemInfo, E_EditPrintMode.Print, E_ViewMode.View, true, E_FieldToEdit.StepText, false);
System.Drawing.Font myFont = vlntxt.TextFont.WindowsFont;
if (!itemInfo.IsTable && StepRTB.MyFontFamily != null)
myFont = new System.Drawing.Font(StepRTB.MyFontFamily, myFont.Size, myFont.Style);
if (itemInfo.IsHigh && itemInfo.MyDocStyle.UndSpecialStepsFoldout) myFont = new System.Drawing.Font(myFont.FontFamily, myFont.Size, myFont.Style | FontStyle.Underline);
_RtfSB.Append(AddFontTable(myFont));
_RtfSB.Append(vlntxt.StartText);
_RtfSB.Append("}");
return _RtfSB.ToString();
}
private float _XOffsetBox = 0;
public float XOffsetBox
{
get { return _XOffsetBox; }
set { _XOffsetBox = value; }
}
private float SetHeader(vlnParagraph para, PdfContentByte cb, ItemInfo itemInfo, FormatInfo formatInfo)
{
float xoff = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
// The '6' below is really converting from characters to Twips. But instead of considering the CPI, 16bit assumed
// it was 12 to center the header. That's where the 6 comes from.
float hdrWidth = (itemInfo.MyHeader.CleanText == null) ? 0 : itemInfo.MyHeader.CleanText.Length * 6;
int typ = ((int)itemInfo.MyContent.Type) % 10000;
int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
if (itemInfo.MyHeader.Justify == System.Drawing.ContentAlignment.MiddleCenter)
{
if (bxIndx != null)
{
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
if (bx.TabPos > 0)
xoff += (float)bx.TabPos; // xoff starts as left margin
else
xoff += (float)((bx.TxtStart + XOffsetBox + (bx.TxtWidth / 2)) - (hdrWidth / 2)); // xoff starts as left margin
}
else if (formatInfo.MyStepSectionLayoutData.Separator.Location > 0)
xoff = XOffset + AdjustToCharPosition((float)((para.Width - hdrWidth) / formatInfo.MyStepSectionLayoutData.Separator.Location), itemInfo.MyHeader.MyFont.CPI);
else
xoff = XOffset + (para.Width / 2) + (hdrWidth / 2); // XOffset has left margin included
}
else
xoff = XOffset; // XOffset has left margin included
vlnHeader myHeader = new vlnHeader(this, cb, itemInfo.MyHeader.Text, itemInfo.MyHeader.CleanText.TrimStart(" ".ToCharArray()), xoff, YOffset, itemInfo.MyHeader.MyFont);
PartsAbove.Add(myHeader);
return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout ? SixLinesPerInch : 0);
}
private float AdjustToCharPosition(float position, float? CPI)
{
int iPosition = (int)position;
int charsToTwips = (int)(72 / (CPI ?? 12));
iPosition = (iPosition / charsToTwips) * charsToTwips;
position = (position / 7.2F) * 7.2F;
return (float)iPosition;
}
private bool _SectionPageBreak = false;
public bool SectionPageBreak
{
get { return _SectionPageBreak; }
set { _SectionPageBreak = value; }
}
private bool _Processed = false;
public bool Processed
{
get { return _Processed; }
set { _Processed = value; }
}
private vlnParagraph _LastRNO;
public vlnParagraph LastRNO
{
get { return _LastRNO; }
set { _LastRNO = value; }
}
private vlnParagraph _MyTopRNO;
public vlnParagraph MyTopRNO
{
get { return _MyTopRNO; }
set { _MyTopRNO = value; }
}
private static string _Prefix = "";
public static string Prefix
{
get { return vlnParagraph._Prefix; }
set { vlnParagraph._Prefix = value; }
}
protected float _YBottomMost; // Bottom of the paragraph including the children
public float YBottomMost
{
get { return _YBottomMost; }
set { _YBottomMost = value; }
}
protected float _YTopMost; // Top of the paragraph including the children
public float YTopMost
{
get { return _YTopMost; }
set { _YTopMost = value; }
}
protected float _YTop; // Top of the paragraph including parts
public float YTop
{
get { return _YTop; }
set
{
vlnParagraph vp = this as vlnParagraph;
_YTop = value;
}
}
public float YSize // How big this paragraph is with all of its children
{
get { return _YBottomMost - _YTopMost; }
}
private ItemInfo _MyItemInfo;
public ItemInfo MyItemInfo
{
get { return _MyItemInfo; }
set { _MyItemInfo = value; }
}
private vlnParagraph _MyHighLevelParagraph;
public vlnParagraph MyHighLevelParagraph
{
get
{
if (_MyHighLevelParagraph == null)
{
_MyHighLevelParagraph = GetHighLevelParagraph();
}
return _MyHighLevelParagraph;
}
}
private vlnParagraph GetHighLevelParagraph()
{
if (MyItemInfo.IsHigh) return this;
return MyParent.GetHighLevelParagraph();
}
// Tab, Separator, ChangeBar, Box, Circle, Checkoff
private vlnPrintObjects _PartsAbove;
public vlnPrintObjects PartsAbove
{
get
{
if (_PartsAbove == null) _PartsAbove = new vlnPrintObjects();
return _PartsAbove;
}
}
private vlnPrintObjects _PartsBelow;
public vlnPrintObjects PartsBelow
{
get
{
if (_PartsBelow == null) _PartsBelow = new vlnPrintObjects();
return _PartsBelow;
}
}
private vlnPrintObjects _PartsRight;
public vlnPrintObjects PartsRight
{
get
{
if (_PartsRight == null) _PartsRight = new vlnPrintObjects();
return _PartsRight;
}
}
private vlnPrintObjects _PartsLeft;
public vlnPrintObjects PartsLeft
{
get
{
if (_PartsLeft == null) _PartsLeft = new vlnPrintObjects();
return _PartsLeft;
}
}
private vlnPrintObjects _PartsContainer;
public vlnPrintObjects PartsContainer
{
get
{
if (_PartsContainer == null) _PartsContainer = new vlnPrintObjects();
return _PartsContainer;
}
}
private vlnParagraphs _ChildrenAbove;
public vlnParagraphs ChildrenAbove
{
get
{
if (_ChildrenAbove == null) _ChildrenAbove = new vlnParagraphs(this);
return _ChildrenAbove;
}
}
private vlnParagraphs _ChildrenBelow;
public vlnParagraphs ChildrenBelow
{
get
{
if (_ChildrenBelow == null) _ChildrenBelow = new vlnParagraphs(this);
return _ChildrenBelow;
}
}
private vlnParagraphs _ChildrenRight;
public vlnParagraphs ChildrenRight
{
get
{
if (_ChildrenRight == null) _ChildrenRight = new vlnParagraphs(this);
return _ChildrenRight;
}
}
private vlnParagraphs _ChildrenLeft;
public vlnParagraphs ChildrenLeft
{
get
{
if (_ChildrenLeft == null) _ChildrenLeft = new vlnParagraphs(this);
return _ChildrenLeft;
}
}
public void AdjustXOffsetForTab(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab)
{
float tabWidth = (myTab == null) ? 0 : myTab.Width;
if (itemInfo.IsStepSection)
{
if (formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Just == "PSLeft")
{
int level = 0;
ItemInfo iilvl = itemInfo;
while (!iilvl.IsProcedure)
{
level++;
iilvl = iilvl.MyParent;
}
level = level <= 2 ? 1 : level - 1;
if (level==1)
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (level * (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos);
else
XOffset = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[level].ColSByLevel;
}
return;
}
int typ = ((int)itemInfo.MyContent.Type) % 10000;
int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
float? colOvrd = formatInfo.PlantFormat.FormatData.StepDataList[typ].ColOverride;
if (bxIndx != null)
{
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
if (bx == null)
{
if ((colOvrd??0)!=0)
{
// 16-bit code subtracted the left margin
//xoff = ((float)colOvrd - (float)itemInfo.MyDocStyle.Layout.LeftMargin) - XOffset;
//XOffset += xoff;
//if (myTab != null) myTab.XOffset += xoff;
//xoff = MyParent.XOffset - myTab.XOffset;
//XOffset += xoff;
float tabOffset = (myTab == null?0: myTab.XOffset) - XOffset;
XOffset = (float)colOvrd;
if (myTab != null) myTab.XOffset = XOffset + tabOffset;
return;
}
else
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + tabWidth + XOffsetBox;
}
else
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)bx.TxtStart + tabWidth + XOffsetBox;
if (myTab != null) myTab.XOffset = XOffset - tabWidth;
}
else if (itemInfo.IsHigh)
{
float x = 0;
float xoff = 0;
if ((colOvrd??0)!=0)
x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)colOvrd;
else
x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
xoff = x - XOffset;
// ColSByLevel will specify the column in which the High Level Step starts with
// respect to the overall level calculation based on sections & meta-sections.
// Only a few of the single column formats use this: WCN1, CAL1, RGEBCK
if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel
&& !(itemInfo.MyDocStyle.SpecialStepsFoldout && itemInfo.MyDocStyle.UseColSByLevel))
{
int indxLevel = itemInfo.PrintLevel + itemInfo.CurrentSectionLevel();
float colsbylevel = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].ColSByLevel;
float seclvlindent = colsbylevel - (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS + seclvlindent;
xoff = x - XOffset;
if (myTab != null) myTab.XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + colsbylevel;
LeftJustifyList jstlst = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList;
if (jstlst.Count > 0)
{
float leftJustifyTabSize = jstlst[indxLevel % jstlst.Count].Size ?? 0;
XOffset = myTab.XOffset + leftJustifyTabSize;
}
else
XOffset = myTab.XOffset + (myTab.Text.Length * (float)itemInfo.FormatStepData.Font.CPI) - colsbylevel;
}
else
{
XOffset += xoff;
if (myTab != null)
{
myTab.XOffset += xoff;
if (myTab.MyMacro != null) myTab.MyMacro.XOffset += xoff;
}
}
}
else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh)
{
// don't adjust for rno
}
else if (MyParent != null)
{
if (myTab != null && itemInfo.IsSequential && formatInfo.PlantFormat.FormatData.SectData.UseMetaSections && formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList.Count > 0)
{
int indxLevels = itemInfo.PrintLevel + itemInfo.CurrentSectionLevel(); // kbr -1;
LeftJustifyList jstlst = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList;
float tableftadj = 0;
foreach (LeftJustify lj in jstlst)
{
if (lj.Index == indxLevels)
{
tableftadj = lj.Size ?? 0;
break;
}
}
// the order of this is important. First adjust the tab's xoffset for the width of
// the tab. The offset of text needs to be adjusted by the 'leftjustify' format variable
// if it existed for this level.
myTab.XOffset += tabWidth;
if (tableftadj != 0 && myTab.Width<tableftadj)
tabWidth = myTab.Width = tableftadj;
XOffset += tabWidth;
myTab.Rtf = myTab.Rtf.Replace(myTab.Text, myTab.Text.TrimStart(" ".ToCharArray()));
Width = MyParent.Width - myTab.Width;
}
else // if no left justify, right align the tab
{
XOffset += tabWidth - (myTab == null ? 0 : myTab.TabAlign);
if (myTab != null) myTab.XOffset += tabWidth - myTab.TabAlign;
}
}
}
public void AdjustWidth(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab)
{
int typ = ((int)itemInfo.MyContent.Type) % 10000;
int? bxIndx = itemInfo.IsStep ? formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex : null;
float? widOvrd = 0;
float xwid = 0;
if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate && (xwid = GetWidthFromTemplate(itemInfo, formatInfo))>0)
widOvrd = xwid;
else
widOvrd = itemInfo.FormatStepData == null ? null : itemInfo.FormatStepData.WidthOverride;
if ((widOvrd??0) != 0)
{
Width = (float)widOvrd;
// if there's a box, we may need to do an adjustment on the width, if the tab data was changed
// so don't return.
if (bxIndx == null) return;
}
float tabWidth = (myTab == null) ? 0 : myTab.Width;
if (bxIndx != null)
{
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
if (bx == null)
{
// NOT SURE IF WE NEED TO TEST FOR THE NULLBOX FORMAT FLAG, MAYBE "bx == null" IS THE SAME THING
//if (formatInfo.MyStepSectionLayoutData.NullBox)
Width = (float)formatInfo.MyStepSectionLayoutData.WidT - tabWidth;
}
else
Width = _WidthAdjustBox + (float)bx.TxtWidth - tabWidth; // add 1 to get it to wrap like 16Bit
}
else if (itemInfo.IsHigh)
{
float CheckOffAdj = 0;
if (itemInfo.MyDocStyle.UseCheckOffs)
{
if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment != null)
CheckOffAdj = -(float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment;
if (!HasCheckOffHeading(itemInfo, formatInfo) && CheckOffAdj < 0)
CheckOffAdj += (float)(9 * 7.2); // 9 is the size of the SIGNOFF adjustment
}
float adjwidth = CheckOffAdj;
SectData sd = formatInfo.PlantFormat.FormatData.SectData;
if (sd.UseMetaSections)
{
if (sd.StepSectionData.StepSectionLayoutData.TieTabToLevel)
{
if (itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
&& !itemInfo.MyDocStyle.CancelSectTitle
&& !(itemInfo.MyDocStyle.SpecialStepsFoldout && itemInfo.MyDocStyle.UseColSByLevel))
{
int indxLevel = itemInfo.PrintLevel + itemInfo.CurrentSectionLevel();
adjwidth += formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].WidSAdjByLevel ?? 0; ;
float colsbylevel = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].ColSByLevel;
float seclvlindent = colsbylevel - (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
adjwidth -= seclvlindent;
adjwidth -= AdjustForSectionLevelTab();
}
}
else
{
if (formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count > 0)
adjwidth += (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[itemInfo.PrintLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].ColSByLevel;
}
}
Width = ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
Width += _WidthAdjust;
Width += adjwidth;
}
else if (itemInfo.IsCaution || itemInfo.IsNote)
{
float mycolT = (float)formatInfo.MyStepSectionLayoutData.ColT;
Width = (float)formatInfo.MyStepSectionLayoutData.WidT - 6 - mycolT;
XOffset += mycolT; // adjust caution/note text position
if (PartsLeft != null)// adjust tab position
foreach(vlnPrintObject vpo in PartsLeft)
vpo.XOffset += mycolT;
}
else if (itemInfo.IsSection)
{
Width = _WidthAdjust + ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
}
else if (MyParent == null)
{
// 72 points / inch - 7 inches (about width of page)
Width = 72 * 7;
}
else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh)
{
Width = MyParent.Width;
}
else if (itemInfo.IsTablePart)
{
Width = 72 * 7; // TODO: Need to determine the Width of the Table based upon the contents
}
else if (itemInfo.MyParent.IsCaution || itemInfo.MyParent.IsNote)
{
Width = MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign);
Width -= 72 * (itemInfo.FormatStepData.CautionOrNoteSubstepIndent == null ? 0 : (float)itemInfo.FormatStepData.CautionOrNoteSubstepIndent / (float)itemInfo.FormatStepData.Font.CPI);
}
else
{
float adjwidth = 0;
Width = adjwidth + MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign);
}
}
private float GetWidthFromTemplate(ItemInfo itemInfo, FormatInfo formatInfo)
{
float rtnwid = 0;
int tpIndx = GetSmartTemplateIndex(itemInfo, itemInfo.MyContent.Type, formatInfo);
if (tpIndx != -1)
{
int ncol = formatInfo.PlantFormat.FormatData.Templates[tpIndx].width;
// now convert to the units for this format. The template width data is in number of columns.
rtnwid = ncol * itemInfo.FormatStepData.Font.CharsToTwips;
}
return rtnwid;
}
private int GetSmartTemplateIndex(ItemInfo itemInfo, int? type, FormatInfo formatInfo)
{
int indx = 0;
// find the starting template in the list for the high level step type:
int highType = (int)itemInfo.MyHLS.MyContent.Type-20001;
while (indx < formatInfo.PlantFormat.FormatData.Templates.Count)
{
// level of 0 starts a new group.
if (formatInfo.PlantFormat.FormatData.Templates[indx].level == 0)
{
indx++;
// now see if we're on the high level step type, if so, look under this one
// for the step type that we're on. If found return the index of it.
if (formatInfo.PlantFormat.FormatData.Templates[indx].type == highType)
{
indx++;
while (indx < formatInfo.PlantFormat.FormatData.Templates.Count && formatInfo.PlantFormat.FormatData.Templates[indx].level != 0)
{
if (formatInfo.PlantFormat.FormatData.Templates[indx].type == type - 20001)
return indx;
indx++;
}
}
}
else
indx++;
}
return -1; // didn't find this step type in the template width override list.
}
private float AdjustForSectionLevelTab()
{
string sectTab = MyItemInfo.ActiveSection.MyTab.CleanText.TrimEnd();
if (sectTab.EndsWith(".0")) return 0;
string myTab = MyItemInfo.MyTab.CleanText;
// -1 below code, +1 for '.' and -2 for standard wid of tab
// standard wid of this tab is 2 (ex: '1.')
// so adjust width if longer than normal
return (float)(sectTab.Length - 1) * 72/(float)MyItemInfo.FormatStepData.Font.CPI;
}
private bool HasCheckOffHeading(ItemInfo itemInfo, FormatInfo formatInfo)
{
if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList.Count != 0)
{
// does this section have a check off heading?
SectionConfig sc = itemInfo.MyActiveSection.MyConfig as SectionConfig;
if (sc != null && sc.Section_CheckoffHeaderSelection > 0) return true;
}
return false;
}
private bool UseCheckOffsDocStyle(int oldToNew, FormatInfo formatInfo)
{
int bit, retval=0;
int mask=1;
for(bit=0; bit < 32; bit++){
if ((oldToNew & mask) != 0 && ((int)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.UseCheckOffsIn & mask) !=0) retval = 1;
mask <<= 1;
}
return retval > 0;
}
}
/// <summary>
/// First order by stepLevel, then within a stepLevel, order by descending yLocation on page.
/// Want to find maximum y value that fits on page, i.e. put the most on page that can
/// fit which is defined by the largest yLocation
/// </summary>
public class StepLevelList : SortedDictionary<int, SortedDictionary<float, vlnParagraph>>
{
public StepLevelList() : base()
{
}
public void Add(int stepLevel, float yLocation, vlnParagraph para)
{
if (stepLevel == 0) return;
if (!this.ContainsKey(stepLevel))
this.Add(stepLevel, new SortedDictionary<float, vlnParagraph>());
// using a negative for yLocation so that its in descending order:
if (!this[stepLevel].ContainsKey(-yLocation))
this[stepLevel].Add(-yLocation, para);
}
}
public class ParagraphLocations : List<ParagraphLocation>
{
public ParagraphLocations()
: base()
{
}
public void Add(vlnParagraph myParagraph, float yTopMost)
{
ParagraphLocation foundOverlap = FindOverlap(myParagraph);
if (foundOverlap == null)
{
this.Add(new ParagraphLocation(yTopMost,myParagraph));
return;
}
ParagraphLocation doubleOverlap = FindOverlap(foundOverlap);
while (doubleOverlap != null)
{
doubleOverlap.Merge(foundOverlap);
this.Remove(foundOverlap);
foundOverlap = doubleOverlap;
doubleOverlap = FindOverlap(foundOverlap);
}
}
private ParagraphLocation FindOverlap(vlnParagraph myParagraph)
{
foreach (ParagraphLocation paraLoc in this)
if (paraLoc.Overlap(myParagraph))
return paraLoc;
return null;
}
private ParagraphLocation FindOverlap(ParagraphLocation myParaLoc)
{
foreach (ParagraphLocation paraLoc in this)
if (paraLoc != myParaLoc && paraLoc.Overlap(myParaLoc))
return paraLoc;
return null;
}
internal StepLevelList BuildStepLevelList()
{
StepLevelList myList = new StepLevelList();
foreach (ParagraphLocation paraLoc in this)
myList.Add(paraLoc.StepLevel, paraLoc.YTop, paraLoc.MyParagraph);
return myList;
}
}
public class ParagraphLocation
{
private float _YTop;
public float YTop
{
get { return _YTop; }
set { _YTop = value; }
}
private float _YBottom;
public float YBottom
{
get { return _YBottom; }
set { _YBottom = value; }
}
private int _StepLevel;
public int StepLevel
{
get { return _StepLevel; }
set { _StepLevel = value; }
}
private vlnParagraph _MyParagraph;
public vlnParagraph MyParagraph
{
get { return _MyParagraph; }
set { _MyParagraph = value; }
}
public ParagraphLocation(float yTopMost,vlnParagraph myParagraph)
{
MyParagraph =myParagraph;
YTop = myParagraph.YVeryTop - yTopMost;
YBottom = myParagraph.YBottom - yTopMost;
StepLevel = myParagraph.MyItemInfo.StepLevel;
}
public bool Overlap(vlnParagraph otherParagraph)
{
if (Between(otherParagraph.YTop, YTop, YBottom)) return true;
if (Between(otherParagraph.YBottom, YTop, YBottom)) return true;
if(Between(YTop,otherParagraph.YVeryTop,otherParagraph.YBottom)) return true;
if(Between(YBottom,otherParagraph.YVeryTop,otherParagraph.YBottom)) return true;
return false;
}
public static bool Between(float x, float lower, float higher)
{ return x >= lower && x <= higher; }
public bool Overlap(ParagraphLocation otherParagraphLocation)
{
if (Between(otherParagraphLocation.YTop, YTop, YBottom)) return true; // The top is within the other
if (Between(otherParagraphLocation.YBottom, YTop, YBottom)) return true; // The bottom is within the other
if(Between(YTop,otherParagraphLocation.YTop,otherParagraphLocation.YBottom)) return true; // the other top is within this one
if(Between(YBottom,otherParagraphLocation.YTop,otherParagraphLocation.YBottom)) return true;// I believe this is unnecessary
return false;
}
public void Merge(vlnParagraph otherParagraph)
{
if (StepLevel < otherParagraph.MyItemInfo.StepLevel) MyParagraph = otherParagraph;
YTop = Math.Min(YTop, otherParagraph.YVeryTop);
YBottom = Math.Max(YBottom, otherParagraph.YBottom);
StepLevel = Math.Max(StepLevel, otherParagraph.MyItemInfo.StepLevel);
}
public void Merge(ParagraphLocation otherParagraphLocation)
{
if (StepLevel < otherParagraphLocation.StepLevel) MyParagraph = otherParagraphLocation.MyParagraph;
YTop = Math.Min(YTop, otherParagraphLocation.YTop);
YBottom = Math.Max(YBottom, otherParagraphLocation.YBottom);
StepLevel = Math.Max(StepLevel, otherParagraphLocation.StepLevel);
}
}
}