How to make a PDF's hidden signature fields visible? - itext

I have a bunch of PDFs with hidden signature fields in them. There is no function to make the actual fields visible; there is only such an option for radio/checkbox/button fields, as far as I have found. Is there any such method or any other way?
I can't add layers to the PDF, as I am trying to turn the fields from hidden to visible, not the other way around.
ArrayList al = new ArrayList();
for (int page = 1; page <= reader.NumberOfPages; page++)
{
foreach (string key in form.Fields.Keys)
{
if (form.GetFieldType(key) == AcroFields.FIELD_TYPE_SIGNATURE)
{
al.Add(key);
}
}
}
foreach (object x in al)
{
string s = (string)x;
AcroFields.Item i = form.GetFieldItem(s);
stamper.AcroFields.Fields.Remove(s);
stamper.AcroFields.Fields.Add(s, i);
}
This was an attempt of mine to reset the field to make it visible, but it was obvious it wouldn't work since it wouldn't lose all of its properties. So how do I do go about this?

Related

Change value of widget inside GWT flex table when other widget's value changes?

Ok, so I have a pretty specific and to me quite complicated issue, as I'm a GWT newbie.
I have a GWT flex table, which I use to dynamically add rows, whose cells contain GWT widgets. The row number changes, but the number of columns in static, always 6. Each row contains a cell with a remove button and five cells each with their own textbox.
What I need to do is somehow code a kind of relationship between the textbox in cell 6 of one row and the textbox in cell 5 in the next row (and vice versa).
To illustrate: when something changes in the textbox at [1,6] the content of textbox at [2,5] needs to be overwritten with the same value. If the textbox at [2,5] changes the textbox at [1,6] needs to change as well. I cannot use a button to commit the changes, it needs to happen via onValueChange or Blur or something similar, which doesn't require the user to perform a specific action.
My problem stems mostly from trying to figure out how to address specific cells in the flex table and their content. For the remove button the solution was easy enough with a click event handler, but for this issue I just can't seem to be able to come up with a solution.
Sadly I also cannot provide any of the code which I have up until now, since it's a business secret. I can only give a broad description of the problem like the one above.
EDIT:
Actually, it's probably more a problem of not having much code in terms of this specific problem.
What I have is a flex table, which has initially only the header row. Upon clicking a button below this table the addNewField() method is called, which just contains the creation, setting of default values and adding of the text fields into a new row.
addNewField() {
int rows = flextable.getRowCount();
Button removeBtn = new Button("x");
removeBtn.getElement().setId(Integer.toString(rows));
//then the button's event handler
TextBox name = new TextBox();
name.setText("something");
flextable.setWidget(rows, 0, "name");
//repeat 4 more times with incrementing columns for the other widgets
}
This way I add entire rows of editable TextBoxes. What I need is a way to influence the values of the 6th column TextBox of a chosen row and the 5th column TextBox of chosen row + 1.
EDIT2: I've tried the dirty option just to see how it would go and somehow the compare inside the if breaks the app. The compiler detects a nullpointerexception and I can't even debug it with breakpoints because it fails to compile and won't start. I can't figure out why though. I threw the code directly into the event for testing purposes, so pardon the ugliness.
TextBox bis = new TextBox();
bis.setText(rows + ":10:00");
subs.setWidget(rows, 5, bis);
bis.addValueChangeHandler(new ValueChangeHandler<String>()
{
#Override
public void onValueChange(ValueChangeEvent<String> event)
{
allRows: for (int i = 0; i < subs.getRowCount(); i++)
{
for (int j = 0; j < subs.getCellCount(i); j++)
{
if ( subs.getWidget(i, j) == bis )
{
TextBox widgetAtColumnSix = ((TextBox) subs.getWidget(i, 5));
String text = widgetAtColumnSix.getText();
TextBox widgetAtColumnFiveRowPlusOne = ((TextBox) subs.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(text);
break allRows;
}
}
}
}
});
EDIT: Since you edited your question and you dont want to use EventBus you could iterate over your FlexTable and set your TextBox value depending on your current rowIndex and cellIndex... Its not nice but it should work:
public class CellWidget extends Composite {
private TextBox nameBox;
public CellWidget() {
FlowPanel flowPanel = new FlowPanel();
Button deleteButton = new Button("x");
nameBox = new TextBox();
nameBox.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
notifiyTextBox(CellWidget.this, event.getValue());
}
});
flowPanel.add(nameBox);
flowPanel.add(deleteButton);
initWidget(flowPanel);
}
public void setText(String text) {
nameBox.setText(text);
}
}
public void notifiyTextBox(CellWidget source, String string) {
rows: for (int i = 0; i < flextable.getRowCount(); i++) {
columns: for (int j = 0; j < flextable.getCellCount(i); j++) {
if (flextable.getWidget(i, j) == source) {
CellWidget widgetAtColumnSix = ((CellWidget) flextable.getWidget(i, 5));
widgetAtColumnSix.setText(string);
CellWidget widgetAtColumnFiveRowPlusOne = ((CellWidget) flextable.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(string);
break rows;
}
}
}
}
I still would recommend using an eventbus. To make it even more convenient there is the GWT Event Binder lib, which makes using events a breeze.
So when you change a value in your textbox[2,5] it also fires your CustomEvent. All Widgets, that need to change their textbox value just need to catch...

How to remove ContentEdit.Static element in ContentTools

I created a new tool in ContentTools that adds a static table (I don't want you to edit).
But being a static element doesn't maintain focus and I can not remove it when I click remove button.
I can do so that the table is not editable but can be removed if you click on it?
That's how I created the element:
new ContentEdit.Static('div', {'data-ce-moveable': true}, '<table><thead><tr><th>Foo head</th></tr></thead><tbody><tr><td>Foo body</td></tr></tbody></table>')
Thank you!
Static elements can't be interacted with for the most part (other elements can be dragged around them but that's about it). ContentEdit/Tools does allow you to restrict the some behaviour for elements but not being able to modify the content of a text element isn't one right now (though I think this might be a worthy addition).
However whilst there's no set way to do this at the moment here's an approach you can use that should provide the behaviour you describe (do let me know how you get on):
ContentEdit.Root.get().bind('mount', function(element) {
// We only care about `TableCell` elements
if (element.type() != 'TableCell') {
return;
}
// We only want to make the element read-only if the parent table has
// the `data-read-only` attribute.
var table = element.closest(function(node) {
return node.type() == 'Table';
});
if (table.attr('data-read-only') !== undefined) {
// Disable text editing for the table cell
element.tableCellText()._onKeyDown = function(ev) {
ev.preventDefault();
}
}
// Disable dragging of the table rows
var tableRow = element.closest(function(node) {
return node.type() == 'TableRow';
});
tableRow.can('drag', false);
tableRow.can('drop', false);
});

SWT - TableViewer - Refreshing Selection

I have a button that runs a method. The method gets the selected Rows in the table and adds them to an arraylist. This works well the first time executed. But if the user selected the wrong row, they will be able to re select a different row and add that selection data to the arraylist.
But with my current the code, it does not matter what row the user selects the second time the first selected data is always added to the arraylist. It is like the selection needs to be reset or refreshed before the user selects the new row.
Button Code
Button pdfButton = new Button(composite, SWT.PUSH);
pdfButton.setText("Get Plotter List");
pdfButton.setEnabled(true);
pdfButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
getPlotterSelection();
}
});
Method Code
public void getPlotterSelection() {
selectedPlotters.clear(); <-- Clearing the ArrayList
int[] row = viewer.getTable().getSelectionIndices(); <-- Getting Current Selections
Arrays.sort(row);
if (row.length > 0) {
for(int i = row.length-1; i >= 0; i--){
PrinterProfile pp = new PrinterProfile(aa.get(i).getPrinterName(), aa.get(i).getProfileName());
selectedPlotters.add(pp);
}
}
viewer.getTable().deselectAll();
}
As I am writing this, I think maybe the problem is in the getSelectionIndices(). It seems to be getting the number of rows selected, but not the actual row number
Edit
The problem was in my logic. I was getting the correct Indices but using i varaible in the for loop to get the value.
for(int i = row.length-1; i >= 0; i--){
PrinterProfile pp = new PrinterProfile(aa.get(i).getPrinterName(), aa.get(i).getProfileName());
changed it to
aa.get(row[i].getPrinterName(), etc...
and it works like I thought it would
Since you are already using a TableViewer, why not get the selection from it?
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
YourObject[] array = (YourObject[])selection.toArray();
Then you can iterate over the array and add them to your ArrayList.

Eclipse RCP ListProvider tweaking

I have problem with changing this image list provider in to thumbnail provider. In case of need I will post View for it too.
public Object[] getElements(Object inputElement) {
if (iDirname == null)
return null;
File dir = new File(iDirname);
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File directory, String filename) {
if (filename.endsWith("jpg") || (filename.endsWith("bmp")) || (filename.endsWith("png") || (filename.endsWith("JPG") || (filename.endsWith("BMP")) || (filename.endsWith("PNG")))))
return true;
else
return false;
}
};
String[] dirList = null;
if (dir.isDirectory()) {
dirList = dir.list(filter);
for (int i=0; i<dirList.length;++i){
//dirList2[i] = new Image(device, dirList2[i]); added this to try passing array of Images - failed.
dirList[i] = iDirname + File.separatorChar + dirList[i];
}
}
return dirList;
}
And the view
public void createPartControl(Composite parent) {
iViewer = new ListViewer(parent);
iViewer.setContentProvider(new DirListProvider());
getSite().setSelectionProvider(iViewer);
makeActions();
hookContextMenu();
contributeToActionBars();
}
I don't know how to change provided path lists to the thumbnail displaying. Should I get the provided content in to Array and iterate through it creating Images? If so how?
Thanks in advance for your help.
EDIT:
I added
ImageDescriptor[] dirList = null;
if (dir.isDirectory()) {
String[] dirList2 = dir.list(filter);
for (int i=0; i<dirList2.length;++i){
dirList[i] = ImageDescriptor.createFromImageData(new ImageData(iDirname + File.separatorChar + dirList2[i]));
//dirList[i] = iDirname + File.separatorChar + dirList[i];
}
}
return dirList;
but this is not showing anything at all.
When you are telling me to use Composite, is it my parent variable? I still don't know how to display the images from paths passed by ListProvider. I am really green in this :/
What you are missing here is a LabelProvider. You can use a LabelProvider to provide an image for each element in your viewer's input.
However, Francis Upton is right, I don't think ListViewer will really suit your needs as you will end up with a single column of images. Although you won't be able to add the images directly to your Composite, you will need to set them as the background image of a label.
There are a couple of other things to consider:
You need to dispose() of your Images once you're done with them as they use up System handles. Therefore you need to keep track of the Images you create in your getElements(Object) method.
If the directories you are reading the images from do not already contain thumbnails, you will need to scale the images before presenting them on your UI.
Remember, the array type you return from your ContentProvider's getElements(Object) method defines the type that will get passed into your LabelProvider's methods. So you started off returning an array of strings representing paths to the images. Your LabelProvider would need to load these into images to be returned from the provider's getImage method - but bear in mind what I said about disposing of these images! Then you switched to returning an Array of image descriptors, in this case you would need to cast your incoming Object to an ImageDescriptor and use that to create the Image in the getImage method. Maybe once you have this working you can think about whether this meets your needs, and then possibly look at doing a different implementation, such as the composite/gridlayout/label approach.
I would not use a ListViewer for this. I would just create a Composite and then using GridLayout set up the number of columns you want and margins and so forth, and then just add the images directly to the composite. As far as I know you cannot put arbitrary things like imagines in an SWT List, so the ListViewer is not going to help you. You can do all of this in the createPartControl method.

