Skip to content

Commit

Permalink
Only show Query & Raw Query
Browse files Browse the repository at this point in the history
  • Loading branch information
kenta.hatano committed Aug 28, 2018
1 parent 6997a84 commit 88f7be8
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 56 deletions.
16 changes: 4 additions & 12 deletions QLSmartFolder.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,29 @@
objects = {

/* Begin PBXBuildFile section */
4A2A823A213565AE0057AE57 /* smartFolderIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4A2A8239213565AE0057AE57 /* smartFolderIcon.png */; };
4A8AF8DB2133B9FF00B0A97B /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A8AF8DA2133B9FF00B0A97B /* GenerateThumbnailForURL.m */; };
4A8AF8DD2133B9FF00B0A97B /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A8AF8DC2133B9FF00B0A97B /* GeneratePreviewForURL.m */; };
4A8AF8DF2133B9FF00B0A97B /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A8AF8DE2133B9FF00B0A97B /* main.c */; };
4A8AF8E92133BEF100B0A97B /* template.html in Resources */ = {isa = PBXBuildFile; fileRef = 4A8AF8E82133BEF100B0A97B /* template.html */; };
4ABF9B502133ED51009DEE78 /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ABF9B4F2133ED51009DEE78 /* CoreSpotlight.framework */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
4A2A8239213565AE0057AE57 /* smartFolderIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = smartFolderIcon.png; sourceTree = "<group>"; };
4A8AF8D72133B9FE00B0A97B /* QLSmartFolder.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QLSmartFolder.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; };
4A8AF8DA2133B9FF00B0A97B /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = "<group>"; };
4A8AF8DC2133B9FF00B0A97B /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = "<group>"; };
4A8AF8DE2133B9FF00B0A97B /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
4A8AF8E02133B9FF00B0A97B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4A8AF8E62133BB3100B0A97B /* Shared.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shared.h; sourceTree = "<group>"; };
4A8AF8E82133BEF100B0A97B /* template.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = template.html; sourceTree = "<group>"; };
4ABF9B4F2133ED51009DEE78 /* CoreSpotlight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSpotlight.framework; path = System/Library/Frameworks/CoreSpotlight.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
4A8AF8D32133B9FE00B0A97B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4ABF9B502133ED51009DEE78 /* CoreSpotlight.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -42,7 +41,6 @@
children = (
4A8AF8D92133B9FE00B0A97B /* QLSmartFolder */,
4A8AF8D82133B9FE00B0A97B /* Products */,
4ABF9B4E2133ED50009DEE78 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -70,19 +68,12 @@
4A8AF8E72133BED800B0A97B /* Resources */ = {
isa = PBXGroup;
children = (
4A2A8239213565AE0057AE57 /* smartFolderIcon.png */,
4A8AF8E82133BEF100B0A97B /* template.html */,
);
path = Resources;
sourceTree = "<group>";
};
4ABF9B4E2133ED50009DEE78 /* Frameworks */ = {
isa = PBXGroup;
children = (
4ABF9B4F2133ED51009DEE78 /* CoreSpotlight.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand Down Expand Up @@ -150,6 +141,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4A2A823A213565AE0057AE57 /* smartFolderIcon.png in Resources */,
4A8AF8E92133BEF100B0A97B /* template.html in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Binary file not shown.
88 changes: 48 additions & 40 deletions QLSmartFolder/GeneratePreviewForURL.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,70 +16,80 @@
OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
{
@autoreleasepool {
NSURL *imgURL = [[NSBundle bundleWithIdentifier:kPluginBundleId] URLForResource:@"smartFolderIcon" withExtension:@"png"];

NSURL *htmlURL = [[NSBundle bundleWithIdentifier:kPluginBundleId] URLForResource:@"template" withExtension:@"html"];
NSMutableString *previewHtml = [NSMutableString stringWithContentsOfURL:htmlURL encoding:NSUTF8StringEncoding error:NULL];

NSURL *URL = (__bridge NSURL *)url;
NSString *name = [[[URL absoluteString] lastPathComponent] stringByRemovingPercentEncoding];

NSDictionary *urlAttributes = [URL resourceValuesForKeys:@[NSURLContentAccessDateKey] error:NULL];
NSDate *lastAccessDate = urlAttributes[NSURLContentAccessDateKey];

NSString *error;
NSPropertyListFormat format;
NSDictionary *contentDict = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfURL:URL] options:0 format:&format error:&error];

NSString *queryString = [((NSString *)contentDict[@"RawQueryDict"][@"RawQuery"]) stringByReplacingOccurrencesOfString:@"kMDItem" withString:@""];
NSString *rawQueryString = contentDict[@"RawQueryDict"][@"RawQuery"];

NSMutableString *queryString = [[NSMutableString alloc] init];

NSArray *criteriaSlices = contentDict[@"SearchCriteria"][@"FXCriteriaSlices"];
NSMutableArray *attributes = [[NSMutableArray alloc] init];
NSMutableDictionary *criteriaTable = [[NSMutableDictionary alloc] init];
for (NSDictionary *criteriaSlice in criteriaSlices) {
NSArray *criteriaArray = (criteriaSlice[@"criteria"]);
NSString *originalCriteria = [((NSString *)criteriaArray[0]) stringByReplacingOccurrencesOfString:@"kMDItem" withString:@""];
NSString *newCriteria = [[[originalCriteria substringToIndex:1] lowercaseString] stringByAppendingString:[originalCriteria substringFromIndex:1]];
[attributes addObject:newCriteria];

criteriaTable[originalCriteria] = newCriteria;
if ([queryString length] > 0) {
[queryString appendString:@"&nbsp;&amp;&nbsp;"];
}
NSArray *displayValuesArray = (criteriaSlice[@"displayValues"]);
NSString *displayValues = [displayValuesArray componentsJoinedByString:@" "];
[queryString appendString:displayValues];
}

for (NSString *key in criteriaTable) {
queryString = [queryString stringByReplacingOccurrencesOfString:key withString:criteriaTable[key]];
NSDictionary *scopesReplacement = @{ @"kMDQueryScopeHome": @"Home",
@"kMDQueryScopeComputer": @"Computer",
@"kMDQueryScopeNetwork": @"Network",
@"kMDQueryScopeAllIndexed": @"All Indexed",
@"kMDQueryScopeComputerIndexed": @"Computer Indexed",
@"kMDQueryScopeNetworkIndexed": @"Network Indexed"
};

NSMutableArray *scopes = contentDict[@"RawQueryDict"][@"SearchScopes"];
for (NSInteger i = 0; i < [scopes count]; i++) {
for (NSString *key in scopesReplacement) {
if ([scopes[i] isEqualToString:key]) {
scopes[i] = scopesReplacement[key];
}
}
}

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];

NSMutableDictionary *previewReplacement = [[NSMutableDictionary alloc] init];
previewReplacement[@"__Name_Value__"] = name;
previewReplacement[@"__Last_Access_Date__"] = @"Last Access Date";
previewReplacement[@"__Last_Access_Date_Value__"] = [formatter stringFromDate:lastAccessDate];
previewReplacement[@"__Scopes__"] = @"Scopes";
previewReplacement[@"__Scopes_Value__"] = [(NSArray *)(contentDict[@"RawQueryDict"][@"SearchScopes"]) componentsJoinedByString:@", "];
previewReplacement[@"__Scopes_Value__"] = [scopes componentsJoinedByString:@", "];
previewReplacement[@"__Query__"] = @"Query";
previewReplacement[@"__Query_Value__"] = queryString;
previewReplacement[@"__Raw_Query__"] = @"Raw&nbsp;Query";
previewReplacement[@"__Raw_Query_Value__"] = rawQueryString;

__block NSMutableArray *foundItems = [[NSMutableArray alloc] init];
__block NSString *errorString = @"";
__block BOOL searchFinished = NO;

CSSearchQuery *query = [[CSSearchQuery alloc] initWithQueryString:queryString attributes:attributes];
query.foundItemsHandler = ^(NSArray<CSSearchableItem *> * _Nonnull items) {
[foundItems addObjectsFromArray:items];
};
query.completionHandler = ^(NSError * _Nullable error) {
errorString = [error description] ?: @"";
searchFinished = YES;
};
[query start];

NSInteger i = 0;
while ([query foundItemCount] < 10 && i < 100 && ![query isCancelled] && !searchFinished) {
[NSThread sleepForTimeInterval:0.1f];
i++;
}

[previewHtml appendFormat:@"<table><tr><th>%ld Files</th></tr>", (long)[query foundItemCount]];
for (CSSearchableItem *item in foundItems) {
[previewHtml appendFormat:@"<table><tr><td>%@</td></tr>", [item uniqueIdentifier]];
}
[previewHtml appendString:@"</table>"];
[previewHtml appendString:errorString];

NSData *imgData = [[NSData alloc] initWithContentsOfURL:imgURL];

NSDictionary *properties = @{(__bridge NSString *)kQLPreviewPropertyTextEncodingNameKey : @"UTF-8",
(__bridge NSString *)kQLPreviewPropertyMIMETypeKey : @"text/html" };
(__bridge NSString *)kQLPreviewPropertyMIMETypeKey : @"text/html",
(__bridge NSString *)kQLPreviewPropertyAttachmentsKey : @{
@"icon" : @{
(__bridge NSString*)kQLPreviewPropertyMIMETypeKey : @"image/png",
(__bridge NSString*)kQLPreviewPropertyAttachmentDataKey: imgData,
}
}
};

for (NSString *key in previewReplacement) {
[previewHtml replaceOccurrencesOfString:key
Expand All @@ -88,8 +98,6 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
range:NSMakeRange(0, [previewHtml length])];
}

[query cancel];

QLPreviewRequestSetDataRepresentation(preview, (__bridge CFDataRef)[previewHtml dataUsingEncoding:NSUTF8StringEncoding], kUTTypeHTML, (__bridge CFDictionaryRef)properties);
}

Expand Down
4 changes: 2 additions & 2 deletions QLSmartFolder/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
<key>QLNeedsToBeRunInMainThread</key>
<false/>
<key>QLPreviewHeight</key>
<real>600</real>
<integer>400</integer>
<key>QLPreviewWidth</key>
<real>800</real>
<integer>600</integer>
<key>QLSupportsConcurrentRequests</key>
<false/>
<key>QLThumbnailMinimumSize</key>
Expand Down
Binary file added QLSmartFolder/Resources/smartFolderIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 28 additions & 1 deletion QLSmartFolder/Resources/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,40 @@
color: #333333;
background: #F8F8F8;
}
img {
width: 64px;
height: 64px;
}
table {
border: 1px #666666;
font-size: small;
}
span.lastAccessDate {
font-size: small;
}
td {
font-family: sans-serif;
padding: 1px;
}
td.title {
font-weight: bold;
}
h2 {
font-family: sans-serif;
display: inline;
}
</style>
<h2>__Name_Value__</h2>
<table>
<tr>
<td><img src="cid:icon" alt="Smart Folder Icon" />&nbsp;&nbsp;</td>
<td>
<h2>__Name_Value__</h2>
<br />
<span class="lastAccessDate">__Last_Access_Date__ : __Last_Access_Date_Value__</span>
</td>
</tr>
</table>
<hr />
<table>
<tr>
<td class="title">
Expand All @@ -37,4 +56,12 @@ <h2>__Name_Value__</h2>
__Query_Value__
</td>
</tr>
<tr>
<td class="title">
__Raw_Query__
</td>
<td>
__Raw_Query_Value__
</td>
</tr>
</table>
1 change: 0 additions & 1 deletion QLSmartFolder/Shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@
//

#import <Cocoa/Cocoa.h>
#import <CoreSpotlight/CoreSpotlight.h>

static NSString * const kPluginBundleId = @"jp.nita.QLSmartFolder";

0 comments on commit 88f7be8

Please sign in to comment.