NSLayoutManager does not always signal atEnd
NSLayoutManager does not always signal atEnd
- Subject: NSLayoutManager does not always signal atEnd
- From: Phill Kelley <email@hidden>
- Date: Sat, 8 May 2004 15:26:19 +1000
I'm having a bit of a problem with NSLayoutManager's delegate method:
layoutManager:didCompleteLayoutForTextContainer:atEnd
The primary UI for the app I'm working is an NSOutlineView where each row
represents an object. When represented in a printed form, the amount of
information associated with each object is highly variable, from as little
as a few lines through to multiple pages. Because I don't have an existing
laid-out NSView that I can just print, I handle printing by generating each
report as one huge attributed string and then pass the whole layout and
pagination problem to a "hand-assembled text system". I've used the
TextEdit example as my guide, particularly in the way it implements the
didCompleteLayout delegate method mentioned above.
Quite early on, I noticed that if I was working with large data sets (say
5,000 objects), the print dialog box would appear long before the layout
manager had actually finished laying out the text. Pressing "Print" in that
situation would only produce the pages that had been laid out up until that
point. I solved that by splitting my printDocument method into two parts
and had the didCompleteLayout method signal my document instance that it
could put up the print dialog box once the layout manager said that it had
finished.
All of that has been working fine for months.
But I've just stumbled across an end-case. Any time the last page is
completely filled, didCompleteLayout is never called with atEnd set to YES.
It doesn't matter if the report is one page or five hundred pages. If the
last line on the last page has something in it, didCompleteLayout is never
called with atEnd:YES. I use words like "line" and "page" loosely - in this
context, they mean whatever layout manager thinks they mean.
By reverting to an all-in-one printDocument method and giving the layout
manager enough time to finish I've been able to determine that the layout
is, in fact, complete and will print correctly. It's just that
didCompleteLayout is never invoked with atEnd:YES.
I've also been able to determine that the problem appears to be related to
not having anything on the n+1 page. The last character in the
NSTextStorage is always a line-feed, so the last line on the last page ends
when that line-feed is encountered. If that last line happens to also be
the last printable line on the logical page, the layout manager reacts by
invoking didCompleteLayout with textContainer==lastContainer and atEnd:NO,
which is a request to add another page. I give it another page but it never
follows-up with atEnd:YES.
This behavior is consistent for page size (A4 vs Quarto), orientation,
scaling factor, and choice of printer. No matter how I cut the cake, if the
last logical line of the last logical page has something in it, atEnd:YES
never occurs.
I can solve the problem by adding an attributed space as the last character
in the text storage. I get a blank page for my trouble but at least
didCompleteLayout is called one final time with atEnd:YES. If this winds up
being the permanent solution, I will probably change it to say "end of
report" or some such (ie, so that it looks like a feature rather than a
bug).
Has anyone else encountered a problem like this? Am I on the right track in
supposing that having a line-feed as the last character in the buffer is
the underlying cause or am I missing some other critical factor when it
comes to attributed strings and layout?
Regards & thanks, Phill
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.