PDA

View Full Version : Printing NSView subclass




cblackburn
Dec 18, 2006, 04:06 PM
Hey all,

I have a custom class that inherits off NSView and I want to be able to print it. I want it to cover the whole of one page when it prints, so I overrode the print: function as so:-

// Make sure we use all of the page when printing
- (void)print:(id)sender
{
NSPrintOperation *op = [NSPrintOperation currentOperation];
NSPrintInfo *pInfo = [op printInfo];

[pInfo setHorizontalPagination:NSFitPagination];
[pInfo setVerticalPagination:NSFitPagination];

[op setPrintInfo:pInfo];

// Continue printing
[super print:sender];
}

However it does not cover the whole page. What am I doing wrong?

Chris



cblackburn
Dec 18, 2006, 04:09 PM
I have also tried this to no avail

- (void)awakeFromNib
{
[[NSPrintInfo sharedPrintInfo] setVerticalPagination:NSFitPagination];
[[NSPrintInfo sharedPrintInfo] setHorizontalPagination:NSFitPagination];
}

robbieduncan
Dec 18, 2006, 04:39 PM
print: is the action method sent down the responder chain. You should probably not override this within the view.

All drawing for printing gets done in the normal drawRect: method. You can use the NSGraphics context isDrawingToScreen (http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSGraphicsContext_Class/Reference/Reference.html#//apple_ref/occ/instm/NSGraphicsContext/isDrawingToScreen) to discover if you are printing.

If you want/need to alter the print info like that the view is totally the wrong place to do it. That's controller code and belongs in the controller. If you are using a document based app put it in NSDocument, otherwise the NSApplication delegate might be a good place...

cblackburn
Dec 18, 2006, 04:47 PM
otherwise the NSApplication delegate might be a good place...

How would I do that, do I need to do something in Interface builder?

Chris

robbieduncan
Dec 18, 2006, 05:15 PM
You'd create a new object, instansiate it in Interface Builder and connect it to the delegate outlet of the File's Owner in MainMenu.nib.

robbieduncan
Dec 18, 2006, 05:20 PM
Scratch that: it doesn't seem to work as something higher in the responder chain is getting the print: message, probably the window.

robbieduncan
Dec 18, 2006, 05:29 PM
OK I've read the documentation. You can have print: in the view if you want but the print: operation will only get routed to that view if it's got focus. I don't think your print: is ever getting called. You could subclass NSWindow and override it there...

I'd drop some NSLogs into see what's getting called where...

cblackburn
Dec 18, 2006, 05:29 PM
Scratch that: it doesn't seem to work as something higher in the responder chain is getting the print: message, probably the window.

I tried connecting the delagate connection of Files Owner and the window containing the control to my main controller class, then placing the afformentioned code in awakeFromNib, but neither has worked :(

robbieduncan
Dec 18, 2006, 05:38 PM
I think you are trying to use pagination wrong. Pagination breaks the image up onto one or more pages. So what you are doing is say fit the contents on a single page. This will scale the content to fit on that page. It will only scale the content down though. As far as I am aware if you want to scale the content up to fill the page you have to do it yourself in drawRect:

cblackburn
Dec 18, 2006, 05:51 PM
I think you are trying to use pagination wrong. Pagination breaks the image up onto one or more pages. So what you are doing is say fit the contents on a single page. This will scale the content to fit on that page. It will only scale the content down though. As far as I am aware if you want to scale the content up to fill the page you have to do it yourself in drawRect:

Hmm, well, my drawRect is written such that it will fill whatever rect it is given. It seems that when it prints it only gets a rect for a small portion of the piece of paper.

robbieduncan
Dec 18, 2006, 05:54 PM
I don't believe the rect gets changed when you print: it's the one in the view. To do what you want to do you probably need to resize the view or copy the view to the correct size when you print.

Or ask the print info what size the paper is and try drawing to that size...

cblackburn
Dec 18, 2006, 06:16 PM
OK I've read the documentation. You can have print: in the view if you want but the print: operation will only get routed to that view if it's got focus. I don't think your print: is ever getting called. You could subclass NSWindow and override it there...

I'd drop some NSLogs into see what's getting called where...

Eugh, that sounds wonderfully horrific. *sigh* it's gonna be a long night.

robbieduncan
Dec 18, 2006, 06:29 PM
Here's an example project to get you started. It manages to do what you want, although the state of the view after the print operation is messed up so you might want to sort that.

I'm not saying this is a good way to do this: I've never looked at the printing system too much before.

Now I've really got to get some sleep!