setting selection in PDFView

  • Dear list,

    In my app I have a user action which allows them to select a particular line in a PDFView. The relevant method (on my PDFView subclass) looks like this.

    - (void)displayLineAtPoint:(NSPoint)point inPageAtIndex:(NSUInteger)pageIndex
    {
      if (pageIndex < [[self document] pageCount]) {
        [[self window] makeFirstResponder:self];
        PDFPage *page = [[self document] pageAtIndex:pageIndex];
        PDFSelection *sel = [page selectionForLineAtPoint:point];
        [self performSelectorOnMainThread:@selector(goToPage:) withObject:page waitUntilDone:YES];
        [self setCurrentSelection:sel];
        [self scrollSelectionToVisible:self];
        [self display];
        [self setCurrentSelection:nil];
        [self performSelector:@selector(setCurrentSelectionAndAnimate:) withObject:sel afterDelay:0.2];
      }
    }

    The problem is that I have to call this twice to get the desired effect. On the first call the view scrolls to the correct page but the selection is not shown. Only on the second call is the selection shown.

    Does anyone have any experience with PDFView and selections? Is there are more reliable way to do what I want?

    Cheers,

    Martin
  • On 7/20/12 6:28 PM, Martin Hewitson wrote:
    > Dear list,
    >
    > In my app I have a user action which allows them to select a particular line in a PDFView. The relevant method (on my PDFView subclass) looks like this.
    >
    > - (void)displayLineAtPoint:(NSPoint)point inPageAtIndex:(NSUInteger)pageIndex
    > {
    > if (pageIndex < [[self document] pageCount]) {
    > [[self window] makeFirstResponder:self];
    > PDFPage *page = [[self document] pageAtIndex:pageIndex];
    > PDFSelection *sel = [page selectionForLineAtPoint:point];
    > [self performSelectorOnMainThread:@selector(goToPage:) withObject:page waitUntilDone:YES];
    > [self setCurrentSelection:sel];
    > [self scrollSelectionToVisible:self];
    > [self display];
    > [self setCurrentSelection:nil];
    > [self performSelector:@selector(setCurrentSelectionAndAnimate:) withObject:sel afterDelay:0.2];
    > }
    > }

    [self performSelectorOnMainThread:@selector(goToPage:) withObject:page
    waitUntilDone:YES];

    looks suspicious. If you're doing this on a secondary thread (which this line
    implies), I'm pretty sure that at least the call to -makeFirstResponder: is
    illegal (main thread only). Not sure about the PDF document class.

    Regards
    Markus
    --
    __________________________________________
    Markus Spoettl
  • On Jul 20, 2012, at 07:13 PM, Markus Spoettl <ms_lists...> wrote:

    > On 7/20/12 6:28 PM, Martin Hewitson wrote:
    >> Dear list,
    >>
    >> In my app I have a user action which allows them to select a particular line in a PDFView. The relevant method (on my PDFView subclass) looks like this.
    >>
    >> - (void)displayLineAtPoint:(NSPoint)point inPageAtIndex:(NSUInteger)pageIndex
    >> {
    >> if (pageIndex < [[self document] pageCount]) {
    >> [[self window] makeFirstResponder:self];
    >> PDFPage *page = [[self document] pageAtIndex:pageIndex];
    >> PDFSelection *sel = [page selectionForLineAtPoint:point];
    >> [self performSelectorOnMainThread:@selector(goToPage:) withObject:page waitUntilDone:YES];
    >> [self setCurrentSelection:sel];
    >> [self scrollSelectionToVisible:self];
    >> [self display];
    >> [self setCurrentSelection:nil];
    >> [self performSelector:@selector(setCurrentSelectionAndAnimate:) withObject:sel afterDelay:0.2];
    >> }
    >> }
    >
    > [self performSelectorOnMainThread:@selector(goToPage:) withObject:page waitUntilDone:YES];
    >
    > looks suspicious. If you're doing this on a secondary thread (which this line implies), I'm pretty sure that at least the call to -makeFirstResponder: is illegal (main thread only). Not sure about the PDF document class.

    No, it's all done on the main thread. Actually, using performSelectorOnMainThread... was just an attempt to get the thing to behave properly. Nominally I'm just calling -setCurrentSelectionAndAnimate: directly. The results are the same.

    Cheers,

    Martin

    >
    > Regards
    > Markus
    > --
    > __________________________________________
    > Markus Spoettl

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Martin Hewitson
    Albert-Einstein-Institut
    Max-Planck-Institut fuer
        Gravitationsphysik und Universitaet Hannover
    Callinstr. 38, 30167 Hannover, Germany
    Tel: +49-511-762-17121, Fax: +49-511-762-5861
    E-Mail: <martin.hewitson...>
    WWW: http://www.aei.mpg.de/~hewitson
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • On 20 Jul 2012, at 18:26, Martin Hewitson wrote:

    >>> In my app I have a user action which allows them to select a particular line in a PDFView. The relevant method (on my PDFView subclass) looks like this.
    >>>
    >>> - (void)displayLineAtPoint:(NSPoint)point inPageAtIndex:(NSUInteger)pageIndex
    >>> {
    >>> if (pageIndex < [[self document] pageCount]) {
    >>> [[self window] makeFirstResponder:self];
    >>> PDFPage *page = [[self document] pageAtIndex:pageIndex];
    >>> PDFSelection *sel = [page selectionForLineAtPoint:point];
    >>> [self performSelectorOnMainThread:@selector(goToPage:) withObject:page waitUntilDone:YES];
    >>> [self setCurrentSelection:sel];
    >>> [self scrollSelectionToVisible:self];
    >>> [self display];
    >>> [self setCurrentSelection:nil];
    >>> [self performSelector:@selector(setCurrentSelectionAndAnimate:) withObject:sel afterDelay:0.2];
    >>> }
    >>> }
    >>
    >> [self performSelectorOnMainThread:@selector(goToPage:) withObject:page waitUntilDone:YES];
    >>
    >> looks suspicious. If you're doing this on a secondary thread (which this line implies), I'm pretty sure that at least the call to -makeFirstResponder: is illegal (main thread only). Not sure about the PDF document class.
    >
    > No, it's all done on the main thread. Actually, using performSelectorOnMainThread... was just an attempt to get the thing to behave properly. Nominally I'm just calling -setCurrentSelectionAndAnimate: directly. The results are the same.

    goToPage: will scroll the shortest distance that shows as much of the page as possible, so it might not even show the whole page and hence, possibly, not the selection. You might want to create a destination (to page and point) and then use goToDestination: to go there. It offers greater precision, and ensures point will always be visible.

    Also: is "setCurrentSelectionAndAnimate" a method of your own? PDFView has setCurrentSelection:animate:

    -António

    ----------------------------------------------------
    A merry heart does good like medicine
    ----------------------------------------------------
previous month july 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today