You are viewing limited content. For full access, please sign in.

Question

Question

Add Text box Append text moves the box up?

asked on February 17, 2021

I'm trying to use the Add Text box activity and I keep getting unexpected results. 

Currently, I'm just testing so I create a multi-value token with a couple of names. I then loop through that values and create a "Text Box text" token that I will use for the actual text. I have merging options set to Append Text. What I'm noticing is that even though the location is the same. Each time I run the workflow, it moves the text box up. Here are my examples. 

I added the 1st and 2nd and 3rd so I could keep track of which time I ran the workflow. 

So you can see that the text is being appended as I expected, but why is the text box moving up the document? It's starting to cover up information on the actual document which is NOT at all what I want. 

Why would the box move up? I'm not touching the placement values. 

 

1 0

Answer

SELECTED ANSWER
replied on February 19, 2021

Okay, new version of the script.

This one checks the document for existing textbox annotations.  If one is found that is on the same page and has the same X and Y coordinates, then instead of adding a new box, it modifies the existing box, setting its appearance based on the token values, and appending the text from the token to the end of the existing text in the textbox.

namespace WorkflowActivity.Scripting.SDKScript
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using Laserfiche.RepositoryAccess;
    using Laserfiche.RepositoryAccess.Common;

    /// <summary>
    /// Provides one or more methods that can be run when the workflow scripting activity is performed.
    /// </summary>
    public class Script1 : RAScriptClass104    //modify this line if Workflow is a different version than 10.4
    {
        /// <summary>
        /// This method is run when the activity is performed.
        /// </summary>
        protected override void Execute()
        {

            //Make sure that we are working with a document...
            if(this.BoundEntryInfo.EntryType == EntryType.Document)
            {

                //Retrieve all Token values from the Workflow
                int pToken = Convert.ToInt32(this.GetTokenValue("Textbox Page Number"));
                int xToken = Convert.ToInt32(this.GetTokenValue("Textbox X Position"));
                int yToken = Convert.ToInt32(this.GetTokenValue("Textbox Y Position"));
                int wToken = Convert.ToInt32(this.GetTokenValue("Textbox Width"));
                int hToken = Convert.ToInt32(this.GetTokenValue("Textbox Height"));
                int fToken = Convert.ToInt32(this.GetTokenValue("Textbox Font Size"));
                string tToken = this.GetTokenValue("Textbox Text").ToString();
                string cToken = this.GetTokenValue("Textbox Comment").ToString();
                bool appendText = false;

                //Get a reference to page 1 of the entry...
                DocumentInfo di = Document.GetDocumentInfo(this.BoundEntryId, this.RASession);
                PageInfo pi = di.GetPageInfo(pToken);

                //Retrieve all existing textBox annotations on the document
                //If an annotation exists that is on the same page, at the same coordinates,
                //then we will want to append the text to it, instead of creating a new textbox.
                List<AnnotationBase> anns = (List<AnnotationBase>)di.GetAnnotations();
                foreach(AnnotationBase ann in anns)
                {
                    if (ann.AnnotationType == AnnotationType.TextBox)
                    {
                        TextBoxAnnotation tb = (TextBoxAnnotation)ann;
                        if(tb.PageNumber == pToken && tb.Coordinates.X == xToken && tb.Coordinates.Y == yToken)
                        {
                            appendText = true;
                            tToken = tb.Text + "\n" + tToken;
                            tb.Text = tToken;
                            tb.Comment = cToken;
                            LfPoint tbPosition = new LfPoint(xToken, yToken);
                            LfSize tbSize = new LfSize(wToken, hToken);
                            tb.Coordinates = new LfRectangle(tbPosition, tbSize);
                            tb.TextSize = fToken;
                            tb.Save();
                        }
                    }
                }

                //If the text was not appended to an existing textbox, create a new textbox.
                if (!appendText)
                {
                    //Create a new TextBoxAnnotation...
                    TextBoxAnnotation textBox = new TextBoxAnnotation();

                    //Set the coordinates and other properties from the token values...
                    LfPoint textBoxPosition = new LfPoint(xToken, yToken);
                    LfSize textBoxSize = new LfSize(wToken, hToken);
                    textBox.Coordinates = new LfRectangle(textBoxPosition, textBoxSize);
                    textBox.TextSize = fToken;
                    textBox.BorderColor = LfColor.TRANSPARENT;
                    textBox.FillColor = LfColor.TRANSPARENT;
                    textBox.Text = tToken;
                    textBox.Comment = cToken;

                    //Add the annotation to the page...
                    pi.AddAnnotation(textBox);
                }
            }
        }
    }
}

 

1 0

Replies

replied on February 17, 2021

I'm not 100% certain, I don't have a lot of experience with that activity, but I believe the positioning is based on the center of the text box, not the top-left corner.  So if you add text that is 100 pixels tall, the top of the box is moved up by 50 pixels.

1 0
replied on February 17, 2021 Show version history

Like Matthew said, seems to have the anchor of the object at the center. There are so many ways you can anchor an object when defining it's position.

You can calculate a Y position based on the number of lines using the token calculator. This method adds 40 pixels for every line, using the Count function to get the number of values in the multi value token. A 12 point font is about 40 pixels high (with the spacing above and below).

0 0
replied on February 18, 2021

Thanks for the input Chad. It does seem like more work than necessary. Nothing in the Admin guide for the Add Text Box activity indicates you need to do this. It definitely implies that everything is calculated based on the upper left location. The coordinates are based on the upper left of the page and the note about how Workflow decides if a text box is in the same location as the one you are trying to add for merging options is based on the upper left coordinates of the text box. 

Note: Text boxes are considered to have the same location if they have the same upper-left coordinate, if their centers are close to each other, or if one text box's borders are completely inside another text box.

I'm not a fan of "if their centers are close to each other" statement either. How close does it need to be? Computers don't just go off vague descriptions for their activities. There is a threshold. Why LF does not put it into the guide is beyond me. 

Again, I would love LF input on this to get it cleared up. If we are using the upper left coordinates of the page to place the box and we can use token in the box, why would the box be anchored in the center! Wouldn't it make much more sense to have the boxes be places by the upper left of the box? Even if I count the values and try to space them out as I want, it still won't help me if I want to add to a text box with the merge feature. The text moves UP the page which is just not natural. We all type things out from top to bottom... 

1 0
replied on February 18, 2021

What does using coordinates of 0,0 do? Does it cut off half of the top and bottom?

The reason why it appears to be a centered anchor is because the center never seems to move as the size of the box increases, you can count the lines of text and find the center.

0 0
replied on February 18, 2021

0,0 just puts it in the upper left corner, no cut-off.  I know that LF isn't going to change anything based on my opinion. I guess the part that frustrates me the most is the documentation. Nowhere does it say the box will be placed with your coordinates bases on the size of your text box and in the middle of the text box. Everything talks about the upper left. 

Logically, I expected the box to be anchored to the upper left corner. Since the way we type starts in the upper left and goes to the right and flows down, I figured anchoring the text box to the upper left would be best because no matter the length of text or size of text, the box would always be places where you want. I don't like that a string of text will be placed in different locations on a page based on the length and size of the text. Those variables change but the upper left is constant.

1 0
replied on February 18, 2021

I've been playing around with it and I'm seeing the same behavior you have indicated.  It definitely appears to use the center of the text box, not the top-left.  I don't see anywhere to change this setting.

From a development perspective, I've always worked from a top-left position, so this isn't intuitive to me at all.  Unfortunately, it does seem to be their intended functionality - this is quite frustrating.

1 0
replied on February 18, 2021

If 0,0 does not cut off anything, then the anchor is at the top left, but based on the screenshots in the OP you can see the anchor is in the middle or middle left, that is odd.

0 0
replied on February 18, 2021

I think the way it treats 0,0 is as an object. It can't force it off the page. The software knows the top edge and doesn't allow for it to pass the page boundary. I have another Workflow that I add text boxes to the lower right of a page. It's a received date. I just use max coordinates to make sure it's always down there. Something like 10,000 for both x and y. I couldn't rely on the preset "lower right" that the activity has. It was never actually on the lower right side. 

0 0
replied on February 18, 2021

Ah actually that is true, I remember having issues where 0 and 10 put the box in the same place. So it must be a centered anchor but can't go off the page.

0 0
replied on February 18, 2021

I know this is not exactly what you want, but here's a workaround, that allows you to add textboxes to your document using an SDK Script activity and some tokens.  You can modify the token values and run the same script again to add more textboxes.

This gives you a little more direct control over the different specifics of the textbox and does appear to be using top-left positioning instead of center positioning - so it's a little more intuitive.

Here's the tokens that are needed:

And here's the script to include in the SDK Script activity (this assumes Workflow version 10.4, you need to edit line 15 if you are on a different version).

namespace WorkflowActivity.Scripting.SDKScript
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using Laserfiche.RepositoryAccess;
    using Laserfiche.RepositoryAccess.Common;

    /// <summary>
    /// Provides one or more methods that can be run when the workflow scripting activity is performed.
    /// </summary>
    public class Script1 : RAScriptClass104
    {
        /// <summary>
        /// This method is run when the activity is performed.
        /// </summary>
        protected override void Execute()
        {

            //Make sure that we are working with a document...
            if(this.BoundEntryInfo.EntryType == EntryType.Document)
            {

                //Retrieve all Token values from the Workflow
                int pToken = Convert.ToInt32(this.GetTokenValue("Textbox Page Number"));
                int xToken = Convert.ToInt32(this.GetTokenValue("Textbox X Position"));
                int yToken = Convert.ToInt32(this.GetTokenValue("Textbox Y Position"));
                int wToken = Convert.ToInt32(this.GetTokenValue("Textbox Width"));
                int hToken = Convert.ToInt32(this.GetTokenValue("Textbox Height"));
                int fToken = Convert.ToInt32(this.GetTokenValue("Textbox Font Size"));
                string tToken = this.GetTokenValue("Textbox Text").ToString();
                string cToken = this.GetTokenValue("Textbox Comment").ToString();

                //Get a reference to page 1 of the entry...
                DocumentInfo di = Document.GetDocumentInfo(this.BoundEntryId, this.RASession);
                PageInfo pi = di.GetPageInfo(pToken);

                //Create a new TextBoxAnnotation...
                TextBoxAnnotation textBox = new TextBoxAnnotation();

                //Set the coordinates and other properties from the token values...
                LfPoint textBoxPosition = new LfPoint(xToken, yToken);
                LfSize textBoxSize = new LfSize(wToken, hToken);
                textBox.Coordinates = new LfRectangle(textBoxPosition, textBoxSize);
                textBox.TextSize = fToken;
                textBox.BorderColor = LfColor.TRANSPARENT;
                textBox.FillColor = LfColor.TRANSPARENT;
                textBox.Text = tToken;
                textBox.Comment = cToken;

                //Add the annotation to the page...
                pi.AddAnnotation(textBox);

            }

        }
    }
}

 

