Office Addin Custom Attributes on Range Text - vsto

I would like to know if it's possible to add additional attributes to simple Range text or Paragraph text from my Word Add-in. For simplicity see code below where I can populate the document with text but additionally i would like to store additional but behind the scenes info along with that text. Ultimately I want these read these custom attributes using the Open Xml SDK when these documents go through a processing stage.
private void AddAttributedContent(string documentContent)
{
var doc = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
var range = doc.Range();
range.Font.Size = 12;
range.Font.Name = "Calibri";
range.Underline = Word.WdUnderline.wdUnderlineSingle;
range.Text = documentContent;
// range.AddOpenXmlProperty("MyProp", "MyValue");
var para = doc.Paragraphs.Add();
para.Range.Text = documentContent;
//para.AddCustomProperty("MyProp", "MyVal");
}
Edit:
Ideally our property would sit inside of the resulting RunProprties :

No, you can't do that. You could probably do it with a content control or a text box though.
For a ContentControl, you could probably use Tag (if this is like sources, it probably has to be unique, though the description seems to imply it's meant for the purpose you need) or Title.
The Tag property is different from the Title property in that a tag is never displayed while a user edits a document. Instead, developers can use it to store a value for programmatic manipulation while the document is opened.
For a text box (a Shape), you could use AlternativeText or Title.
Note that altering Title (in both cases) or AlternativeText will probably affect the way the document is displayed if you save it as HTML.

Related

Macro to Modify Content Control Properties for Directory of Documents

I have over 300 documents with a table coverpage, within one of the cells is a content control box with incorrect properties (the title and the tag are both named wrong). I can so far create a macro to fix the properties but only after I click into the cell by opening each document one by one. Is there a way to run a macro that can find this content control box in a table and amend the properties and save?
To search for a Content Control with a certain Title and/or Tag in a document and then change the Title or Tag, you'd use code something like this ...
Dim cc As ContentControl
For Each cc In ActiveDocument.ContentControls
If cc.Range.Information(wdWithInTable) Then
If cc.Tag = "InErrorTag" And cc.Title = "InErrorTitle" Then
'then correct the Tag and Title
cc.Tag = "CorrectedTag"
cc.Title = "CorrectedTitle"
End If
End If
Next
To then perform this replacement in a batch process of updating multiple documents you need additional code.
There is a Wiki article Batch Editing MS Word Documents that provides cross platform (Windows and Mac) VBA code for that purpose. You can merge the article's code with the Content Control replacement code above to accomplish you task.

ABC PDF version 6.0 Form Fields Read Only

We have a VB.NET program that is using Supergoo's ABCPDF version 6.1.1.2. Our program takes standard XML strings and places values in a corresponding PDF form field on the template PDF.
Problem:
We have over 3000 PDF files that have all been "tagged" with form fields. There could be up to 50 form fields on the template PDFs for a total of roughly 150,000 form fields in use potentially. We have noticed that some of these form fields have their form field common properties set to hidden by mistake. (see screenshot)
The issue is that the PDF coming back after the string values have been added are not showing up. Duh right? Fix the form field property and call it done. However, there is no way to know how many other of the other 150,000 form fields have been improperly tagged like this.
Does anyone know if I can adjust the PDF generation program to forcefully ignore that form field common property? Here is a sample of the vb.net code I am hoping to slightly alter...
Dim theDoc As Doc = New Doc
theDoc.Form.Fields("SampleFieldName").?????? 'can we set something here to ignore the hidden property?
According to the docs at
http://www.websupergoo.com/helppdfnet/source/6-abcpdf.objects/field/2-properties/page.htm
The .Page property of a Field object will tell you the page the field is on. Since Page is a class, if the result 'Is Nothing' then you know that the field is not visible since it doesn't appears on any page in the PDF document.
Please note that there are a few caveats when using fields that are not hidden but not actually visible when rendered (being too small, being spread on two pages, etc). If you need need to handle that you may be interested in http://www.websupergoo.com/helppdfnet/source/6-abcpdf.objects/field/2-properties/rect.htm depending on your use cases.
For the ABCPDF v6 software, I have discovered through Mihai's suggestion that it is possible. I have coded this C# example in the hopes that it helps someone down the road...
static void SetFillableFieldsToWriteableExample(string origFileLocation, string newFileLocation)
{
Doc theDoc = new Doc();
theDoc.Read(origFileLocation);
var theFields = theDoc.Form.GetFieldNames();
foreach (string theField in theFields)
{
Field theFieldInstance = theDoc.Form[theField];
theDoc.SetInfo(theFieldInstance.ID, "/F", "4");
}
theDoc.Save(newFileLocation);
}
I have tested this and it works when all fields are text fields on the PDF. Not sure on the other field types.
This code should not be used in a production environment as written here. There is no guarantee that the origFileLocation or newFileLocation references a PDF and no error handling among other issues. This is for demonstration purposes only.

Set export value of a new created checkbox with iText

I need to add a checkbox to an existing pdf. Also I need set the export value of this checkbox. I saw that this should be configurared with appearance dictionary /AP but till now I did evaluate how to set this on a new checkbox.
With export value I mean the value which is marked in the screenshot
Here is my code which creates a checkbox, but the export value is always empty...
case AcroFields.FIELD_TYPE_CHECKBOX:
PdfFormField checkbox = PdfFormField.createCheckBox(stamper.getWriter());
checkbox.setWidget(fieldVO.rect, PdfAnnotation.HIGHLIGHT_NONE);
checkbox.setFieldName(fieldVO.getNewName());
//TODO set export value
log.info("exportValue is " + fieldVO.getExportValue());
stamper.addAnnotation(checkbox, fieldVO.getPageNumber());
break;
First this: you are using PdfFormField to create a check box. That is hard. Why don't you use the RadioCheckField class?
rect = new Rectangle(180, 806, 200, 788);
checkbox = new RadioCheckField(stamper.getWriter(), rect,
"fieldVO.getNewName()", "on");
field = checkbox.getCheckField();
Then you want to define the appearances. Suppose that onOff is an array of PdfAppearance objects, one with the appearance if the box isn't selected (0) and one if the box is selected (1). Note that the name of the off state should be "Off" as defined in ISO-32000-1. As far as I remember, the standard recommends using "Yes" for the on state, but you can use a custom value, such as "MyCustomValue":
field.setAppearance(
PdfAnnotation.APPEARANCE_NORMAL, "Off", onOff[0]);
field.setAppearance(
PdfAnnotation.APPEARANCE_NORMAL, "MyCustomValue", onOff[1]);
In this case, the appearance of the on state will be stored as an entry with key /MyCustomValue. This key is a PDF name object and several restrictions apply. That's why the /Opt key was introduced:
(Taken from ISO-32000-1) Beginning with PDF 1.4, the field dictionary for check boxes and radio buttons may contain an optional Opt entry. If present, the Opt entry shall be an array of text strings representing the export value of each annotation in the field. It may be used for the following purposes:
To represent the export values of check box and radio button fields in non-Latin writing systems. Because name objects in the appearance dictionary are limited to PDFDocEncoding, they cannot represent non-Latin text.
To allow radio buttons or check boxes to be checked independently, even if they have the same export value.
EXAMPLE: a group of check boxes may be duplicated on more than one page such that the desired behavior is that when a user checks a box, the corresponding boxes on each of the other pages are also checked. In this case, each of the corresponding check boxes is a widget in the Kids array of a check box field.
In your case, you'd need something like:
PdfArray options = new PdfArray();
options.add(new PdfString("My Custom Value"));
field.put(PdfName.OPT, options);
I haven't tested if this works, I'm merely interpreting what ISO-32000-1 says and converting the spec into iText code.
Finally, you can add the field.
stamper.addAnnotation(field, 1);

Building Word fields

Apart from just inserting and parsing text into a blank Word field, is there any way to programmatically build user-defined fields and field codes into my own templates with VBA? Furthermore, is there a way to make these fields show up in the list of available fields?
I recently developed a solution that used Word's MACROBUTTON and ADDIN field types.
I found MACROBUTTON useful because the third whitespace-delimited entry inside the field (programmatically field.code.text) is displayed within Word. This allows my users to watch fields as they move around. { MACROBUTTON NoMacro * } would display an "*" in Word, e.g. And it would do nothing when the user double-clicked on it, because I have purposefully not defined a macro named "NoMacro".
The ADDIN field does not display (except when display field codes is turned on) and stores a hidden string in its field.data property. Using this field I could have a hidden field the contents of which could not be seen or modified by users (excepting that if they turn on "show field codes" they can see that it is an ADDIN field (but they cannot see/edit the "data" property), and that they can delete this field just like any other field.)
I found these pages useful:
Using MacroButton fields
Using Addin Fields
What had you in mind? It is possible to add custom document properties either manually or with VBA. These are the accessible as fields under DOCPROPERTY:
{ DOCPROPERTY "Test" \* MERGEFORMAT }
You can use a macro to ensure that the custom property is added to documents:
Sub AutoNew()
Dim objCustomProperties As DocumentProperties
Set objCustomProperties = ActiveDocument.CustomDocumentProperties
objCustomProperties.Add Name:="Test", _
Type:=msoPropertyTypeString, Value:="Blah", _
LinkToContent:=False
End Sub
Further Information
Automacros: http://msdn.microsoft.com/en-us/library/aa263747(office.10).aspx
Understanding Custom Document Properties in Microsoft Office Word 2003: http://msdn.microsoft.com/en-us/library/aa537154.aspx

How can I change the 259 char limit inside WinForms Treeview LabelEdit?

My VB.Net Winforms app is a tool to allow hierarchical data to be edited in a tree, then stored in a database. I am using a treeview control.
Content is drag-dropped from other documents onto the treenodes, or the nodes can be edited directly.
if I edit the database field directly, and enter a bit of content (a thousand characters long or more!), the treeview will happily display it.. but, when I drag drop, the data is being truncated at 259 characters. If I edit directly, the maximum edit 'window' is also 259 characters.
259 seems like a really strange number to stop at, so I am wondering - where does this size come from, and can I change it programmatically?
I would recommend taking a different approach. You probably don't want to show your users all 10000 or characters of a document anyway in their TreeNode, so create an custom data storage class
with properties like Name and Content to store the document and it's title. Add your content to the Content property and a title or something meaningful to the Name property then add the object to the Tag property of the TreeNode object.
Dim mynode As New TreeNode
Dim SomeBigCustomObject as New MyContentStorageObject(name,content)
mynode.Text = SomeBigCustomObject.Name
mynode.Tag = SomeBigCustomObject
TreeView1.Nodes.Add(mynode)
You can then get the object back when a node is selected (using the AfterSelect event) like this:
dim ContentStorageObject As MyContentStorageObject = CType(e.Node.Tag, MyContentStorageObject)
dim content as string = ContentStorageObject.Content
If you need to edit the text, I would then either pop up a editor dialog or send the data that is stored in Content to an textbox on your form for editing. Your users will probably appreciate not having to type it all in the treeview node editor.
That's a real quick and dirty explanation, but the essence is "use the .Tag property". Good luck.