Quick look preview multipage rich text

  • Hi all,

    I am trying to generate multipage pdf data for display in a quick look
    preview from rich text attributed string data. Attributed strings
    don't know anything about pages, so it seems to me that I'll have to
    go through the OS printing architecture to generate the multipage pdf
    content.

    Frustrating thing is, this works if I write the data to a file but not
    if I send it to quicklook. I can generate the pdf data with a custom
    print info specifying the page attributes, but quicklook does not
    display the content as multipage. If I use the same settings but a
    different print operation, writing the data to a temporary file
    instead, I get a correctly paginated document.

    Code follows.

    I understand that PDF content can be created with CGPDFContextCreate
    and the associated begin and end page calls, but the attributed string
    doesn't know about pages, so that seems like a dead end to me. If
    there's a method for doing it that way, I'm all for switching.

    You might also suggest just sending RTF to Quick Look, but I'd like
    the text attachments to display. Converting it to html seems like even
    more work.

    ===

    GenerateMultiPagePDFPreviewForURL(...)

    NSAttributedString *attrString = ...;
    NSTextView *textView = ... (filled with attrString);

    NSMutableData *pdfData = [NSMutableData data];
    NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];

    [printInfo setPaperSize:NSMakeSize(612,792)];
    [printInfo setHorizontalPagination: NSFitPagination];
    [printInfo setVerticalPagination: NSAutoPagination];
    [printInfo setVerticallyCentered:NO];

    NSPrintOperation *po = [NSPrintOperation PDFOperationWithView:textView
    insideRect:[textView bounds]
    toData:pdfData
    printInfo:printInfo];

    [po runOperation];
    QLPreviewRequestSetDataRepresentation(preview, (CFDataRef)pdfData,
    kUTTypePDF, NULL);

    ===

    Quicklook does not present a multipage preview with that code. But the
    following code writes a multipage document...

    ===

    NSAttributedString *attrString = ...;
    NSTextView *textView = ... (filled with attrString);

    NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    NSMutableDictionary *printInfoDict = [NSMutableDictionary
    dictionaryWithDictionary:[printInfo dictionary]];

    [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
    [printInfoDict setObject:@"someLocation.pdf" forKey:NSPrintSavePath];

    printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
    [printInfo setHorizontalPagination: NSFitPagination];
    [printInfo setVerticalPagination: NSAutoPagination];
    [printInfo setVerticallyCentered:NO];

    po  = [NSPrintOperation printOperationWithView:textView
    printInfo:printInfo];
    [po setShowPanels:NO];
    [po runOperation];

    ===

    In the first case I'm using [NSPrintOperation
    PDFOperationWithView:insideRect:toData:printInfo:] and in the second
    [NSPrintOperation printOperationWithView: printInfo:]. Is the
    PDFOperationWithView method not capable of producing multipage pdf
    data despite the custom printInfo?

    ~Phil
  • If I understand correctly your point, it seems that in the first case, you
    use the direct to data print operation and in the second case, you use the
    direct to file print operation then read back the file in memory and send it
    to Quick Look. Both methods use QLPreviewRequestSetDataRepresentation(). Am
    I right?

    What do you mean when you say "does not display the content as multipage".
    What does it display?

    You should try to dump on disk the data produced in the first case and take
    a look at it.

    --
    Julien

    On Wed, Jul 9, 2008 at 4:40 AM, Philip Dow <dev...> wrote:

    > Hi all,
    >
    > I am trying to generate multipage pdf data for display in a quick look
    > preview from rich text attributed string data. Attributed strings don't know
    > anything about pages, so it seems to me that I'll have to go through the OS
    > printing architecture to generate the multipage pdf content.
    >
    > Frustrating thing is, this works if I write the data to a file but not if I
    > send it to quicklook. I can generate the pdf data with a custom print info
    > specifying the page attributes, but quicklook does not display the content
    > as multipage. If I use the same settings but a different print operation,
    > writing the data to a temporary file instead, I get a correctly paginated
    > document.
    >
    > Code follows.
    >
    > I understand that PDF content can be created with CGPDFContextCreate and
    > the associated begin and end page calls, but the attributed string doesn't
    > know about pages, so that seems like a dead end to me. If there's a method
    > for doing it that way, I'm all for switching.
    >
    > You might also suggest just sending RTF to Quick Look, but I'd like the
    > text attachments to display. Converting it to html seems like even more
    > work.
    >
    > ===
    >
    > GenerateMultiPagePDFPreviewForURL(...)
    >
    > NSAttributedString *attrString = ...;
    > NSTextView *textView = ... (filled with attrString);
    >
    > NSMutableData *pdfData = [NSMutableData data];
    > NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    >
    > [printInfo setPaperSize:NSMakeSize(612,792)];
    > [printInfo setHorizontalPagination: NSFitPagination];
    > [printInfo setVerticalPagination: NSAutoPagination];
    > [printInfo setVerticallyCentered:NO];
    >
    > NSPrintOperation *po = [NSPrintOperation PDFOperationWithView:textView
    > insideRect:[textView bounds]
    > toData:pdfData
    > printInfo:printInfo];
    >
    > [po runOperation];
    > QLPreviewRequestSetDataRepresentation(preview, (CFDataRef)pdfData,
    > kUTTypePDF, NULL);
    >
    > ===
    >
    > Quicklook does not present a multipage preview with that code. But the
    > following code writes a multipage document...
    >
    > ===
    >
    > NSAttributedString *attrString = ...;
    > NSTextView *textView = ... (filled with attrString);
    >
    > NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    > NSMutableDictionary *printInfoDict = [NSMutableDictionary
    > dictionaryWithDictionary:[printInfo dictionary]];
    >
    > [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
    > [printInfoDict setObject:@"someLocation.pdf" forKey:NSPrintSavePath];
    >
    > printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
    > [printInfo setHorizontalPagination: NSFitPagination];
    > [printInfo setVerticalPagination: NSAutoPagination];
    > [printInfo setVerticallyCentered:NO];
    >
    > po  = [NSPrintOperation printOperationWithView:textView
    > printInfo:printInfo];
    > [po setShowPanels:NO];
    > [po runOperation];
    >
    > ===
    >
    > In the first case I'm using [NSPrintOperation
    > PDFOperationWithView:insideRect:toData:printInfo:] and in the second
    > [NSPrintOperation printOperationWithView: printInfo:]. Is the
    > PDFOperationWithView method not capable of producing multipage pdf data
    > despite the custom printInfo?
    >
    > ~Phil
    >
  • Le 9 juil. 08 à 23:54, Julien Jalon a écrit :

    > If I understand correctly your point, it seems that in the first
    > case, you
    > use the direct to data print operation and in the second case, you
    > use the
    > direct to file print operation then read back the file in memory and
    > send it
    > to Quick Look. Both methods use
    > QLPreviewRequestSetDataRepresentation(). Am
    > I right?
    >
    > What do you mean when you say "does not display the content as
    > multipage".
    > What does it display?
    >
    > You should try to dump on disk the data produced in the first case
    > and take
    > a look at it.
    >
    > --
    > Julien
    >
    > On Wed, Jul 9, 2008 at 4:40 AM, Philip Dow <dev...> wrote:
    >
    >> Hi all,
    >>
    >> I am trying to generate multipage pdf data for display in a quick
    >> look
    >> preview from rich text attributed string data. Attributed strings
    >> don't know
    >> anything about pages, so it seems to me that I'll have to go
    >> through the OS
    >> printing architecture to generate the multipage pdf content.
    >>
    >> Frustrating thing is, this works if I write the data to a file but
    >> not if I
    >> send it to quicklook. I can generate the pdf data with a custom
    >> print info
    >> specifying the page attributes, but quicklook does not display the
    >> content
    >> as multipage. If I use the same settings but a different print
    >> operation,
    >> writing the data to a temporary file instead, I get a correctly
    >> paginated
    >> document.
    >>
    >> Code follows.
    >>
    >> I understand that PDF content can be created with
    >> CGPDFContextCreate and
    >> the associated begin and end page calls, but the attributed string
    >> doesn't
    >> know about pages, so that seems like a dead end to me. If there's a
    >> method
    >> for doing it that way, I'm all for switching.
    >>
    >> You might also suggest just sending RTF to Quick Look, but I'd like
    >> the
    >> text attachments to display. Converting it to html seems like even
    >> more
    >> work.
    >>
    >> ===
    >>
    >> GenerateMultiPagePDFPreviewForURL(...)
    >>
    >> NSAttributedString *attrString = ...;
    >> NSTextView *textView = ... (filled with attrString);
    >>
    >> NSMutableData *pdfData = [NSMutableData data];
    >> NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    >>
    >> [printInfo setPaperSize:NSMakeSize(612,792)];
    >> [printInfo setHorizontalPagination: NSFitPagination];
    >> [printInfo setVerticalPagination: NSAutoPagination];
    >> [printInfo setVerticallyCentered:NO];
    >>
    >> NSPrintOperation *po = [NSPrintOperation
    >> PDFOperationWithView:textView
    >> insideRect:[textView bounds]
    >> toData:pdfData
    >> printInfo:printInfo];
    >>
    >> [po runOperation];
    >> QLPreviewRequestSetDataRepresentation(preview, (CFDataRef)pdfData,
    >> kUTTypePDF, NULL);
    >>
    >> ===
    >>
    >> Quicklook does not present a multipage preview with that code. But
    >> the
    >> following code writes a multipage document...
    >>
    >> ===
    >>
    >> NSAttributedString *attrString = ...;
    >> NSTextView *textView = ... (filled with attrString);
    >>
    >> NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    >> NSMutableDictionary *printInfoDict = [NSMutableDictionary
    >> dictionaryWithDictionary:[printInfo dictionary]];
    >>
    >> [printInfoDict setObject:NSPrintSaveJob
    >> forKey:NSPrintJobDisposition];
    >> [printInfoDict setObject:@"someLocation.pdf" forKey:NSPrintSavePath];
    >>
    >> printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
    >> [printInfo setHorizontalPagination: NSFitPagination];
    >> [printInfo setVerticalPagination: NSAutoPagination];
    >> [printInfo setVerticallyCentered:NO];
    >>
    >> po  = [NSPrintOperation printOperationWithView:textView
    >> printInfo:printInfo];
    >> [po setShowPanels:NO];
    >> [po runOperation];
    >>
    >> ===
    >>
    >> In the first case I'm using [NSPrintOperation
    >> PDFOperationWithView:insideRect:toData:printInfo:] and in the second
    >> [NSPrintOperation printOperationWithView: printInfo:]. Is the
    >> PDFOperationWithView method not capable of producing multipage pdf
    >> data
    >> despite the custom printInfo?
    >>
    >> ~Phil
    >>
    >>

    QuickLook support WebView contents, and the WebView support RTF data.

    convert your attributed string into RTF (using -[NSAttributedString
    RTFFromRange:documentAttributes:]), then send the data to QuickLook.
    You may also generate html from your RTF , but I think the convertion
    is sometime less accurate.
  • Le 10 juil. 08 à 00:20, Jean-Daniel Dupas a écrit :

    >
    > Le 9 juil. 08 à 23:54, Julien Jalon a écrit :
    >
    >> If I understand correctly your point, it seems that in the first
    >> case, you
    >> use the direct to data print operation and in the second case, you
    >> use the
    >> direct to file print operation then read back the file in memory
    >> and send it
    >> to Quick Look. Both methods use
    >> QLPreviewRequestSetDataRepresentation(). Am
    >> I right?
    >>
    >> What do you mean when you say "does not display the content as
    >> multipage".
    >> What does it display?
    >>
    >> You should try to dump on disk the data produced in the first case
    >> and take
    >> a look at it.
    >>
    >> --
    >> Julien
    >>
    >> On Wed, Jul 9, 2008 at 4:40 AM, Philip Dow <dev...> wrote:
    >>
    >>> Hi all,
    >>>
    >>> I am trying to generate multipage pdf data for display in a quick
    >>> look
    >>> preview from rich text attributed string data. Attributed strings
    >>> don't know
    >>> anything about pages, so it seems to me that I'll have to go
    >>> through the OS
    >>> printing architecture to generate the multipage pdf content.
    >>>
    >>> Frustrating thing is, this works if I write the data to a file but
    >>> not if I
    >>> send it to quicklook. I can generate the pdf data with a custom
    >>> print info
    >>> specifying the page attributes, but quicklook does not display the
    >>> content
    >>> as multipage. If I use the same settings but a different print
    >>> operation,
    >>> writing the data to a temporary file instead, I get a correctly
    >>> paginated
    >>> document.
    >>>
    >>> Code follows.
    >>>
    >>> I understand that PDF content can be created with
    >>> CGPDFContextCreate and
    >>> the associated begin and end page calls, but the attributed string
    >>> doesn't
    >>> know about pages, so that seems like a dead end to me. If there's
    >>> a method
    >>> for doing it that way, I'm all for switching.
    >>>
    >>> You might also suggest just sending RTF to Quick Look, but I'd
    >>> like the
    >>> text attachments to display. Converting it to html seems like even
    >>> more
    >>> work.
    >>>
    >
    >
    > QuickLook support WebView contents, and the WebView support RTF data.
    >
    > convert your attributed string into RTF (using -[NSAttributedString
    > RTFFromRange:documentAttributes:]), then send the data to QuickLook.
    > You may also generate html from your RTF , but I think the
    > convertion is sometime less accurate.

    Sorry for the noise, I think I should read the whole message before
    replying. That said, there is also an -
    RTFDFromRange:documentAttributes: method. RTFD should include
    attachement, I wonder if there is a way to send the generated data to
    a Webview (and so to QuickLook).
  • That's right, I realized after posting the message that I should have
    boiled it down to the following:

    + (NSPrintOperation *)PDFOperationWithView:insideRect:toData:printInfo:
    This operation produces a single page of PDF no matter what print
    settings I pass in, one very long page.

    + (NSPrintOperation *)printOperationWithView:printInfo:aPrintInfo
    This operation when set to write the data to disk correctly produces a
    paginated document.

    It's like the NSPrintOperation methods do not allow you to create a
    multi-page PDF in memory. You have to write it to disk first.

    I did take a look at the output in both operations, and that's exactly
    what happens. The fist op gives you one long page of pdf, which is
    unreadable when scaled to fit inside the quicklook preview. The second
    op gives you what you expect.

    I suppose I could use the second operation and then read back in the
    correctly paginated pdf, but then I'm writing out to the hard disk any
    time the user wants to quicklook my document. This seems like a
    terrible waste of resources.

    --

    In response to Jean-Daniel's suggestion. I can convert the RTFD to
    HTML, but then I need to go in and account for all of the rich text
    attachments, which doesn't sound like a simple task. I'd love to just
    create multi-page pdf data in memory and send that to quicklook.

    ~Phil

    On Jul 9, 2008, at 2:54 PM, Julien Jalon wrote:

    > If I understand correctly your point, it seems that in the first
    > case, you use the direct to data print operation and in the second
    > case, you use the direct to file print operation then read back the
    > file in memory and send it to Quick Look. Both methods use
    > QLPreviewRequestSetDataRepresentation(). Am I right?
    >
    > What do you mean when you say "does not display the content as
    > multipage". What does it display?
    >
    > You should try to dump on disk the data produced in the first case
    > and take a look at it.
    >
    > --
    > Julien
    >
    > On Wed, Jul 9, 2008 at 4:40 AM, Philip Dow <dev...> wrote:
    > Hi all,
    >
    > I am trying to generate multipage pdf data for display in a quick
    > look preview from rich text attributed string data. Attributed
    > strings don't know anything about pages, so it seems to me that I'll
    > have to go through the OS printing architecture to generate the
    > multipage pdf content.
    >
    > Frustrating thing is, this works if I write the data to a file but
    > not if I send it to quicklook. I can generate the pdf data with a
    > custom print info specifying the page attributes, but quicklook does
    > not display the content as multipage. If I use the same settings but
    > a different print operation, writing the data to a temporary file
    > instead, I get a correctly paginated document.
    >
    > Code follows.
    >
    > I understand that PDF content can be created with CGPDFContextCreate
    > and the associated begin and end page calls, but the attributed
    > string doesn't know about pages, so that seems like a dead end to
    > me. If there's a method for doing it that way, I'm all for switching.
    >
    > You might also suggest just sending RTF to Quick Look, but I'd like
    > the text attachments to display. Converting it to html seems like
    > even more work.
    >
    > ===
    >
    > GenerateMultiPagePDFPreviewForURL(...)
    >
    > NSAttributedString *attrString = ...;
    > NSTextView *textView = ... (filled with attrString);
    >
    > NSMutableData *pdfData = [NSMutableData data];
    > NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    >
    > [printInfo setPaperSize:NSMakeSize(612,792)];
    > [printInfo setHorizontalPagination: NSFitPagination];
    > [printInfo setVerticalPagination: NSAutoPagination];
    > [printInfo setVerticallyCentered:NO];
    >
    > NSPrintOperation *po = [NSPrintOperation PDFOperationWithView:textView
    > insideRect:[textView bounds]
    > toData:pdfData
    > printInfo:printInfo];
    >
    > [po runOperation];
    > QLPreviewRequestSetDataRepresentation(preview, (CFDataRef)pdfData,
    > kUTTypePDF, NULL);
    >
    > ===
    >
    > Quicklook does not present a multipage preview with that code. But
    > the following code writes a multipage document...
    >
    > ===
    >
    > NSAttributedString *attrString = ...;
    > NSTextView *textView = ... (filled with attrString);
    >
    > NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    > NSMutableDictionary *printInfoDict = [NSMutableDictionary
    > dictionaryWithDictionary:[printInfo dictionary]];
    >
    > [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
    > [printInfoDict setObject:@"someLocation.pdf" forKey:NSPrintSavePath];
    >
    > printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
    > [printInfo setHorizontalPagination: NSFitPagination];
    > [printInfo setVerticalPagination: NSAutoPagination];
    > [printInfo setVerticallyCentered:NO];
    >
    > po  = [NSPrintOperation printOperationWithView:textView
    > printInfo:printInfo];
    > [po setShowPanels:NO];
    > [po runOperation];
    >
    > ===
    >
    > In the first case I'm using [NSPrintOperation
    > PDFOperationWithView:insideRect:toData:printInfo:] and in the second
    > [NSPrintOperation printOperationWithView: printInfo:]. Is the
    > PDFOperationWithView method not capable of producing multipage pdf
    > data despite the custom printInfo?
    >
    > ~Phil
    >

    Journler Developer
    <phil...>
  • On Fri, Jul 11, 2008 at 8:00 PM, Philip Dow <dev...> wrote:

    >
    > That's right, I realized after posting the message that I should have
    > boiled it down to the following:
    >
    > + (NSPrintOperation *)PDFOperationWithView:insideRect:toData:printInfo:
    > This operation produces a single page of PDF no matter what print settings
    > I pass in, one very long page.
    >
    > + (NSPrintOperation *)printOperationWithView:printInfo:aPrintInfo
    > This operation when set to write the data to disk correctly produces a
    > paginated document.
    >
    > It's like the NSPrintOperation methods do not allow you to create a
    > multi-page PDF in memory. You have to write it to disk first.
    >
    > I did take a look at the output in both operations, and that's exactly what
    > happens. The fist op gives you one long page of pdf, which is unreadable
    > when scaled to fit inside the quicklook preview. The second op gives you
    > what you expect.
    >
    > I suppose I could use the second operation and then read back in the
    > correctly paginated pdf, but then I'm writing out to the hard disk any time
    > the user wants to quicklook my document. This seems like a terrible waste of
    > resources.
    >

    Please, don't do that as your plug-in really should avoid doing anything but
    reading stuff on disk. Maybe someone from the AppKit team will be able to
    find the source of your problem.

    --
    Julien

    >
  • I have a filed a report, Bug ID# 6072333.

    ~Phil

    On Jul 11, 2008, at 1:02 PM, Julien Jalon wrote:

    >
    >
    > On Fri, Jul 11, 2008 at 8:00 PM, Philip Dow <dev...> wrote:
    >
    > That's right, I realized after posting the message that I should
    > have boiled it down to the following:
    >
    >
    > + (NSPrintOperation
    > *)PDFOperationWithView:insideRect:toData:printInfo:
    > This operation produces a single page of PDF no matter what print
    > settings I pass in, one very long page.
    >
    > + (NSPrintOperation *)printOperationWithView:printInfo:aPrintInfo
    > This operation when set to write the data to disk correctly produces
    > a paginated document.
    >
    > It's like the NSPrintOperation methods do not allow you to create a
    > multi-page PDF in memory. You have to write it to disk first.
    >
    > I did take a look at the output in both operations, and that's
    > exactly what happens. The fist op gives you one long page of pdf,
    > which is unreadable when scaled to fit inside the quicklook preview.
    > The second op gives you what you expect.
    >
    > I suppose I could use the second operation and then read back in the
    > correctly paginated pdf, but then I'm writing out to the hard disk
    > any time the user wants to quicklook my document. This seems like a
    > terrible waste of resources.
    >
    >
    > Please, don't do that as your plug-in really should avoid doing
    > anything but reading stuff on disk. Maybe someone from the AppKit
    > team will be able to find the source of your problem.
    >
    > --
    > Julien
    >

    Journler Developer
    <phil...>