source: trunk/macosx/QuickLookPlugin/GeneratePreviewForURL.m @ 13433

Last change on this file since 13433 was 13433, checked in by livings124, 10 years ago

better spacing of the file/tracker/webseed list in Quick Look

File size: 8.5 KB
Line 
1#import "transmission.h"
2#import "NSStringAdditions.h"
3
4OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
5void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
6
7NSString * generateIconData(NSString * fileExtension, NSUInteger width, NSMutableDictionary * allImgProps)
8{
9    NSString * rawFilename = ![fileExtension isEqualToString: @""] ? fileExtension : @"blank_file_name_transmission";
10    NSString * iconFileName = [NSString stringWithFormat: @"%ldx%@.tiff", width, rawFilename]; //we need to do this once per file extension, per size
11   
12    if (![allImgProps objectForKey: iconFileName])
13    {
14        NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFileType: fileExtension];
15       
16        const NSRect iconFrame = NSMakeRect(0.0, 0.0, width, width);
17        NSImage * renderedIcon = [[NSImage alloc] initWithSize: iconFrame.size];
18        [renderedIcon lockFocus];
19        [icon drawInRect: iconFrame fromRect: NSZeroRect operation: NSCompositeCopy fraction: 1.0];
20        [renderedIcon unlockFocus];
21       
22        NSData * iconData = [renderedIcon TIFFRepresentation];
23        [renderedIcon release];
24       
25        NSDictionary * imgProps = @{
26            (NSString *)kQLPreviewPropertyMIMETypeKey : @"image/png",
27            (NSString *)kQLPreviewPropertyAttachmentDataKey : iconData };
28        [allImgProps setObject: imgProps forKey: iconFileName];
29    }
30   
31    return [@"cid:" stringByAppendingString: iconFileName];
32}
33
34OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
35{
36    // Before proceeding make sure the user didn't cancel the request
37    if (QLPreviewRequestIsCancelled(preview))
38        return noErr;
39   
40    //try to parse the torrent file
41    tr_info inf;
42    tr_ctor * ctor = tr_ctorNew(NULL);
43    tr_ctorSetMetainfoFromFile(ctor, [[(NSURL *)url path] UTF8String]);
44    const int err = tr_torrentParse(ctor, &inf);
45    tr_ctorFree(ctor);
46    if (err)
47        return noErr;
48   
49    NSURL * styleURL = [[NSBundle bundleWithIdentifier: @"org.m0k.transmission.QuickLookPlugin"] URLForResource: @"style" withExtension: @"css"];
50    NSString * styleContents = [NSString stringWithContentsOfURL: styleURL encoding: NSUTF8StringEncoding error: NULL];
51   
52    NSMutableString * htmlString = [NSMutableString string];
53    [htmlString appendFormat: @"<html><style type=\"text/css\">%@</style><body>", styleContents];
54   
55    NSMutableDictionary * allImgProps = [NSMutableDictionary dictionary];
56   
57    NSString * name = [NSString stringWithUTF8String: inf.name];
58    NSString * fileTypeString = inf.isMultifile ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension];
59   
60    const NSUInteger width = 32;
61    [htmlString appendFormat: @"<h2><img class=\"icon\" src=\"%@\" width=\"%ld\" height=\"%ld\" />%@</h2>", generateIconData(fileTypeString, width, allImgProps), width, width, name];
62   
63    NSString * fileSizeString = [NSString stringForFileSize: inf.totalSize];
64    if (inf.isMultifile)
65    {
66        NSString * fileCountString;
67        if (inf.fileCount == 1)
68            fileCountString = NSLocalizedString(@"1 file", "quicklook file count");
69        else
70            fileCountString= [NSString stringWithFormat: NSLocalizedString(@"%@ files", "quicklook file count"), [NSString formattedUInteger: inf.fileCount]];
71        fileSizeString = [NSString stringWithFormat: @"%@, %@", fileCountString, fileSizeString];
72    }
73    [htmlString appendFormat: @"<p>%@</p>", fileSizeString];
74   
75    NSString * dateCreatedString = inf.dateCreated > 0 ? [NSDateFormatter localizedStringFromDate: [NSDate dateWithTimeIntervalSince1970: inf.dateCreated] dateStyle: NSDateFormatterLongStyle timeStyle: NSDateFormatterShortStyle] : nil;
76    NSString * creatorString = inf.creator ? [NSString stringWithUTF8String: inf.creator] : nil;
77    if ([creatorString isEqualToString: @""]) creatorString = nil;
78    NSString * creationString = nil;
79    if (dateCreatedString && creatorString)
80        creationString = [NSString stringWithFormat: NSLocalizedString(@"Created on %@ with %@", "quicklook creation info"), dateCreatedString, creatorString];
81    else if (dateCreatedString)
82        creationString = [NSString stringWithFormat: NSLocalizedString(@"Created on %@", "quicklook creation info"), dateCreatedString];
83    else if (creatorString)
84        creationString = [NSString stringWithFormat: NSLocalizedString(@"Created with %@", "quicklook creation info"), creatorString];
85    if (creationString)
86        [htmlString appendFormat: @"<p>%@</p>", creationString];
87   
88    if (inf.comment)
89    {
90        NSString * comment = [NSString stringWithUTF8String: inf.comment];
91        if (![comment isEqualToString: @""])
92            [htmlString appendFormat: @"<p>%@</p>", comment];
93    }
94   
95    NSMutableArray * lists = [NSMutableArray array];
96   
97    if (inf.webseedCount > 0)
98    {
99        NSMutableString * listSection = [NSMutableString string];
100        [listSection appendString: @"<table>"];
101       
102        NSString * headerTitleString = inf.webseedCount == 1 ? NSLocalizedString(@"1 Web Seed", "quicklook web seed header") : [NSString stringWithFormat: NSLocalizedString(@"%@ Web Seeds", "quicklook web seed header"), [NSString formattedUInteger: inf.webseedCount]];
103        [listSection appendFormat: @"<tr><th>%@</th></tr>", headerTitleString];
104       
105        for (int i = 0; i < inf.webseedCount; ++i)
106            [listSection appendFormat: @"<tr><td>%s<td></tr>", inf.webseeds[i]];
107       
108        [listSection appendString:@"</table>"];
109       
110        [lists addObject: listSection];
111    }
112   
113    if (inf.trackerCount > 0)
114    {
115        NSMutableString * listSection = [NSMutableString string];
116        [listSection appendString: @"<table>"];
117       
118        NSString * headerTitleString = inf.trackerCount == 1 ? NSLocalizedString(@"1 Tracker", "quicklook tracker header") : [NSString stringWithFormat: NSLocalizedString(@"%@ Trackers", "quicklook tracker header"), [NSString formattedUInteger: inf.trackerCount]];
119        [listSection appendFormat: @"<tr><th>%@</th></tr>", headerTitleString];
120       
121#warning handle tiers?
122        for (int i = 0; i < inf.trackerCount; ++i)
123            [listSection appendFormat: @"<tr><td>%s<td></tr>", inf.trackers[i].announce];
124       
125        [listSection appendString:@"</table>"];
126       
127        [lists addObject: listSection];
128    }
129   
130    if (inf.isMultifile)
131    {
132        NSMutableString * listSection = [NSMutableString string];
133        [listSection appendString: @"<table>"];
134       
135        NSString * fileTitleString = inf.fileCount == 1 ? NSLocalizedString(@"1 File", "quicklook file header") : [NSString stringWithFormat: NSLocalizedString(@"%@ Files", "quicklook file header"), [NSString formattedUInteger: inf.fileCount]];
136        [listSection appendFormat: @"<tr><th>%@</th></tr>", fileTitleString];
137       
138#warning display size?
139#warning display folders?
140        for (int i = 0; i < inf.fileCount; ++i)
141        {
142            NSString * fullFilePath = [NSString stringWithUTF8String: inf.files[i].name];
143            NSCAssert([fullFilePath hasPrefix: [name stringByAppendingString: @"/"]], @"Expected file path %@ to begin with %@/", fullFilePath, name);
144           
145            NSString * shortenedFilePath = [fullFilePath substringFromIndex: [name length]+1];
146           
147            const NSUInteger width = 16;
148            [listSection appendFormat: @"<tr><td><img class=\"icon\" src=\"%@\" width=\"%ld\" height=\"%ld\" />%@<td></tr>", generateIconData([shortenedFilePath pathExtension], width, allImgProps), width, width, shortenedFilePath];
149        }
150       
151        [listSection appendString:@"</table>"];
152       
153        [lists addObject: listSection];
154    }
155   
156    if ([lists count] > 0)
157        [htmlString appendFormat: @"<hr/><br>%@", [lists componentsJoinedByString: @"<br><br>"]];
158   
159    [htmlString appendString: @"</body></html>"];
160   
161    tr_metainfoFree(&inf);
162   
163    NSDictionary * props = @{ (NSString *)kQLPreviewPropertyTextEncodingNameKey : @"UTF-8",
164                                (NSString *)kQLPreviewPropertyMIMETypeKey : @"text/html",
165                                (NSString *)kQLPreviewPropertyAttachmentsKey : allImgProps };
166   
167    QLPreviewRequestSetDataRepresentation(preview, (CFDataRef)[htmlString dataUsingEncoding: NSUTF8StringEncoding], kUTTypeHTML, (CFDictionaryRef)props);
168   
169    return noErr;
170}
171
172void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview)
173{
174    // Implement only if supported
175}
Note: See TracBrowser for help on using the repository browser.