using System; using System.Collections.Generic; using System.Text; using System.Drawing; using iTextSharp.text.pdf; using iTextSharp.text; using VEPROMS.CSLA.Library; namespace Volian.Print.Library { public class vlnChangeBarMessage { private float _ParentX; public float ParentX { get { return _ParentX; } set { _ParentX = value; } } private string _Message; public string Message { get { return _Message; } set { _Message = value; } } private static int _UniqueMessageId = 0; public static int UniqueMessageId { get { return vlnChangeBarMessage._UniqueMessageId++; } set { vlnChangeBarMessage._UniqueMessageId = value; } } private int _MessageId = UniqueMessageId; public int MessageId { get { return _MessageId; } set { _MessageId = value; } } public vlnChangeBarMessage(float parentx, string msg) { _ParentX = parentx; _Message = msg; } } public partial class vlnChangeBar : vlnPrintObject { private bool _HasChangeBar; public bool HasChangeBar { get { return _HasChangeBar; } set { _HasChangeBar = value; } } protected float _YChangeBarBottom; public float YChangeBarBottom { get { if (_YChangeBarBottom == 0F) _YChangeBarBottom = _YOffset - _Height; return _YChangeBarBottom; } set { _YChangeBarBottom = value; _Height = _YOffset - _YChangeBarBottom; } } private SortedDictionary _Messages; public SortedDictionary Messages { get { return _Messages; } set { _Messages = value; } } private int _MessageAlignment; public int MessageAlignment { get { return _MessageAlignment; } set { _MessageAlignment = value; } } private float _YExtendLine = 4.75F; public float YExtendLine { get { return _YExtendLine; } set {_YExtendLine = value; } } public float YChangeBarBottomExtend { get {return YChangeBarBottom - YExtendLine; } } private bool _BottomIsTable = false; public bool BottomIsTable { get { return _BottomIsTable; } set { _BottomIsTable = value; } } private bool _IsRev; private bool _MsgAtTop; // flags that message should be drawn at top of change bar public vlnChangeBar(PdfContentByte cb, vlnParagraph parent, float xoff, float yoff, int msgAlignment, bool isRev, bool msgAtTop) { // for grids, a y adjustment is made to match 16bit output, see the variable 'GridTopAdjust'. Take this // adjustment into account for the change bar. 6.5 positioned the change bar to match 16bit output. if (parent.MyItemInfo.MyContent.MyGrid != null) yoff -= 6.5F; MyContentByte = cb; XOffset = xoff; YOffset = yoff; MyParent = parent; _IsRev = isRev; _MsgAtTop = msgAtTop; Messages = new SortedDictionary(); // if there is an RNO separator, add the separator's height in too. float scale = parent.MyItemInfo.IsRtfRaw ? 0.6f : 1; // use scale for equations (B2016-265) Height = (scale * parent.Height) * MyPageHelper.YMultiplier; // B2017-102, removed the extra line (was making changebar to long) foreach (vlnPrintObject vpo in parent.PartsBelow) { if (vpo is vlnRNOSeparator) { // see if any of children don't have changebar if ((vpo as vlnRNOSeparator).ExtendChangeBar) _YExtendLine = (vpo.Height + vpo.YOffset - ((scale * parent.Height) + parent.YOffset)) * MyPageHelper.YMultiplier; } } foreach (vlnPrintObject vph in parent.PartsAbove) { if (vph is vlnHeader) { string sep = parent.MyItemInfo.MyHeader == null ? "" : parent.MyItemInfo.MyHeader.CleanText; vlnHeader tmp = vph as vlnHeader; // if the part above is not the same type and it's a Note or Caution and the OnlyBulletSameCautionNoteType is true // don't extend the change bar to the item above if (!parent.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.OnlyBulletSameCautionNoteType || ((parent.MyItemInfo.IsCaution || parent.MyItemInfo.IsNote) && (parent.MyItemInfo.MyContent.Type != vph.MyParent.MyItemInfo.MyContent.Type))) { // the separator must exist and the previous must have a change bar. if ((sep != "") && (tmp.Text == sep) && parent.MyItemInfo.MyPrevious != null && parent.MyItemInfo.MyPrevious.HasChangeBar) { if (MyPageHelper.MyParagraphs.ContainsKey(parent.MyItemInfo.MyPrevious.ItemID)) { vlnParagraph prev = MyPageHelper.MyParagraphs[parent.MyItemInfo.MyPrevious.ItemID]; float delta = parent.YOffset - prev.YOffset; _YOffset += delta; _Height += delta; } else if (parent.PartsAbove.Count > 0) { float delta = parent.YOffset - parent.PartsAbove[0].YOffset; _YOffset += delta; _Height += delta; } } } } } _MessageAlignment = msgAlignment; } public override string ToString() { return string.Format("vlnChangeBar: X={0} Y={1} H={2} B={3} ID={4}", XOffset, YOffset, Height, YChangeBarBottom, MyParent.MyItemInfo.ItemID); } public override float ToPdf(PdfContentByte cb, float yPageStart, ref float yTopMargin, ref float yBottomMargin) { float? topMost = null; cb.SaveState(); // for bug fix B2015-159 // Ginna reported an instance where a change bar started printing inside the page header box // in their Abnornal procedures AP-SG.1 step 41.b RNO which continued onto the next page // calculate a new starting position for the change bar if (_MyParent is vlnParagraph) { vlnParagraph pgh = _MyParent as vlnParagraph; topMost = cb.PdfWriter.PageSize.Height - (float)pgh.MyItemInfo.MyDocStyle.Layout.TopMargin; } VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; PdfLayer textLayer = _MyPageHelper == null ? null : _MyPageHelper.TextLayer; if (textLayer != null) cb.BeginLayer(textLayer); float yAdj = -3.75F; //0.5F; float xAdj = 3F; //cb.SetColorStroke(Color.GREEN); // TODO: Should default to black iTextSharp.text.Color changeBarColor = new iTextSharp.text.Color(PrintOverride.OverrideChangeBarColor(System.Drawing.Color.Black)); cb.SetColorStroke(changeBarColor); cb.SetLineWidth(.5F); // for Bug Fix 2015-159 // reset the YOffset if up too high before printing the change bar if (topMost != null) YOffset = Math.Min(YOffset, (float)topMost); cb.MoveTo(XOffset + xAdj, YOffset - yAdj); // combination yStart and YOffset cb.LineTo(XOffset + xAdj, YChangeBarBottomExtend - yAdj - 1); cb.Stroke(); DebugPdf(cb, XOffset + xAdj - 1.5F, YOffset - yAdj + 4); DebugPdf(cb, XOffset + xAdj - 1.5F, YChangeBarBottomExtend - yAdj - 1); if (Messages != null) { // if doing messages at top, then remove duplicates if they are next to each other. // If this was not done, the location of messages was not correct. if (_MsgAtTop && Messages.Count > 1) { string lastNoDup = ""; SortedDictionary tmpNoDup = new SortedDictionary(); foreach (KeyValuePair nodupM in Messages) { vlnChangeBarMessage noDupCmb = (vlnChangeBarMessage)nodupM.Value; if (lastNoDup != noDupCmb.Message) tmpNoDup.Add(nodupM.Key, noDupCmb); lastNoDup = noDupCmb.Message; } Messages = tmpNoDup; } // Loop through messages for this change bar. The first message is the bottom-most, which is always put out. // Working up, if the current message is the same as the one below it, don't put it out. string lastMsg = null; int incrementMsgAtTop = (Messages == null ? 0 : Messages.Count-1); foreach (KeyValuePair kvp in Messages) { float yBottom = (float)System.Convert.ToDouble(kvp.Key); vlnChangeBarMessage vcbm = (vlnChangeBarMessage)kvp.Value; if (lastMsg != vcbm.Message) { // use bigger font if revnum msg // 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 B21017-117 //iTextSharp.text.Font iFont = _IsRev? Volian.Svg.Library.VolianPdf.GetFont(new System.Drawing.Font("Letter Gothic", 10F)): // Volian.Svg.Library.VolianPdf.GetFont(new System.Drawing.Font("Letter Gothic", 5.5F)); iTextSharp.text.Font iFont = _IsRev? Volian.Svg.Library.VolianPdf.GetFont(VE_Font.GetWinSysFont("Letter Gothic", 10F)): Volian.Svg.Library.VolianPdf.GetFont(VE_Font.GetWinSysFont("Letter Gothic", 5.5F)); Chunk chk = new Chunk(vcbm.Message.IndexOf(@"\n") > -1 ? vcbm.Message.Substring(0, vcbm.Message.IndexOf(@"\n")) : vcbm.Message, iFont); Paragraph myparagraph = new Paragraph(chk); if (vcbm.Message.IndexOf(@"\n") > -1) { myparagraph.Add(Chunk.NEWLINE); myparagraph.Add(new Chunk(vcbm.Message.Substring(vcbm.Message.IndexOf(@"\n") + 2, vcbm.Message.Length - vcbm.Message.IndexOf(@"\n") - 2), iFont)); } myparagraph.Alignment = MessageAlignment; myparagraph.Leading = iFont.Size; float w = GetTableWidth(cb, myparagraph, MyParent.MyItemInfo.MyDocStyle.Layout.PageWidth); float h = GetParagraphHeight(cb, myparagraph, string.Empty, w); cb.SetColorFill(changeBarColor); float yloc = yBottom + h - Rtf2Pdf.Offset.Y + 2.7F; if (_MsgAtTop) { yloc = YOffset - ((incrementMsgAtTop * h)); // + 2); incrementMsgAtTop--; } Rtf2Pdf.TextAt(cb, myparagraph, XOffset + xAdj - Rtf2Pdf.Offset.X + 3, yloc, w, h, "", yBottomMargin); lastMsg = vcbm.Message; } } } if (textLayer != null) cb.EndLayer(); cb.RestoreState(); return yPageStart; } } }