B2019-052: Pdf Links for each Referenced Object and Transition within a Step

This commit is contained in:
Kathy Ruffing 2019-04-25 13:07:19 +00:00
parent 456909e848
commit cd3656c955
3 changed files with 154 additions and 75 deletions

View File

@ -12,6 +12,7 @@ using Itenso.Rtf.Support;
using Microsoft.Win32;
using Volian.Base.Library;
using System.Text.RegularExpressions;
using VEPROMS.CSLA.Library;
namespace Volian.Print.Library
{
@ -91,6 +92,7 @@ namespace Volian.Print.Library
}
public class Rtf2iTextSharp : RtfVisualVisitorBase
{
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private bool _HasIndent = false;
public bool HasIndent
{
@ -125,7 +127,7 @@ namespace Volian.Print.Library
get { return _MyDebugID; }
set { _MyDebugID = value; }
}
public bool DoPdfLinks = false;
// public Rtf2iTextSharp(IRtfDocument rtfDoc, Document doc, PdfWriter writer)
public Rtf2iTextSharp(IRtfDocument rtfDoc)
{
@ -270,6 +272,86 @@ namespace Volian.Print.Library
// sb.Append(c);
// return sb.ToString();
//}
// ParseLink & GetDefaultItemInfo (which used to be in vlnParagraph) support coding that was added to DoVisitText for
// doing pdflink for each transition/ro in a step, see bug B2019-052
private RoUsageInfo _Roui = null;
private TransitionInfo _Ti = null;
private int _linkType = 0;
// for the particular link, parse its text to see the type of link and its associated data, either transitioninfo or rousageinfo:
public void ParseLink(string _LinkInfoText)
{
if (_LinkInfoText == null) return;
// First parse the string
if (_LinkInfoText.Contains(@"\v"))
throw new Exception("LinkText.ParseLink found RTF token");
Match m = Regex.Match(_LinkInfoText, @"[#]Link:([A-Za-z]*):(.*)");
string _MyValue = m.Groups[1].Value;
string _MyLink = "#Link:" + m.Groups[2].Value + ":" + m.Groups[3].Value;
switch (m.Groups[1].Value)
{
case "ReferencedObject":
_linkType = 1;
string[] subs = m.Groups[2].Value.Split(" ".ToCharArray());
if (subs[0].IndexOf("CROUSGID") > -1)
_Roui = null;
else if (subs[0].IndexOf("NewID") > -1)
_Roui = null;
else
{
int roUsageid = int.Parse(subs[0]);
_Roui = RoUsageInfo.Get(roUsageid);
}
break;
case "Transition":
case "TransitionRange":
_linkType = 2;
string[] subst = m.Groups[2].Value.Split(" ".ToCharArray());
if (subst[1].IndexOf("CTID") > -1)
_Ti = null;
else if (subst[1].IndexOf("NewID") > -1)
_Ti = null;
else
{
int transitionID = int.Parse(m.Groups[2].Value.Split(" ".ToCharArray())[1]);
_Ti = TransitionInfo.Get(transitionID);
}
break;
}
}
// GetDefaultItemInfo finds the item that a transition goes to. If it goes to procedure, go to default section's (or procedure
// steps section if no default) first step (or go to default section if there are not steps). Also, go to step if there are
// steps, else go to section. And last, if none of these can be found, just go to the item passed in.
private ItemInfo GetDefaultItemInfo(ItemInfo myItemInfo)
{
if (myItemInfo.IsProcedure && myItemInfo.Sections != null)
{
SectionInfo siProcedureSteps = null;
foreach (SectionInfo si in myItemInfo.Sections)
{
if (si.IsDefaultSection)
{
if (si.Steps != null) return si.Steps[0];
if (si.Sections != null) return si.Sections[0];
return si;
}
if (si.DisplayText.Contains("Procedure Step"))
siProcedureSteps = si;
}
if (siProcedureSteps != null)
{
if (siProcedureSteps.Steps != null) return siProcedureSteps.Steps[0];
if (siProcedureSteps.Sections != null) return siProcedureSteps.Sections[0];
return siProcedureSteps;
}
}
if (myItemInfo.IsSection)
{
if (myItemInfo.Steps != null) return myItemInfo.Steps[0];
if (myItemInfo.Sections != null) return myItemInfo.Sections[0];
}
return myItemInfo;
}
private static int chkStart = -1;
protected override void DoVisitText(IRtfVisualText visualText)
{
//Code to find text (non-symbol) being output with a symbol font
@ -283,6 +365,67 @@ namespace Volian.Print.Library
int profileDepth = ProfileTimer.Push(">>>> DoVisitText");
if (visualText.Format.IsHidden)
{
// B2019-052: Hidden text contains the link text - so if doing the pdf links when printing, this can be used to determine how
// to create the link. A given link may have multiple chunks though, if there are attribute changes, symbols, etc. This
// code goes through all of the chunks of a link and sets attributes on each chunk so that the link goes to the correct
// place (RO or Transition 'to'). Note that the pdf links were originally done in vlnparagraph.cs but only went to a single
// link within a step. The code was moved here so that each ro and transition link within a step could have its on pdf link.
if (DoPdfLinks)
{
// use the start and end tokens in the link text, these may span more than one chunk.
if (visualText.Text.Contains("<START]")) chkStart = _MyParagraph.Chunks.Count;
if (visualText.Text.Contains("[END>"))
{
string txt = visualText.Text;
ParseLink(txt); // get the link data, ro or transition
for (int i = chkStart; i < _MyParagraph.Chunks.Count; i++)
{
try
{
Chunk chk = _MyParagraph.Chunks[i] as Chunk;
if (chk != null)
{
if (_linkType == 2 && _Ti != null) // transition
{
ItemInfo tiDefault = GetDefaultItemInfo(_Ti.MyItemToID);
ItemInfo from = _Ti.MyContent.ContentItems[0];
if (_Ti.MyItemToID.MyProcedure.ItemID == from.MyProcedure.ItemID &&
!from.ActiveSection.DisplayNumber.ToUpper().StartsWith("FOLDOUT"))
{ // Local Go To
if (_Ti.MyItemToID.MyContent.Type > 9999) // internal to this file
{
chk.SetLocalGoto(string.Format("ItemID={0}", tiDefault.ItemID));
chk.SetBackground(Color.CYAN);
chk.SetBackground(new Color(System.Drawing.Color.LightCyan));
}
}
else if (_Ti != null) // Remote Go To
{
chk.SetRemoteGoto(_Ti.MyItemToID.MyProcedure.DisplayNumber.Replace("/", "_") + ".pdf", string.Format("ItemID={0}", tiDefault.ItemID));
chk.SetBackground(new Color(System.Drawing.Color.PeachPuff));
}
}
else if (_linkType == 1 && _Roui != null) // referenced object
{
if (_Roui.ROID.Substring(0, 4) != "FFFF")
{
chk.SetRemoteGoto("completeroreport.pdf", string.Format("ROID={0}", _Roui.ROID.Substring(0, 12).ToUpper()));
chk.SetBackground(new Color(System.Drawing.Color.LightGreen));
}
}
}
}
catch (Exception ex)
{
_MyLog.ErrorFormat("Error creating pdf links {0}", ex.Message);
}
}
_Ti = null;
_Roui = null;
_linkType = 0;
chkStart = -1;
}
}
ProfileTimer.Pop(profileDepth);
_lastWasLineBreak = 0; // B2017-191 reset hard return count
return;

View File

@ -1061,47 +1061,12 @@ namespace Volian.Print.Library
if (MyItemInfo.MyContent.Text.ToUpper().Contains("LINK:TR") && MyItemInfo.MyContent.ContentTransitionCount==0)
Console.WriteLine("Missing Transition {0}", MyItemInfo.ItemID);
chk1.SetLocalDestination(string.Format("ItemID={0}", MyItemInfo.ItemID)); // Destination
if (MyItemInfo.MyContent.ContentTransitionCount > 0)
{
TransitionInfo ti = MyItemInfo.MyContent.ContentTransitions[0];
ItemInfo tiDefault = GetDefaultItemInfo(ti.MyItemToID);
if (ti.MyItemToID.MyProcedure.ItemID == MyItemInfo.MyProcedure.ItemID &&
!MyItemInfo.ActiveSection.DisplayNumber.ToUpper().StartsWith("FOLDOUT"))
{ // Local Go To
if (ti.MyItemToID.MyContent.Type > 9999) // B2019-053: internal if going to a section, not just a step (changed from 19999 to 9999
// B2018-034 The following code previously used IParagraph rather than _IParagraph. See first Comment
foreach (Chunk chk in _IParagraph.Chunks)
{
//Console.WriteLine("\"LocalGoTo\"\t{0}", tiDefault.ItemID);
chk.SetLocalGoto(string.Format("ItemID={0}", tiDefault.ItemID));
chk.SetBackground(Color.CYAN);
chk.SetBackground(new Color(System.Drawing.Color.LightCyan));
}
}
else // Remote Go To
{
foreach (Chunk chk in IParagraph.Chunks)
{
//Console.WriteLine("\"RemoteGoTo\"\t{0}", tiDefault.ItemID);
chk.SetRemoteGoto(ti.MyItemToID.MyProcedure.DisplayNumber.Replace("/", "_") + ".pdf", string.Format("ItemID={0}", tiDefault.ItemID));
chk.SetBackground(new Color(System.Drawing.Color.PeachPuff));
}
}
}
if (MyItemInfo.MyContent.ContentRoUsageCount > 0)
{
RoUsageInfo ru = MyItemInfo.MyContent.ContentRoUsages[0];
// B2018-034 The following code previously used IParagraph rather than _IParagraph. See first Comment
foreach (Chunk chk in _IParagraph.Chunks)
{
if (ru.ROID.Substring(0, 4) != "FFFF")
{
chk.SetRemoteGoto("completeroreport.pdf", string.Format("ROID={0}", ru.ROID.Substring(0, 12).ToUpper()));
//Console.WriteLine("ROID={0},{1}", ru.ROID.Substring(0, 12).ToUpper(), chk.Content);
chk.SetBackground(new Color(System.Drawing.Color.LightGreen));
}
}
}
// B2019-052: If multiple ROs/Transitions within a step, each should have a their own link rather than all linking to same thing.
// Note the pdf link code that was here was moved to Rtf2iTextSharp.cs in DoVisitText so that each 'chunk' could have a link.
// The code that remained here was the code that marks the destination for each step & the code that does the pdf links for
// enhanced steps.
// Also, the method GetDefaultItemInfo was moved to Rtf2iTextSharp.cs also - it was only called from code that was moved.
StepConfig sc = new StepConfig(MyItemInfo.MyContent.Config);
DVEnhancedDocuments dveds = MyItemInfo.MyDocVersion.DocVersionConfig.MyEnhancedDocuments;
foreach (EnhancedDocument ed in sc.MyEnhancedDocuments)
@ -1163,36 +1128,6 @@ namespace Volian.Print.Library
// chk.SetBackground(new Color(System.Drawing.Color.LemonChiffon));
//}
}
private ItemInfo GetDefaultItemInfo(ItemInfo myItemInfo)
{
if (myItemInfo.IsProcedure && myItemInfo.Sections != null)
{
SectionInfo siProcedureSteps = null;
foreach (SectionInfo si in myItemInfo.Sections)
{
if (si.IsDefaultSection)
{
if (si.Steps != null) return si.Steps[0];
if (si.Sections != null) return si.Sections[0];
return si;
}
if (si.DisplayText.Contains("Procedure Step"))
siProcedureSteps = si;
}
if (siProcedureSteps != null)
{
if (siProcedureSteps.Steps != null) return siProcedureSteps.Steps[0];
if (siProcedureSteps.Sections != null) return siProcedureSteps.Sections[0];
return siProcedureSteps;
}
}
if (myItemInfo.IsSection)
{
if (myItemInfo.Steps != null) return myItemInfo.Steps[0];
if (myItemInfo.Sections != null) return myItemInfo.Sections[0];
}
return myItemInfo;
}
private static bool _MissingInitials = false;
public static bool MissingInitials

View File

@ -130,7 +130,7 @@ namespace Volian.Print.Library
// B2018-034 Attributes were being lost when the IsCompressed flag was true.
// CopyAttributesToNewIParagraph retains any attribute which have been set
Paragraph oldParagraph = _IParagraph;
_IParagraph = RtfToParagraph(myRtf, HasIndent);
_IParagraph = RtfToParagraph(myRtf, HasIndent, MyPageHelper.MyPromsPrinter.SaveLinks);
// B2018-034 Attributes were being lost when the IsCompressed flag was true.
// CopyAttributesToNewIParagraph retains any attribute which have been set
CopyAttributesToNewIParagraph(oldParagraph, _IParagraph);
@ -433,9 +433,9 @@ namespace Volian.Print.Library
}
public static iTextSharp.text.Paragraph RtfToParagraph(string rtf)
{
return RtfToParagraph(rtf, false);
return RtfToParagraph(rtf, false, false);
}
public static iTextSharp.text.Paragraph RtfToParagraph(string rtf, bool hasIndent)
public static iTextSharp.text.Paragraph RtfToParagraph(string rtf, bool hasIndent, bool doPdfLinks)
{
if (hasIndent)
{
@ -446,6 +446,7 @@ namespace Volian.Print.Library
IRtfDocument rtfDoc = RtfInterpreterTool.BuildDoc(rtf);
Rtf2iTextSharp rtf2IText = new Rtf2iTextSharp(rtfDoc);
rtf2IText.DoPdfLinks = doPdfLinks;
rtf2IText.HasIndent = hasIndent;
iTextSharp.text.Paragraph para = rtf2IText.Convert();
para.SetLeading(_SixLinesPerInch, 0);