Posts RSS Comments RSS 32 Posts and 1,017 Comments till now

Quick Look APIs

I recently did some extensive reverse-engineering of Quick Look to investigate the API, mainly to track down how to get the cool zooming effect when Quick-Looking a file in Finder. It turns out it’s pretty simple to use Quick Look from your own code.

First you’ll need to load the framework found at /System/Library/PrivateFrameworks/QuickLookUI.framework

if([[NSBundle bundleWithPath:@"/System/…/QuickLookUI.framework"] load])
   NSLog(@"Quick Look loaded!");

Loading the framework with NSBundle is preferable to linking directly for 2 reasons:

  • If your app is to support Tiger then we can try to load the framework and only use Quick Look if it succeeds
  • Since the framework is in PrivateFrameworks there is the possibility that Apple may move it – e.g. if it becomes public

All your interaction with the QL system will be through the QLPreviewPanel singleton class, accessed using [QLPreviewPanel sharedPreviewPanel] – you’ll need to include this header so that you can use the methods without warnings. I use a define like this:

#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")

To allow QLPreviewPanel to be used in code.

Quick Look works with URLs (provided as NSURL instances) – to tell it which items to display you pass it an NSArray of NSURLs like so:

[[QLPreviewPanel sharedPreviewPanel] setURLs:URLs currentIndex:0 preservingDisplayState:YES]

The other 2 parameters should be self explanatory.

Then you need to tell the Quick Look panel to display. The simplest method is to have it fade in by using

[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFrontWithEffect:1]

And that’s it! To change the current set of items (e.g. when the user changes the selection) just call setURLs:current:preservingDisplayState: again with the new URLs. Check [[QLPreviewPanel sharedPreviewPanel] isOpen] to determine whether to use makeKeyAndOrderFrontWithEffect: or not. Call closeWithEffect: to close the panel.

To get the zoom effect we need a little more work. First we need to set up a delegate, like this:

[[[QLPreviewPanel sharedPreviewPanel] windowController] setDelegate:theDelegate]

This delegate must implement - (NSRect)previewPanel:(NSPanel*)panel frameForURL:(NSURL*)URL, returning the rect which the item represented by URL originates from.
With a delegate set, simply change your makeKeyAndOrderFrontWithEffect: call to use 2 and Quick Look will automatically request the frame when required.

I’ve put together a simple project which demonstrates using Quick Look, you can download the source code here.

13 Responses to “Quick Look APIs”

  1. on 11 Dec 2007 at 6:27 pmCiarán

    Leopard ships with a tool which you can use to preview files, just run

    qlmanage -p «file»
    

    To view a Quick Look preview.

  2. on 11 Dec 2007 at 8:52 pmXavier C.

    But qlmanage doesn’t have the fancy zooming effect nor the spacebar closing functionnality… which you provide with your example code

  3. on 28 Jan 2008 at 1:50 pmWarren

    This works great, thanks for the info! Saved me a ton of work.

  4. on 23 Jul 2008 at 3:06 pmNorbert M. Doerner

    Thank you so much for this really good introduction!

    One question, though:

    When the QuickLook window is the active one, and a single item is selected, in Finder, I can use the arrow keys to navigate through the current view. In your sample (and also in my own implementation), that only works if the original view is clicked onto (thus made active again).

    How could I set up the responder chain or the delegate, so that it would forward me keyDowns to my own view?

    (I have tried to add my own keyDown method to the delegate for QuickLook, but that was never called…)

    Thanks again!!

  5. on 03 Oct 2008 at 10:24 pmCarbcoa

    Just curious. Why are your implementation files Obj C++?

    I changed them to Obj-C and it they compile just fine. I just had to enable C99 to compile one of your for loops. I didn’t see any C++ in any of your code either.

  6. [...] Griekspoor of mekentosj fame pointed me in the direction of Ciarán Walsh’s reverse-engineering of the QuickLook private framework, and I decided to get [...]

  7. on 21 Oct 2008 at 1:35 pmMo

    Hi Ciarán,

    Your reverse-engineering efforts helped me to throw together DropLook—a little applet that previews, via QuickLook, whatever file (or files) you drop onto it in windows with standard decorations and previews.

    So, many thanks—you’ve assisted in me getting around to doing a smattering of Cocoa and I’ve worked around one of my biggest bugbears with QuickLook (the fact the windows vanish when you switch to another app).

  8. on 16 Dec 2008 at 8:35 pmTom

    This is great . .. Amy hints on navigating the file previewed for example a powerpoint file as a slide show in front row

  9. on 05 Mar 2009 at 6:17 pmkrasnojask

    thanks a lot for your reverse engineering efforts!

  10. on 16 Jun 2009 at 2:31 pm.max

    Thank you for the post. I’ve used this approach to customize Quick Look behavior a little further for what I need. By the way Quick Look UI appears to be a part of public Quartz framework in Snow Leopard. Which is good. Kinda. Most private APIs are deprecated though and it might get tricky to use Quick Look in both Leopard and Snow Leopard.

  11. [...] Ciarán Walsh’s Blog » Quick Look APIs ciaranwal.sh/2007/12/07/quick-look-apis – view page – cached I recently did some extensive reverse-engineering of Quick Look to investigate the API, mainly to track down how to get the cool zooming effect when Quick-Looking a file in Finder. It turns out it’s pretty simple to use Quick Look from your own code. — From the page [...]

  12. on 02 Mar 2010 at 9:14 amMikko

    Is it possible to launch quick look from a command line tool using this approach? I am aware of the qlmanage tool, but it provides only a subset of features from what launching quick look from Finder does.

  13. on 06 May 2010 at 3:17 pmJason Harris

    Things have changed in SnowLeopard and this Quicklook approach and the one used in GitX is no longer working….

Fork me on GitHub