views:

152

answers:

4

I'm trying to print a document. The document is an array of NSImageReps, or a single NSPDFImageRep, which has multiple pages. I'm having trouble figuring out how to use the NSPrintOperation class to print this.

The NSPrintOperation seems to need an NSView to print. Do I need to manually add each image into the view at a calculated position and then let it do the pagination? that seems like it isn't in the spirit of Cocoa... is there some technique that I'm missing?

A: 

You can't print something that can't be drawn. NSView is how you draw what you want to print. You can make an NSView subclass just for printing that decides how you want the printing to work (e.g. do you want one NSImageRep for page — ANY size page?) by using NSView's pagination methods. Just override knowsPageRange: to return YES.

Chuck
right, of course you can't print what you can't draw. But getting it to deal with multiple imageReps seems tedious. Is there a more elegant way of doing it than manually placing the images into a huge virtual view and then telling it where each rectangle is manually? It seems, needlessly baroque... Also, it is unclear what the point of knowsPageRange: is. what does it mean to know a page range?
Brian Postow
You could use NSImageViews that automatically position the image, but you're going to have to specify how the document is drawn somehow. And `knowsPageRange:` tells the printing subsystem that you want to handle pagination yourself.
Chuck
A: 

For Future reference, I believe the answer is PDFViews. you can add a PDFPage all at once to a PDFView (Via a PDFDocument) and then you can print with printWithInfo:autoRotate:

In theory at least, I have gotten the view created, and the print dialog comes up, but when I hit "print" the dialog doesn't disappear...

But that's a different question.

Brian Postow
A: 

In addition to other's answers, if your "isn't in the spirit of Cocoa" comment is meant in the MVC sense, keep in mind a printed representation is also a "view" of the data. :-)

Joshua Nozzi
+1  A: 

You can create view that that displays what you want to print. Then you use it to create print operation.

You would typically created a view that displays your image. You implement an algorithm to figure out what image you want to display on which page. Then you return number of pages available to print and implement method to print specific page.

  • If you have 10 images and you want to print one per page that's easy.
  • If you want to print records per page and you have 100 records then you calculate how many records you can fit on a page (using current font size and number of lines per record).
  • Then you figure out from records per page how many pages you need to display all records - this is your number of pages (range of pages).
  • When requested to print specific range of pages you select the records that should be show on given page and display them.
  • See references below on how to implement these steps. See the custom pagination info for example how to implement these steps, it's not difficult.

See Print Programming Topics, or the full example I reference bellow from the book has pagination which I did not included here. Have a look at the custom pagination for more hints.

If you have Document Based application and a view that you want to dump to printer, then in our MyDocument (or whatever you call it) that extends NSDocument you would implement:

- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps
                                           error:(NSError **)e

The view then uses standard drawRect: for drawing.

Example, here PeopleView just draws a table of people details, it takes a NSDictonary of people employees here:

- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps
                                           error:(NSError **)e
{
    PeopleView * view = [[PeopleView alloc] initWithPeople:employees];
    NSPrintInfo * printInfo = [self printInfo];
    NSPrintOperation * printOp
        = [NSPrintOperation printOperationWithView:view
                                         printInfo:printInfo];
    [view release];
    return printOp;
}

You can look for more details in chapter 27, Printing, in Hillegass' Cocoa Programming For Mac OS X.

stefanB
The problem is that I don't want to have to do custom pagination. I just one one image per page, so I'd rather not have to manually place each image into the view at a specified location and then deal with that. I think the PDFView is much easier for what I want to do...
Brian Postow