so just look at the iText Jump-Start Tutorial of Chapter 1: Introducing basic building blocks Figure 1.2: List example, how to set the line space for the generated lists?
Line spacing is controlled by LEADING property in iText7.
One of the ways to specify leading would be to use setFixedLeading or setMultipliedLeading on iText7's Paragraph class and then add those Paragraph instances directly to ListItem instances.
A helper method for creating such a list item based on a text string looks as follows:
private ListItem createListItemWithLeading(String text) {
Paragraph paragraph = new Paragraph(text);
paragraph.setFixedLeading(30);
paragraph.setMargin(0);
ListItem listItem = new ListItem();
listItem.add(paragraph);
return listItem;
}
Another way, as there is currently no setFixedLeading or setMultpliedLeading setters on other elements than Paragraphs, would be to set this property manually to the list:
list.setProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, 2.5f));
// Add the list
document.add(list);
Please be careful when use setProperty directly and do it at your own risk. The preferred way is still to use getters/setters provided in the public API.
Related
I recently upgraded from iText5 to iText7.
I'm using iText7 to flatten documents to remove interactivity. I expected that the printed document would look the same before and after flattening. Unfortunately that's not the case.
The source pdf has non-printing Button objects that are set to "Visible but doesn't print". After flattening, the undesired fields do print.
Is there a setting I'm missing, or do I need to remove non-printing buttons, fields etc before flattening?
Public Shared Function FlattenPdf(SourcePath As String, DestPath As String) As String
Using reader As New Pdf.PdfReader(SourcePath)
Using writer As New Pdf.PdfWriter(DestPath)
'Opens PDF document in the stamping mode
Dim pdfDoc As New Pdf.PdfDocument(reader, writer)
Dim form As Forms.PdfAcroForm = Forms.PdfAcroForm.GetAcroForm(pdfDoc, createIfNotExist:=True)
'flatten the form to remove editing options
form.FlattenFields()
pdfDoc.Close()
End Using
End Using
Return DestPath
End Function
I know that with Descriptive programming you can do something like this:
Browser("StackOverflow").Page("StackOverflow").Link("text:=Go To Next Page ", "html tag:=A").Click
But is it possible to create some kind of string so I can assign more than one data value and pass it as single variable? I've tried many combinations using escape characters and I always get error.
For example in the case above, let's say I have more properties in the Page object, so I'd normally have to do something like this:
Browser("StackOverflow").Page("name:=StackOverflow", "html id:=PageID")...etc...
But I'd like to pass "name:=StackOverflow", "html id:=PageID" as a single variable, so when writing many objects I'd only have to write:
Browser(BrowserString).Page(PageString).WebEdit("name:=asdfgh")
And the first part would remain static, so if the parents' data needs to be modified I'd only have to modify two variables and not all the objects created in all libraries.
Is it possible?
If I was not clear enough please let me know.
Thank you in advance!
I think what you're looking for is UFT's Description object
This allows you finer grained control on the description since in descriptive programming all values are regular expressions but with Description you can turn the regular expression functionality off for a specific property.
Set desc = Description.Create()
desc("html tag").Value = "A"
desc("innertext").Value = "More information..."
desc("innertext").RegularExpression = False
Browser("Example Domain").Navigate "www.example.com"
Browser("Example Domain").Page("Example Domain").WebElement(desc).Click
If you want to represent this with plain string then it's a bit more of a problem, you can write a helper function but I'm not sure I would recommend it.
Function Desc(descString)
Set ret = Description.Create()
values = Split(descString, "::")
For Each value In values
keyVal = Split(value, ":=")
ret(keyVal(0)).Value = keyVal(1)
Next
Set Desc = ret
End Function
' Usage
Browser("StackOverflow").Page("StackOverflow").WebElement(Desc("html tag:=H2::innertext:=some text")).Click
Further reading about descriptive programming.
As an alternative to Motti's excellent answer, you could also Set a variable to match your initial descriptive object and then extend it as required:
Set myPage = Browser("StackOverflow").Page("name:=StackOverflow", "html id:=PageID")
after which you can then use
myPage.WebEdit("name:=asdfgh")
throughout the rest of the code, so long as the myPage object stays in scope...
I am using an Entry with an EntryCompletion opbject that has a ListStore model.
For each record in the model, there is an image I would like to display in the autocomplete-popup list.
How can this be done?
Is it possible to add a Gtk.CellRendererPixbuf column to the model?
Interesting enough I could not find any examples of this yet it turns out to be possible and not insanely complicated. Lets start with a small image of the goal which uses icons for convinces reasons.
So how do we get there, first we create the ListStore containing a column with strings to match on and a icon-name to convert into a pixbuf (this could also be a pixbuf directly).
# Define the entries for the auto complete
entries = [
('revert', 'document-revert'),
('delete', 'edit-delete'),
('dev help', 'devhelp'),
]
# Setup the list store (Note that the data types should match those of the entries)
list_store = Gtk.ListStore(str, str)
# Fill the list store
for entry_pair in entries:
list_store.append(entry_pair)
Next step is setting up the EntryCompletion and linking it with the Liststore
# Create the Entry Completion and link it to the list store
completion = Gtk.EntryCompletion()
completion.set_model(list_store)
Now the magic, we need to create 2 renderers, one for the text, one for the pixbufs. We then pack these in the completion to add columns to it.
# Create renderer's for the pixbufs and text
image_renderer = Gtk.CellRendererPixbuf.new()
cell_renderer = Gtk.CellRendererText.new()
# Pack the columns in to the completion, in this case first the image then the string
completion.pack_start(image_renderer, True)
completion.pack_start(cell_renderer, True)
In order to make sure the renderers use the the correct column we here specify which column from the ListStore the renderers should read. For the image_renderer we set the icon_name attribute as we give it icon names. If we would feed it Pixbuf's we would need the pixbuf instead.
# Set up the renderer's such that the read the correct column
completion.add_attribute(image_renderer, "icon_name", 1)
completion.add_attribute(cell_renderer, "text", 0)
As there are no multiple column we need to tell the completion which column contains the string. In our case column 0.
# Tell the completion which column contains the strings to base the completion on
completion.props.text_column = 0
# Create the entry and link it to the completion
entry = Gtk.Entry()
entry.set_completion(completion)
And that's it!
I have got a Kendo Grid and I want to access the data from the row whose detail I expanded. For testing purposes, I have this:
function detailExpand(e)
{
var aux = e.sender.MyModelId;
var aux2 = this.MyModelId;
...
But none of those variables have the MyModelId in it.
I have inspected it and I can't find the model properties unless inside the e.sender._data[index-here] but I don't know the index of the row whose detail I've expanded.
e.sender.dataItem(e.masterRow).MyModelId
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-detailExpand
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#methods-dataItem
For the record, you should try to avoid using methods starting with an underscore (_). I believe kendo uses the underscore to show it's an internal method (a "private"). Unexpected behavior could occur.
Given an HTML document, I want to identify all the numbers in the document and add custom tags around the numbers.
Right now, i use the following:
HtmlNodeCollection bodyNode = htmlDoc.DocumentNode.SelectNodes("//body");
MatchCollection numbersColl = Regex.Matches(htmlNode.InnerText, <some regex>);
Once I get the numbersColl, I can traverse through each Match and get the index.
However, I can't change the InnerText since it is read-only.
What I need is that if match.Value = 100 and match.Index=25, I want to replace that 25 with
<span isIdentified='true'> 25 </span>
Any help on this will be greatly appreciated. Currently, since I am not able to modify the inner text, I have to modify the InnerHtml but some element might have 25 in it's innerHtml. That should not be touched. But how do I identify whether the number is within
an html tag i.e. < table border='1' > has 1 in the tag.
Here's what I did to work around the read-only property limitation of the InnerText property of a Text node, just select the Parent node of the Text node and note the index of the Text node in the child node collections of the Parent node. Then just do a ReplaceChild(...).
private void WriteText(HtmlNode node, string text)
{
if (node.ChildNodes.Count > 0)
{
node.ReplaceChild(htmlDocument.CreateTextNode(text), node.ChildNodes.First());
}
else
{
node.AppendChild(htmlDocument.CreateTextNode(text));
}
}
In your case I believe you need to create a new Element node that wraps the text into an HtmlElement and then just use it as a replacement of the Text node.
Or even better, see if you can do something like the answer posted here:
Replacing a HTML div InnerText tag using HTML Agility Pack
creating a textnode does not what it should do in this case:
myParentNode.AppendChild(D.CreateTextNode("<script>alert('a');</script>"));
Console.Write(myParentNode.InnerHtml);
The result should be something like
<script....
but it is a working script task even if i add it as "TEXT" not as html. This causes kind of a security issue for me because the text would be a input from a anonymous user.