GWT CellBrowser- how to always show all values?

GWT's CellBrowser is a great way of presenting dynamic data.
However when the browser contains more rows than some (seemingly) arbitrary maximum, it offers a "Show More" label that the user can click to fetch the unseen rows.
How can I disable this behavior, and force it to always show every row?
There are several ways of getting rid of the "Show More" (which you can combine):
In your TreeViewModel, in your NodeInfo's setDisplay or in the DataProvider your give to the DefaultNodeInfo, in onRangeChange: overwrite the display's visible range to the size of your data.
Extend CellBrowser and override its createPager method to return null. It won't change the list's page size though, but you can set it to some very high value there too.
The below CellBrowser removes the "Show More" text plus loads all available elements without paging.
public class ShowAllElementsCellBrowser extends CellBrowser {
public ShowAllElementsCellBrowser(TreeViewModel viewModel, CellBrowser.Resources resources) {
super(viewModel, null, resources);
}
#Override
protected <C> Widget createPager(HasData<C> display) {
PageSizePager pager = new PageSizePager(Integer.MAX_VALUE);
// removes the text "Show More" during loading
display.setRowCount(0);
// increase the visible range so that no one ever needs to page
display.setVisibleRange(0, Integer.MAX_VALUE);
pager.setDisplay(display);
return pager;
}
}
I found a valid and simple solution in setting page size to the CellBrowser's builder.
Hope this will help.
CellBrowser.Builder<AClass> cellBuilder = new CellBrowser.Builder<AClass>(myModel, null);
cellBuilder.pageSize(Integer.MAX_VALUE);
cellBrowser = cellBuilder.build();
The easiest way to do this is by using the:
cellTree.setDefaultNodeSize(Integer.MAX_VALUE);
method on your Cell Tree. You must do this before you begin expanding the tree.
My workaround is to navigate through elements of treeview dom to get "show more" element with
public static List<Element> findElements(Element element) {
ArrayList<Element> result = new ArrayList<Element>();
findShowMore(result, element); return result; }
private static void findShowMore(ArrayList res, Element element) {
String c;
if (element == null) { return; }
if (element.getInnerText().equals("Show more")) { res.add(element);
}
for (int i = 0; i < DOM.getChildCount(element); i++) { Element
child = DOM.getChild(element, i); findShowMore(res, child); } }
and than use:
if (show) { element.getStyle().clearDisplay(); } else {
element.getStyle().setDisplay(Display.NONE); }