0 0
replied on February 19, 2021

Thank you, Matthew. The script works and gives me more control for sure. I can't find where I can add merging options? Any ideas? 

1 0
SELECTED ANSWER
replied on February 19, 2021

Okay, new version of the script.

This one checks the document for existing textbox annotations.  If one is found that is on the same page and has the same X and Y coordinates, then instead of adding a new box, it modifies the existing box, setting its appearance based on the token values, and appending the text from the token to the end of the existing text in the textbox.

namespace WorkflowActivity.Scripting.SDKScript
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using Laserfiche.RepositoryAccess;
    using Laserfiche.RepositoryAccess.Common;

    /// <summary>
    /// Provides one or more methods that can be run when the workflow scripting activity is performed.
    /// </summary>
    public class Script1 : RAScriptClass104    //modify this line if Workflow is a different version than 10.4
    {
        /// <summary>
        /// This method is run when the activity is performed.
        /// </summary>
        protected override void Execute()
        {

            //Make sure that we are working with a document...
            if(this.BoundEntryInfo.EntryType == EntryType.Document)
            {

                //Retrieve all Token values from the Workflow
                int pToken = Convert.ToInt32(this.GetTokenValue("Textbox Page Number"));
                int xToken = Convert.ToInt32(this.GetTokenValue("Textbox X Position"));
                int yToken = Convert.ToInt32(this.GetTokenValue("Textbox Y Position"));
                int wToken = Convert.ToInt32(this.GetTokenValue("Textbox Width"));
                int hToken = Convert.ToInt32(this.GetTokenValue("Textbox Height"));
                int fToken = Convert.ToInt32(this.GetTokenValue("Textbox Font Size"));
                string tToken = this.GetTokenValue("Textbox Text").ToString();
                string cToken = this.GetTokenValue("Textbox Comment").ToString();
                bool appendText = false;

                //Get a reference to page 1 of the entry...
                DocumentInfo di = Document.GetDocumentInfo(this.BoundEntryId, this.RASession);
                PageInfo pi = di.GetPageInfo(pToken);

                //Retrieve all existing textBox annotations on the document
                //If an annotation exists that is on the same page, at the same coordinates,
                //then we will want to append the text to it, instead of creating a new textbox.
                List<AnnotationBase> anns = (List<AnnotationBase>)di.GetAnnotations();
                foreach(AnnotationBase ann in anns)
                {
                    if (ann.AnnotationType == AnnotationType.TextBox)
                    {
                        TextBoxAnnotation tb = (TextBoxAnnotation)ann;
                        if(tb.PageNumber == pToken && tb.Coordinates.X == xToken && tb.Coordinates.Y == yToken)
                        {
                            appendText = true;
                            tToken = tb.Text + "\n" + tToken;
                            tb.Text = tToken;
                            tb.Comment = cToken;
                            LfPoint tbPosition = new LfPoint(xToken, yToken);
                            LfSize tbSize = new LfSize(wToken, hToken);
                            tb.Coordinates = new LfRectangle(tbPosition, tbSize);
                            tb.TextSize = fToken;
                            tb.Save();
                        }
                    }
                }

                //If the text was not appended to an existing textbox, create a new textbox.
                if (!appendText)
                {
                    //Create a new TextBoxAnnotation...
                    TextBoxAnnotation textBox = new TextBoxAnnotation();

                    //Set the coordinates and other properties from the token values...
                    LfPoint textBoxPosition = new LfPoint(xToken, yToken);
                    LfSize textBoxSize = new LfSize(wToken, hToken);
                    textBox.Coordinates = new LfRectangle(textBoxPosition, textBoxSize);
                    textBox.TextSize = fToken;
                    textBox.BorderColor = LfColor.TRANSPARENT;
                    textBox.FillColor = LfColor.TRANSPARENT;
                    textBox.Text = tToken;
                    textBox.Comment = cToken;

                    //Add the annotation to the page...
                    pi.AddAnnotation(textBox);
                }
            }
        }
    }
}

 

1 0
replied on February 22, 2021

This works as expected! Thank you so much for the script Matthew. This is a valuable contribution to LF Answers. 

1 0
You are not allowed to follow up in this post.

Sign in to reply to this post.