November 15, 2008

Tabbing in PDF Annotation Editor

Filed under: Uncategorized — frameworker @ 8:09 pm

Written by John Calhoun, the PDF Annotation Editor is a sample application that uses PDF Kit to examine, edit, and create PDF annotations. 

It lets you tab in Test mode but not in Edit mode.

I needed to tab in Edit mode, but was headed in the wrong direction when John Calhoun graciously provided this recipé:

“Grab keyDown’s in your PDFView subclass and keep track of the current annotation with “focus”.  Manually advance the focus by going round-robin through the annotations on the page.”

Here is its implementation:

// Add a case to [PDFViewEdit keyDown] to detect the Tab key
// and call "advanceFocus" when it is hit.
- (void) keyDown: (NSEvent *) theEvent
    unichar oneChar;

    // Skip out if not in 'edit mode'.
    if (_editMode == NO)
        [super keyDown: theEvent];

    // Get the character from the keyDown event.
    oneChar = [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];

    // Delete or Tab ?
    if ((oneChar == NSDeleteCharacter) || (oneChar == NSDeleteFunctionKey))
        [self delete: self];
    else if (oneChar == NSTabCharacter)
        [self advanceFocus];
        [super keyDown: theEvent];

Add two methods to PDFViewEdit.m
and their method declarations to PDFViewEdit.h.

// Tab key was hit; move focus to the next widget.
- (void) advanceFocus
    if (_activeAnnotation != NULL)
        PDFPage * currentPage = [_activeAnnotation page];

        // Walk array of annotations.
        NSArray *annotations = [currentPage annotations];
        int annotCount = [annotations count];

        int activeIndex = [annotations indexOfObject: _activeAnnotation];

        int newActiveIndex = [self nextAnnotIndex: activeIndex withinCount: annotCount];

        PDFAnnotation * newActiveAnnotation = [annotations objectAtIndex: newActiveIndex];

        [self selectAnnotation: newActiveAnnotation];

// return the index of the next annot, wrapping around on the current page.
– (int) nextAnnotIndex: (int) activeIndex withinCount: (int) annotCountForPage
    int nextIndex = -1;

if (activeIndex +1 < annotCountForPage)     {         nextIndex = activeIndex + 1;     }     else     {         nextIndex = 0; // Wrap around on page.     }     return nextIndex; } [/sourcecode] Voilà, that's all there is to it!  Thanks John!


November 9, 2008

Plan B

Filed under: Uncategorized — frameworker @ 12:20 am

Plan B: A backup plan for unforseen contingencies.

Plan B is an interactive PDF forms editor that lets you edit, save and re-edit PDF forms. It requires OS X 10.5.

UPDATE: Preview now lets you save and re-edit PDF forms! So, for all practical purposes, Plan B is defunct (along with Buffalo Bill).

To install Plan B in your Applications folder, first download Plan B, then double-click its dmg file. Next, drag the Plan B icon onto the Applications folder alias in the Plan B.dmg window.

Your edited forms data will only be visible in Plan B. To make the edited form viewable (but not editable) by another PDF viewer like Preview, flatten the file by doing a “Save as PDF…” in Plan B’s “Print…” dialog.

There is no charge to use Plan B, although its use is governed by the EULA you accepted by downloading it.

Your feedback will be appreciated!

UPDATE: The original upload, version ß2, only worked on Intel hardware; I’ve uploaded version ß3 which is a Universal Binary.

Blog at