Re: Re: PDFKit: problem with PDFView goToDestination across PDFViews.
Re: Re: PDFKit: problem with PDFView goToDestination across PDFViews.
- Subject: Re: Re: PDFKit: problem with PDFView goToDestination across PDFViews.
- From: "Michael McCracken" <email@hidden>
- Date: Mon, 11 Dec 2006 15:37:28 -0800
Hi, thanks for the reply. Some further questions within:
On 12/11/06, John Calhoun <email@hidden> wrote:
On Dec 8, 2006, at 5:48 PM, Michael McCracken wrote:
Is it possible to use a PDFDestination generated from one PDFView to
direct another PDFView to go there (assuming they display the same
PDFDocument)?
No, not directly. This is because the PDFdestination references a PDFPage object that is unique to the owning PDFDocument.
I was using the same PDFDocument object - I had one PDFDocument, two
controllers, and two PDFViews, both set to use the same document
object.
I'm still confused as to why it doesn't work as I wrote it in my
original email, but I also tried a version that avoids passing
PDFDestinations, and instead uses page indexes and NSPoints and
regenerates a PDFDestination in the secondary window controller:
in mouseDown: in the main PDFView (a subclass):
('dest' is the destination I had been passing around. It is correct,
because if I use it directly with [self goToDestination:dest], I get
what I want.)
[controller showSubWindowAtPageNumber:[[self document] indexForPage:[dest page]]
location:[dest point]];
that calls this method:
- (void)showSubWindowAtPageNumber:(int)pageNum
location:(NSPoint)locationInPageSpace{
SubWindowController *swc = [[SubWindowController alloc] init];
[swc showWindow:self];
PDFDocument *doc = [[self document] pdfDocument]; // the same
document object as the result of [self document] above.
[swc setPdfDocument:doc];
[swc goToPageNumber:pageNum location:locationInPageSpace];
[subWindowControllers addObject:[swc autorelease]];
}
and swc - goToDestination: is simple:
- (void)goToPageNumber:(int)pageNum location:(NSPoint)locationInPageSpace{
// pdfView here is the subwindowcontroller's PDFView, that has the
same PDFDocument:
PDFPage *page = [[pdfView document] pageAtIndex:pageNum];
PDFDestination *dest = [[[PDFDestination alloc] initWithPage:page
atPoint:locationInPageSpace] autorelease];
[pdfView goToDestination:dest];
}
This code produces the same behavior I described earlier - the second
PDFView goes to the correct page, but always displays the top of the
page, not the location passed as locationInPageSpace.
I'd be happy to post a test project if that'd help.
Thanks,
-mike
So, when you get the PDFdestination (say from an annotation) PDF Kit has already taken the page reference (or page number — as an index) from the original PDF file and created a PDFDestination with the appropriate PDFPage object. This was a deliberate attempt to avoid using page numbers in PDF Kit and focus entirely on page objects when possible. FWIW, it means that you can move pages around in a PDF and not break links and such....
But there is an indirect way you can accomplish what you want with a few lines of code.
From the PDFDestiantion, get it's page:
page = [myDestination page];
From the page you can get the index within it's document:
index = [myDocument indexForPage: page];
or
index = [[page document] indexForPage: page];
Now you can create a new PDFDestination for document B. First you need to get the target page from document B.
pageB = [myDocumentB pageAtIndex: index];
Then create a new PDFDestination (getting the destination point from the original destination):
newDestination = [[PDFDestination alloc] initWithPage: pageB atPoint: [myDestination point]];
All together with less lines:
newPage = [myDocumentB pageAtIndex: [[page document] indexForPage: page]];
newDestination = [[PDFDestination alloc] initWithPage: newPage atPoint: [myDestination point]];
I want to click on a PDFView and have a new window with a second
PDFView open that shows that point.
I actually wanted to do that with destinations of link annotations,
but even the easy case doesn't quite work:
in a subclass of PDFView, in -mouseDown:(NSEvent *)theEvent, I'm doing this:
NSPoint windowMouseLoc = [theEvent locationInWindow];
NSPoint viewMouseLoc = [self convertPoint:windowMouseLoc
fromView:nil];
PDFPage *page = [self pageForPoint:viewMouseLoc
nearest:YES];
NSPoint pageSpaceMouseLoc = [self convertPoint:viewMouseLoc
toPage:page];
PDFDestination *dest = [[[PDFDestination alloc] initWithPage:page
atPoint:pageSpaceMouseLoc] autorelease];
[controller
showSubWindowAtDestination:dest];
// => this leads to calling "[pdfView goToDestination:dest];" on a
new PDFView in a different window. (It has the same PDFDocument).
// note that replacing this call with [self goToDestination:dest];
works as expected, in the original PDFView of
course.
I think the problem above is the page. Get the corresponding PDFPage from [pdfView document].
All of the values look sane in the debugger, including the value of dest,
up until the call to goToDestination, which scrolls to the right page
but invariably
just goes to the top of the correct page, apparently ignoring the
value of dest.point.
It doesn't completely ignore it, though - if I set it to something
arbitrary, like NSMakePoint(20,20), it will scroll to the top of the
page following dest.page.
I don't understand how it is using the point value of the destination
argument. Can anyone shed some light on this for me?
No, in fact it surprises me that it goes to the right page at all. Try my suggestions above and see if the behavior isn't more predictable.
john calhoun—
--
Michael McCracken
UCSD CSE PhD Candidate
research: http://www.cse.ucsd.edu/~mmccrack/
misc: http://michael-mccracken.net/wp/
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden