Cocoa Programming for Mac OS X - Aaron Hillegass [107]
// How many lines per page?
linesPerPage = pageRect.size.height / lineHeight;
// Pages are 1-based
range->location = 1;
// How many pages will it take?
range->length = [people count] / linesPerPage;
if ([people count] % linesPerPage) {
range->length = range->length + 1;
}
return YES;
}
- (NSRect)rectForPage:(NSInteger)i
{
// Note the current page
currentPage = i - 1;
// Return the same page rect everytime
return pageRect;
}
#pragma mark Drawing
// The origin of the view is at the upper-left corner
- (BOOL)isFlipped
{
return YES;
}
- (void)drawRect:(NSRect)r
{
NSRect nameRect;
NSRect raiseRect;
raiseRect.size.height = nameRect.size.height = lineHeight;
nameRect.origin.x = pageRect.origin.x;
nameRect.size.width = 200.0;
raiseRect.origin.x = NSMaxX(nameRect);
raiseRect.size.width = 100.0;
NSInteger i;
for (i=0; i if (index >= [people count]) { break; } Person *p = [people objectAtIndex:index]; // Draw index and name nameRect.origin.y = pageRect.origin.y + (i * lineHeight); NSString *nameString = [NSString stringWithFormat:@"%2d %@", index, [p personName]]; [nameString drawInRect:nameRect withAttributes:attributes]; raiseRect.origin.y = nameRect.origin.y; NSString *raiseString=[NSString stringWithFormat:@"%4.1f%%", [p expectedRaise]]; [raiseString drawInRect:raiseRect withAttributes:attributes]; } } @end The code in RMDocument.m is pretty simple. First, import PeopleView.h at the top: #import PeopleView.h Then implement printOperationWithSettings:error:: - (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps error:(NSError **)e; { PeopleView *view = [[PeopleView alloc] initWithPeople:employees]; NSPrintInfo *printInfo = [self printInfo]; NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:view printInfo:printInfo]; return printOp; } In the MainMenu.xib file, note that the Print... menu item is nil-targeted and that its action is printDocument:, which will trigger printOperationWithSettings:error:. Build and run the application. Note that a setup of multiple pages per sheet (4-up, for example) works. Notice that you can change the paper size and more or fewer people subsequently appear on each page. For the More Curious: Are You Drawing to the Screen? In your drawRect: method, you can ask the current graphics context if it is currently drawing to the screen: if ([[NSGraphicsContext currentContext] isDrawingToScreen]) { ...draw grid... } Challenge Chapter 28. Web Services Figure 28.1. Your Average Web Service in Action HTTP requests and responses are handled by NSURL, NSURLRequest, and NSURLConnection (Figure 28.2). Figure 28.2. Classes for Making HTTP Requests Generating and parsing XML is typically done in one of two ways. The high-level method is to use NSXMLDocument and NSXMLNode. If you have an NSData containing the following XML, NSXMLDocument will parse it into a handy tree (Figure 28.3): Figure 28.3. Parsed XML Document Low-level XML parsing is done with NSXMLParser. As it parses NSData containing XML, NSXMLParser makes calls to its delegate as it encounters XML elements and other structures. Low-level XML parsing is most appropriate when working with a large XML document or when memory
In an application, you will often want to draw things differently on screen than on the printer. For example, in a drawing program, the on-screen view might show a grid on-screen but not when printed on paper.
Add page numbers to the printout.
Web services are getting a lot of hype. In the end, however, a Web service is just an HTTP request and response where each may be carrying XML data (Figure 28.1). So using a Web service from Cocoa is simply a matter of being able to send HTTP requests and receive responses and it also may require generating and parsing XML or JSON.