SourceCode/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs
2011-07-14 16:16:06 +00:00

912 lines
32 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.factories;
using Volian.Svg.Library;
using System.Text.RegularExpressions;
using System.Xml;
using VEPROMS.CSLA.Library;
namespace Volian.Print.Library
{
public class VlnSvgPageHelper:SvgPageHelper
{
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// This handles Page Breaks within a Step
private List<vlnParagraph> _ParaBreaks = new List<vlnParagraph>();
public List<vlnParagraph> ParaBreaks
{
get { return _ParaBreaks; }
set { _ParaBreaks = value; }
}
private PageBookmarks _PageBookmarks = new PageBookmarks();
public PageBookmarks PageBookmarks
{
get { return _PageBookmarks; }
set { _PageBookmarks = value; }
}
private PdfOutline _MyPdfOutline = null;
public PdfOutline MyPdfOutline
{
get { return _MyPdfOutline; }
set { _MyPdfOutline = value; }
}
private vlnText _TopMessage;
public vlnText TopMessage
{
get { return _TopMessage; }
set { _TopMessage = value; }
}
private vlnText _BottomMessage;
public vlnText BottomMessage
{
get { return _BottomMessage; }
set { _BottomMessage = value; }
}
Dictionary<int, vlnParagraph> _MyParagraphs = new Dictionary<int, vlnParagraph>();
public Dictionary<int, vlnParagraph> MyParagraphs
{
get { return _MyParagraphs; }
set { _MyParagraphs = value; }
}
float _YMultiplier = 1;
public float YMultiplier
{
get { return _YMultiplier; }
set { _YMultiplier = value; }
}
private PdfWriter _MyPdfWriter;
public PdfWriter MyPdfWriter
{
get { return _MyPdfWriter; }
set
{
MyPageCounts = new PageCounts();
_MyPdfWriter = value;
}
}
private PdfContentByte _MyPdfContentByte;
public PdfContentByte MyPdfContentByte
{
get { return _MyPdfContentByte; }
set { _MyPdfContentByte = value; }
}
public override void OnCloseDocument(PdfWriter writer, iTextSharp.text.Document document)
{
AddBookmarks(writer);
MyPageCounts.DrawTemplates();
}
public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document)
{
if (!OnFoldoutPage)
{
AddBookmarks(writer);
MyPageCounts.CanIncrement = true;
base.OnEndPage(writer, document);
DrawChangeBars(writer.DirectContent);
DrawMessages(writer.DirectContent);
if (!CreatingFoldoutPage)
DrawRuler(writer.DirectContent);
}
else
{
MyPageCounts.CanIncrement = true;
base.OnEndPage(writer, document);
if (!CreatingFoldoutPage)
DrawRuler(writer.DirectContent);
}
}
private void DrawRuler(PdfContentByte cb)
{
if (DebugLayer == null) return;
cb.SaveState();
cb.BeginLayer(DebugLayer);
float x = (cb.PdfWriter.PageSize.Left + cb.PdfWriter.PageSize.Right) / 2;
cb.SetLineWidth(.1F);
cb.SetColorStroke(new Color(System.Drawing.Color.CornflowerBlue));
float yTop = 648;
float yBottom = 48;
cb.MoveTo(x, yTop);
cb.LineTo(x, yBottom);
int i = 0;
for (float y = yTop; y >= yBottom; y -= 12)
{
float w = 10;
if (i % 10 == 0) w = 30;
else if (i % 5 == 0) w = 20;
i++;
cb.MoveTo(x - w, y);
cb.LineTo(x, y);
}
i = 0;
for (float y = yTop; y >= yBottom; y -= 10.1F)
{
float w = 10;
if (i % 10 == 0) w = 30;
else if (i % 5 == 0) w = 20;
i++;
cb.MoveTo(x + w, y-1);
cb.LineTo(x, y-1);
}
Layout layout = MySection.MyDocStyle.Layout;
cb.Rectangle((float)layout.LeftMargin, (float)(cb.PdfWriter.PageSize.Height - layout.TopMargin), (float)layout.PageWidth - (float)layout.LeftMargin, (float)-layout.PageLength);
float yRuler = 612;
cb.MoveTo(0, yRuler);
cb.LineTo(612, yRuler);
for (float x1 = 0; x1 < 612; x1 += 6) // tic marks every 1/8 inch
{
if (x1 % 72 == 0)
{
cb.MoveTo(x1, yRuler-20);
cb.LineTo(x1, yRuler+20);
}
else if (x1 % 36 == 0)
{
cb.MoveTo(x1, yRuler-10);
cb.LineTo(x1, yRuler+10);
}
else
{
cb.MoveTo(x1, yRuler-5);
cb.LineTo(x1, yRuler+5);
}
}
//cb.MoveTo(122.4F, 0); //WCN2 HLS
//cb.LineTo(122.4F, cb.PdfWriter.PageSize.Height);
//cb.MoveTo(78, 0); // HLP HLS
//cb.LineTo(78, cb.PdfWriter.PageSize.Height);
//cb.MoveTo(441, 0); // HLP cover page date
//cb.LineTo(441, cb.PdfWriter.PageSize.Height);
//cb.MoveTo(71.4F, 0); // WCN Purpose page, Revision: {REV}
//cb.LineTo(71.4F, cb.PdfWriter.PageSize.Height);
cb.Stroke();
cb.EndLayer();
cb.RestoreState();
}
private void AddBookmarks(PdfWriter writer)
{
foreach (PageBookmark pb in PageBookmarks)
{
if (!pb.MyItemInfo.IsSection && MyPdfOutline != null)
new PdfOutline(MyPdfOutline, pb.PdfDestination, pb.Title, false);
else
{
PdfDestination dest = new PdfDestination(PdfDestination.FIT);
MyPdfOutline = new PdfOutline(writer.DirectContent.RootOutline, dest, pb.Title, false);
}
}
PageBookmarks.Clear();
}
private void DrawMessages(PdfContentByte cb)
{
if (TopMessage != null)
{
TopMessage.ToPdf(cb, 0, 0, 0);
TopMessage = null; // Only output it once.
}
if (BottomMessage != null)
{
BottomMessage.ToPdf(cb, 0, 0, 0);
BottomMessage = null; // Only output it once.
}
}
private void DrawChangeBars(PdfContentByte cb)
{
foreach (vlnChangeBar vcb in MyChangeBars)
{
// TODO: Pass in zeroes because topdf is inherited.
vcb.ToPdf(cb, 0, 0, 0);
}
_MyChangeBars = new List<vlnChangeBar>();
}
#region SectionLevelData
private ChangeBarDefinition _ChangeBarDefinition;
public ChangeBarDefinition ChangeBarDefinition
{
get { return _ChangeBarDefinition; }
set { _ChangeBarDefinition = value; }
}
#endregion
private PdfLayer _TextLayer;
public PdfLayer TextLayer
{
get { return _TextLayer; }
set { _TextLayer = value; }
}
private PdfLayer _DebugLayer;
public PdfLayer DebugLayer
{
get { return _DebugLayer; }
set { _DebugLayer = value; }
}
private VEPROMS.CSLA.Library.SectionInfo _MySection;
public VEPROMS.CSLA.Library.SectionInfo MySection
{
get { return _MySection; }
set
{
_MySection = value;
MySectionTitle = ((_MySection.DisplayNumber ?? "")=="" ? "" : _MySection.DisplayNumber + " - ") + _MySection.DisplayText;
MySvg = BuildSvg(_MySection);
}
}
private string _MySectionTitle;
public string MySectionTitle
{
get { return _MySectionTitle; }
set { _MySectionTitle = value; }
}
private int _MaxRNO;
public int MaxRNO
{
get
{
if (_MaxRNO == 0) _MaxRNO = _MySection.ColumnMode;
return _MaxRNO;
}
}
private int _CurrentPageOf = 0;
public int CurrentPageOf
{
get { return _CurrentPageOf; }
set { _CurrentPageOf = value; }
}
private string _Rev = string.Empty;
public string Rev
{
get { return _Rev; }
set { _Rev = value; }
}
private string _RevDate = string.Empty;
public string RevDate
{
get { return _RevDate; }
set { _RevDate = value; }
}
private List<vlnChangeBar> _MyChangeBars = new List<vlnChangeBar>();
public List<vlnChangeBar> MyChangeBars
{
get { return _MyChangeBars; }
set { _MyChangeBars = value; }
}
public void AddChangeBar(vlnChangeBar vcb, string cbmess)
{
if (vcb == null) return;
vlnChangeBar prevCB = null;
foreach (vlnChangeBar cb in MyChangeBars)
{
// only look at changebars in same column
if (cb.XOffset == vcb.XOffset)
{
// if the two change bars end at same location, set prevCB which will
// adjust the length (top position) of the change bar. This condition
// also flags that the change bar texts overlap.
if (cb.YChangeBarBottom == vcb.YChangeBarBottom) prevCB = cb;
// continuous case, if changes bars overlap, adjust size and don't add new one to
// the MyChangeBars list.
if (MySection.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ContinuousChangeBars)
{
if (OverlapOrSpan(cb, vcb))
{
if (prevCB == null) prevCB = cb;
else if (prevCB.YChangeBarBottom > cb.YChangeBarBottom) prevCB = cb;
}
}
}
}
// if this and the prevCB overlap, adjust yoffset/height/ybottom in the prevCB so that both change bars are
// included in this Dictionary item. A new vlnChangeBar is not added to the MyChangeBars list, the current
// one that overlaps with the new is adjusted.
if (prevCB != null)
{
// Bottom for both change bars is same, adjust top (YOffset) and height.
if (prevCB.YChangeBarBottom == vcb.YChangeBarBottom)
{
prevCB.YOffset = Math.Max(prevCB.YOffset, vcb.YOffset);
float yChangeBarBottomExtend = prevCB.YChangeBarBottomExtend;
prevCB.Height = Math.Max(prevCB.Height, vcb.Height);
prevCB.YExtendLine = prevCB.YChangeBarBottom - Math.Min(yChangeBarBottomExtend, vcb.YChangeBarBottomExtend); //Math.Max(prevCB.YExtendLine, vcb.YExtendLine);
// if a change bar message at this ychangebarbottom exists, see which message is used
if (cbmess != null && prevCB.Messages.ContainsKey(prevCB.YChangeBarBottom)) UpdateCbMessage(cbmess, prevCB, vcb.XOffset);
return;
}
// Bottom locations are not the same, but another change bar is not added, i.e. the
// length of the line is adjusted.
prevCB.YOffset = Math.Max(prevCB.YOffset, vcb.YOffset);
float yChangeBarBottomExtend1 = prevCB.YChangeBarBottomExtend;
prevCB.YChangeBarBottom = Math.Min(prevCB.YChangeBarBottom, vcb.YChangeBarBottom);
prevCB.YExtendLine = prevCB.YChangeBarBottom - Math.Min(yChangeBarBottomExtend1, vcb.YChangeBarBottomExtend); //Math.Max(prevCB.YExtendLine, vcb.YExtendLine);
// Two messages at this location, determine which one to use
if (cbmess != null && prevCB.Messages.ContainsKey(prevCB.YChangeBarBottom)) UpdateCbMessage(cbmess, prevCB, vcb.XOffset);
// no message at this location, just add it.
else if (cbmess != null)
prevCB.Messages.Add(vcb.YChangeBarBottom, new vlnChangeBarMessage(vcb.MyParent.XOffset, cbmess));
return;
}
// There was no overlap, add a message if it exists, and then add the change bar to the MyChangeBars list.
if (cbmess != null) vcb.Messages.Add(vcb.YChangeBarBottom, new vlnChangeBarMessage(vcb.MyParent.XOffset, cbmess));
MyChangeBars.Add(vcb);
}
private static void UpdateCbMessage(string cbmess, vlnChangeBar prevCB, float xoff)
{
// If there are two messages at the same location, for example an AER change bar & and RNO
// change bar, and the messages have different text, see which change bar message should be
// added, i.e. use the one in 'rno', the greatest x value.
vlnChangeBarMessage tmp = prevCB.Messages[prevCB.YChangeBarBottom];
if (cbmess != tmp.Message)
{
if (xoff > tmp.ParentX)
{
prevCB.Messages.Remove(prevCB.YChangeBarBottom);
prevCB.Messages.Add(prevCB.YChangeBarBottom, new vlnChangeBarMessage(xoff, cbmess));
}
}
}
private bool OverlapOrSpan(vlnChangeBar cb, vlnChangeBar vcb)
{
if (cb.MyParent.MyItemInfo.MyHLS.ItemID != vcb.MyParent.MyItemInfo.MyHLS.ItemID) return false;
// cb.Yoffset is within range of vcb:
if (cb.YOffset <= vcb.YOffset &&
cb.YOffset >= (vcb.YChangeBarBottomExtend - vlnPrintObject.SixLinesPerInch)) return true;
// cb.YChangeBarBottom is within range of vcb:
if ((cb.YChangeBarBottomExtend-vlnPrintObject.SixLinesPerInch) <= vcb.YOffset &&
cb.YChangeBarBottomExtend >= (vcb.YChangeBarBottomExtend - vlnPrintObject.SixLinesPerInch)) return true;
// vcb.Yoffset is within range of cb:
if (vcb.YOffset <= cb.YOffset &&
vcb.YOffset >= (cb.YChangeBarBottomExtend - vlnPrintObject.SixLinesPerInch)) return true;
// vcb.YChangeBarBottom is within range of cb:
if ((vcb.YChangeBarBottomExtend - vlnPrintObject.SixLinesPerInch) <= cb.YOffset &&
vcb.YChangeBarBottomExtend >= (cb.YChangeBarBottomExtend - vlnPrintObject.SixLinesPerInch)) return true;
return false;
}
public VlnSvgPageHelper(VEPROMS.CSLA.Library.SectionInfo mySection) : base()
{
MySection = mySection;
}
private Volian.Svg.Library.Svg BuildSvg(VEPROMS.CSLA.Library.SectionInfo mySection)
{
VEPROMS.CSLA.Library.FormatInfo activeFormat = mySection.ActiveFormat;
VEPROMS.CSLA.Library.DocStyle docStyle = mySection.MyDocStyle;
Volian.Svg.Library.Svg mySvg = null;
mySvg = SvgSerializer<Volian.Svg.Library.Svg>.StringDeserialize(BuildMyText(activeFormat));
mySvg.ViewBox.Height = 1100;
mySvg.ViewBox.Width = 850;
mySvg.Height = new SvgMeasurement(11, E_MeasurementUnits.IN);
mySvg.Width = new SvgMeasurement(8.5F, E_MeasurementUnits.IN);
mySvg.LeftMargin = (float)docStyle.Layout.LeftMargin;
mySvg.TopMargin = 9.6F;
VEPROMS.CSLA.Library.PageStyle pageStyle = docStyle.pagestyle;
AddPageListItems(mySvg, pageStyle, mySection);
mySvg.ProcessText += new SvgProcessTextEvent(mySvg_ProcessText);
return mySvg;
}
public PageCounts MyPageCounts = null;
private static Regex regexFindToken = new Regex("{[^{}]*}");
private string mySvg_ProcessText(object sender, SvgProcessTextArgs args)
{
if (args.MyText == null) return string.Empty; // Needed for empty genmac text (was space in 16bit files)
if (!args.MyText.Contains("{"))
return args.MyText;
/*
* Check if tokens for handling page counts ({PAGE} {OF} etc). if so, do templates.
*/
if (args.MyText.Contains("{DOCCURPAGE}") || args.MyText.Contains("{DOCTOTPAGE}"))
{
string key = "DocCurPage." + MySection.ItemID;
string txt = args.MyText.Replace("{DOCCURPAGE}", "{PAGE}").Replace("{DOCTOTPAGE}", "{OF}");
MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, txt, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
return string.Empty;
}
if (args.MyText.Contains("{PAGE}") || args.MyText.Contains("{OF}"))
{
#region numberingseq
/*
public enum E_NumberingSequence : uint
{
NoPageNum = 0,
WithSteps = 1, Add to original steps section page count.
WithinEachDocStyle = 2,
WithinEachSection = 3,
WithinEachDocStyle1 = 4,
GroupedByPagination = 5,
GroupedByLevel = 6,
WithStepsAndSecondaryPageNumber = 7,
WithStepsAndSecondaryPageNumberGroupedByLevel = 8,
Like6_ButDoesntNeedSubsection = 9,
Like6_ButDoesntNeedSubsection1 = 10
};
*/
#endregion
// default for the key is to make it NumberingSequence. Then handle
// specific cases.
string key = ((int)MySection.MyDocStyle.NumberingSequence).ToString();
E_NumberingSequence numseq = MySection.MyDocStyle.NumberingSequence??0;
switch (numseq)
{
case E_NumberingSequence.WithSteps: // Number with 'originalstepsection'
ProcedureInfo pc = MySection.MyProcedure;
int sectid = 0;
foreach (SectionInfo si in pc.Sections)
{
SectionConfig sc = si.MyConfig as SectionConfig;
if (sc.Section_OriginalSteps == "Y")
{
sectid = si.ItemID;
break;
}
}
if (sectid != 0) key = (int)E_NumberingSequence.WithinEachSection + "." + sectid;
break;
case E_NumberingSequence.WithinEachDocStyle:
key = key + "." + MySection.ActiveFormat.FormatID + "." + MySection.MyDocStyle.Index;
break;
case E_NumberingSequence.WithinEachSection:
key = key + "." + MySection.ItemID;
break;
}
MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, args.MyText, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
return string.Empty;
}
return regexFindToken.Replace(args.MyText, new MatchEvaluator(ReplacePageListToken));
}
private string BuildMyText(VEPROMS.CSLA.Library.FormatInfo activeFormat)
{
string sGenMac = activeFormat.GenMac;
if (sGenMac == null || sGenMac == "")
{
// If subformat and does not have its own genmac, find an inherited genmac.
FormatInfo tmpf = FormatInfo.Get(activeFormat.ParentID);
while (tmpf.FormatID!=1 && (sGenMac==null||sGenMac==""))
{
sGenMac = tmpf.GenMac;
tmpf = FormatInfo.Get(tmpf.ParentID);
}
if (sGenMac == null || sGenMac == "") return "";
}
if (!sGenMac.Contains("xmlns"))
sGenMac = sGenMac.Replace("<svg ", "<svg xmlns='http://www.w3.org/2000/svg' ");
XmlDocument xDocGenMac = new XmlDocument();
xDocGenMac.LoadXml(sGenMac); // Add xmlns if necessary
Volian.Svg.Library.Svg mySvg = new Volian.Svg.Library.Svg();
SvgDefine def = new SvgDefine();
mySvg.Add(def);
def.ID = "GenMac Templates";
string str = SvgSerializer<Volian.Svg.Library.Svg>.StringSerialize(mySvg);
XmlDocument xDocPrintout = new XmlDocument();
xDocPrintout.LoadXml(str);
XmlNode xn = xDocPrintout.DocumentElement.ChildNodes[0];
xn.AppendChild(xDocPrintout.ImportNode(xDocGenMac.DocumentElement, true));
return xDocPrintout.OuterXml;
}
private string FirstAndLast(string token)
{
// strip the curly braces and return the first and last character
// For example Header1 becomes H1 and Box2 becomes B2
return token.Substring(1, 1) + token.Substring(token.Length - 2, 1);
}
private static Regex regexJustTokens = new Regex(@"^{([^{}]*}{)*[^{}]*}$");
private void AddPageListItems(Volian.Svg.Library.Svg mySvg, VEPROMS.CSLA.Library.PageStyle pageStyle, VEPROMS.CSLA.Library.SectionInfo section)
{
SvgGroup svgGroup = new SvgGroup();
foreach (VEPROMS.CSLA.Library.PageItem pageItem in pageStyle.PageItems)
{
MatchCollection matches = regexFindToken.Matches(pageItem.Token);
if (matches.Count>0)
{
foreach (Match match in matches)
{
string token = match.Value;
//token = Regex.Replace(token, @"[\xB3-\xDF]", " ");
switch (match.Value)
{
case "{HEADER1}":
case "{HEADER2}":
case "{HEADER3}":
case "{HEADER4}":
case "{HEADER5}":
case "{BOX1}":
case "{BOX2}":
case "{BOX3}":
case "{BOX4}":
case "{BOX5}":
case "{BOX6}":
case "{BOX7}":
case "{BOX8}":
case "{BOX9}":
svgGroup.Add(PageItemToSvgUse(pageItem, FirstAndLast(token)));
break;
case "{PMODEBOX}": // need to set either 1 or 2 depending on number of columns
string box = "1";
if (_MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.Four)
box = "4";
else if (_MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.Three)
box = "3";
else if (_MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.Two)
box = "2";
box = "{BOX" + box + "}";
svgGroup.Add(PageItemToSvgUse(pageItem, FirstAndLast(box)));
break;
case "{DRAFTPAGE}":
case "{REFERENCEPAGE}":
case "{MASTERPAGE}":
case "{SAMPLEPAGE}":
//mySvg.SetValidWaterMark(token, _Watermark); // Need logic to limit watermark to tokens.
break;
case "{PROCTITLE}":
case "{PROCTITLE1}":
case "{PROCTITLE2}":
float linelen = (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength * (float)pageItem.Font.CPI / 12;
SplitTitle(svgGroup, pageItem, section.MyProcedure.MyContent.Text, (int)linelen, token);
//SplitTitle(svgGroup, pageItem, section.MyProcedure.MyContent.Text, (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength, token);
break;
case "{EOPNUM}":
svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token, section.MyProcedure.MyContent.Number)));
break;
case "{SECTIONLEVELTITLE}":
SplitTitle(svgGroup, pageItem, section.DisplayText, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionTitleLength, token);
svgGroup.Add(PageItemToSvgText(pageItem, section.DisplayText));
break;
case "{SECTIONLEVELNUMBER}":
svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token,section.DisplayNumber)));
break;
default:
// see if it's a PSI token:
if (token.Contains(@"PS-"))
{
ProcedureConfig procConfig = section.MyProcedure.MyConfig as ProcedureConfig;
if (procConfig != null)
{
int indx = token.IndexOf("-");
string val = procConfig.GetValue("PSI", token.Substring(4,token.Length-5));
svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token,val)));
}
}
else if (token.Contains(@"PS="))
{
ProcedureConfig procConfig = section.MyProcedure.MyConfig as ProcedureConfig;
if (procConfig != null)
{
int indx = token.IndexOf("=");
int qindx = token.IndexOf("?", indx);
string pstok = token.Substring(indx + 1, qindx-indx-1);
string val = procConfig.GetValue("PSI", pstok);
int bindx = token.IndexOf("|", indx);
if (val == "Y")
val = token.Substring(qindx + 1, bindx - qindx - 1);
else
{
int eindx = token.IndexOf("}", bindx);
val = token.Substring(bindx + 1, eindx - bindx - 1);
}
if (val != null && val != "")svgGroup.Add(PageItemToSvgText(pageItem, val));
}
}
else
svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token));
//_MyLog.InfoFormat("Token not processed {0}", token);
break;
}
}
}
else
{
svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token));
}
}
mySvg.Add(svgGroup);
}
private void SplitTitle(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len, string match)
{
if (match == "{PROCTITLE2}") return;
if (len == null || ItemInfo.StripRtfFormatting(title).Length < len)
{
if (match == "{PROCTITLE2}") return; // this would have been done in proctitle1
svgGroup.Add(PageItemToSvgText(pageItem, title));
return;
}
// Otherwise determine how many line to split the text into
List<string> titleLines = SplitText(title, (int)len);
// if the token was proctitle, dont' adjust. If the token was PROCTITLE1/2 then
// move down 6.
int adj = pageItem.Token.Contains("1") || pageItem.Token.Contains("2") ? 0 : -6;
float yOffset = adj * (titleLines.Count - 1);
foreach (string line in titleLines)
{
svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset));
yOffset += 12;
}
}
private List<string> SplitText(string text, int len)
{
List<string> results = new List<string>();
int width = 0;
int start = 0;
int lastspace = 0;
string rtfprefix = "";
string nextprefix = "";
for (int indx = 0; indx < text.Length; indx++)
{
if (text[indx] == '\\') //rtf command
{
// look for three things at beginning of string: hex, unicode, rtfcommand.
Match m = Regex.Match(text.Substring(indx), @"^\\'[a-fA-F0-9][a-fA-F0-9]"); //hex
if (m.Success)
{
indx += m.Length - 1;
width++;
}
else
{
m = Regex.Match(text.Substring(indx), @"^\\u[a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]?");
if (m.Success)
{
indx += m.Length - 1;
width++;
}
else
{
m = Regex.Match(text.Substring(indx), @"^\\[^ ]*? ");
if (m.Success)
{
indx += m.Length - 1;
rtfprefix = AdjustRtfPrefix(rtfprefix, m.Value);
}
}
}
}
else
{
if (text[indx] == ' ')
{
lastspace = indx;
}
width++;
if (width > len)
{
// what should be done if lastspace == 0
results.Add(nextprefix+text.Substring(start, lastspace));
nextprefix = rtfprefix;
if (nextprefix != "") nextprefix += " ";
start = lastspace + 1;
width = 0;
lastspace = 0;
}
}
}
if (width > 0 || start < text.Length) results.Add(nextprefix + text.Substring(start));
return results;
}
private string AdjustRtfPrefix(string rtfprefix, string rtfcommand)
{
if (rtfcommand.Contains(@"\ulnone") || rtfcommand.Contains(@"\ul0")) // off
rtfprefix = rtfprefix.Replace(@"\ul","");
else if (rtfcommand.Contains(@"\ul"))
rtfprefix += @"\ul";
if (rtfcommand.Contains(@"\up0") || rtfcommand.Contains(@"\dn0")) rtfprefix = rtfprefix.Replace(@"\up2", "").Replace(@"\dn2", "");
else if (rtfcommand.Contains(@"\up")) rtfprefix += @"\up2";
else if (rtfcommand.Contains(@"\dn")) rtfprefix += @"\dn2";
if (rtfcommand.Contains(@"\b0"))
rtfprefix = rtfprefix.Replace(@"\b", "");
else if (rtfcommand.Contains(@"\b"))
rtfprefix += @"\b";
if (rtfcommand.Contains(@"\i0"))
rtfprefix = rtfprefix.Replace(@"\i", "");
else if (rtfcommand.Contains(@"\i"))
rtfprefix += @"\i";
return rtfprefix;
}
private int FindWidth(string title, int start, int len)
{
for (int ii = start + len; ii > start; ii--)
{
if (title[ii] == ' ')
{
while (title[ii] == ' ') ii--;
if (ii > start)
return 2 + ii - start;
return len;
}
}
return len;
}
private SvgPart PageItemToSvgUse(VEPROMS.CSLA.Library.PageItem pageItem, string templateName)
{
SvgUse svgUse = new SvgUse();
svgUse.UseID = templateName;
svgUse.X = new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT);
svgUse.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT);
return svgUse;
}
private static SvgText PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text)
{
SvgText svgText = new SvgText();
svgText.Text = text;
VEPROMS.CSLA.Library.E_Justify justify = pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft;
if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft)
svgText.Justify = SvgJustify.Left;
else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight)
svgText.Justify = SvgJustify.Right;
else
svgText.Justify = SvgJustify.Center;
svgText.Font = pageItem.Font.WindowsFont;
svgText.X = new SvgMeasurement((float)(pageItem.Col), E_MeasurementUnits.PT);
svgText.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT);
if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace
return svgText;
}
private SvgPart PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text, float yOffset)
{
SvgText svgText = new SvgText();
svgText.Text = text;
VEPROMS.CSLA.Library.E_Justify justify = pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft;
if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft)
svgText.Justify = SvgJustify.Left;
else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight)
svgText.Justify = SvgJustify.Right;
else
svgText.Justify = SvgJustify.Center;
svgText.Font = pageItem.Font.WindowsFont;
svgText.X = new SvgMeasurement((float)pageItem.Col, E_MeasurementUnits.PT); // new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT);
svgText.Y = new SvgMeasurement((float)(yOffset + pageItem.Row ?? 0), E_MeasurementUnits.PT);
if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace
return svgText;
}
private List<string> _MissingTokens = new List<string>();
protected override string ReplacePageListToken(Match match)
{
switch (match.Value)
{
case "{PAGE}": // Current Page Number
return CurrentPageNumber.ToString();
case "{OF}": // Total Page Count for this section
return CurrentPageOf.ToString();
case "{REVDATE}": // Revision Date
if (RevDate == null || RevDate == "") return DateTime.Now.ToShortDateString();
return RevDate;
case "{REV}": // Revision Number
// 16-bit had very specific code to check for first character
// == to a ' ' (space) and if so, start Rev from second character.
if (Rev !=null && Rev != "" && Rev[0] == ' ') return Rev.Substring(1, Rev.Length - 1);
return Rev;
}
if (!_MissingTokens.Contains(match.Value))
{
_MissingTokens.Add(match.Value);
_MyLog.InfoFormat("Unhandled token {0}", match.Value);
}
return "";
}
}
public class PageBookmarks : List<PageBookmark>
{
public PageBookmarks()
: base()
{
}
public void Add(ItemInfo itemInfo, string title, PdfDestination pdfDestination)
{
Add(new PageBookmark(itemInfo, title, pdfDestination));
}
}
public class PageBookmark
{
private ItemInfo _MyItemInfo;
public ItemInfo MyItemInfo
{
get { return _MyItemInfo; }
set { _MyItemInfo = value; }
}
private string _Title;
public string Title
{
get { return _Title; }
set { _Title = value; }
}
private PdfDestination _PdfDestination;
public PdfDestination PdfDestination
{
get { return _PdfDestination; }
set { _PdfDestination = value; }
}
public PageBookmark(ItemInfo itemInfo, string title, PdfDestination pdfDestination)
{
_MyItemInfo = itemInfo;
_Title = title;
_PdfDestination = pdfDestination;
}
}
public class ChangeBarDefinition // anything that is section level should go in here.
{
private PrintChangeBar _MyChangeBarType;
public PrintChangeBar MyChangeBarType
{
get { return _MyChangeBarType; }
set { _MyChangeBarType = value; }
}
private PrintChangeBarLoc _MyChangeBarLoc;
public PrintChangeBarLoc MyChangeBarLoc
{
get { return _MyChangeBarLoc; }
set { _MyChangeBarLoc = value; }
}
private PrintChangeBarText _MyChangeBarText;
public PrintChangeBarText MyChangeBarText
{
get { return _MyChangeBarText; }
set { _MyChangeBarText = value; }
}
private string _MyChangeBarMessage; // user defined change bar message from docconfig
public string MyChangeBarMessage
{
get { return _MyChangeBarMessage; }
set { _MyChangeBarMessage = value; }
}
private int _MyChangeBarColumn; // two dimensional array, if both on same side, values are =
public int MyChangeBarColumn
{
get { return _MyChangeBarColumn; }
set { _MyChangeBarColumn = value; }
}
/*
* could have line thickness (set default from 16-bit), line color (set default as black), line style
*/
public ChangeBarDefinition()
{
}
public ChangeBarDefinition(PrintChangeBar myCBT, PrintChangeBarLoc myCBL, PrintChangeBarText myCBTxt, string myCBMsg)
{
_MyChangeBarType = myCBT;
_MyChangeBarLoc = myCBL;
_MyChangeBarText = myCBTxt;
}
public ChangeBarDefinition(DocVersionConfig docverConfig, FormatInfo formatInfo)
{
// if there is not overridden data on the docversion, prompt user...
ChangeBarData changeBarData = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData;
if (docverConfig == null || docverConfig.Print_ChangeBar == PrintChangeBar.SelectBeforePrinting)
{
// use these for now, i.e. this is what user would have selected from dialog.
_MyChangeBarType = PrintChangeBar.WithDefault;
_MyChangeBarLoc = PrintChangeBarLoc.OutsideBox;
_MyChangeBarText = PrintChangeBarText.None;
}
else
{
_MyChangeBarType = docverConfig.Print_ChangeBar;
_MyChangeBarLoc = docverConfig.Print_ChangeBarLoc;
_MyChangeBarText = docverConfig.Print_ChangeBarText;
}
if (_MyChangeBarType == PrintChangeBar.WithDefault) // get data from format
{
_MyChangeBarText = changeBarData.ChangeBarMessage == "ChgID" ? PrintChangeBarText.ChgID :
changeBarData.ChangeBarMessage == "DateAndChgID" ? PrintChangeBarText.DateChgID :
changeBarData.ChangeBarMessage == "None" ? PrintChangeBarText.None :
changeBarData.ChangeBarMessage == "RevNum" ? PrintChangeBarText.RevNum : PrintChangeBarText.UserDef;
}
if (_MyChangeBarType != PrintChangeBar.Without)
{
// if the format has the absolutefixedchangecolumn format flag, then always use the fixedchangecolumn from the
// format, otherwise, use the default column based on the selected location, stored in the base format.
_MyChangeBarColumn = (changeBarData.AbsoluteFixedChangeColumn) ?
(int)changeBarData.FixedChangeColumn :
System.Convert.ToInt32(changeBarData.DefaultCBLoc.Split(" ".ToCharArray())[System.Convert.ToInt32(_MyChangeBarLoc)]);
if (_MyChangeBarText == PrintChangeBarText.UserDef)
_MyChangeBarMessage = docverConfig.Print_UserCBMess1 + @"\n" + docverConfig.Print_UserCBMess2;
}
}
}
}