Skip to content

Commit 7a6e8a3

Browse files
authored
Merge pull request #3083 from quicksilver/pjrobertson/finder-sidebar
Fix up sfl file parsing + add preset for finder sidebar items
2 parents 999ba83 + eedebbb commit 7a6e8a3

File tree

5 files changed

+93
-23
lines changed

5 files changed

+93
-23
lines changed

Quicksilver/PlugIns-Main/Finder/Info.plist

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,43 @@
4343
<key>children</key>
4444
<array>
4545
<dict>
46+
<key>icon</key>
47+
<string>FinderIcon</string>
48+
<key>source</key>
49+
<string>QSFileSystemObjectSource</string>
50+
<key>settings</key>
51+
<dict>
52+
<key>parser</key>
53+
<string>QSDirectoryParser</string>
54+
<key>folderTypes</key>
55+
<array>
56+
<string>com.apple.application</string>
57+
</array>
58+
<key>folderDepth</key>
59+
<integer>1</integer>
60+
<key>scanContents</key>
61+
<integer>1</integer>
62+
<key>kind</key>
63+
<string>Folder</string>
64+
<key>path</key>
65+
<string>/System/Library/CoreServices/Finder.app/Contents/Applications/</string>
66+
<key>skipItem</key>
67+
<integer>1</integer>
68+
<key>type</key>
69+
<string></string>
70+
</dict>
4671
<key>ID</key>
4772
<string>QSPresetSidebarItems</string>
73+
<key>name</key>
74+
<string>Finder Sidebar Items</string>
75+
</dict>
76+
<dict>
77+
<key>ID</key>
78+
<string>QSPresetSidebarFavorites</string>
4879
<key>icon</key>
4980
<string>FinderIcon</string>
5081
<key>name</key>
51-
<string>Finder Sidebar Items</string>
82+
<string>Finder Favorites</string>
5283
<key>settings</key>
5384
<dict>
5485
<key>path</key>

Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSSharedFileListSource.m

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,44 @@
1111

1212
@implementation QSSharedFileListSource
1313

14+
/**
15+
* Returns the valid path for an SFL file.
16+
* Tries .sfl3, .sfl2, and .sfl extensions in order.
17+
* @return NSString path, or nil if no valid file exists
18+
*/
19+
- (NSString *)validPathForSfl:(NSString *)sflPath
20+
{
21+
NSString *basePath = [sflPath stringByStandardizingPath];
22+
// Strip any existing .sfl* extension
23+
basePath = [basePath stringByDeletingPathExtension];
24+
25+
// Try extensions in order: .sfl3, .sfl2, .sfl
26+
NSFileManager *manager = [NSFileManager defaultManager];
27+
NSArray *extensions = @[@".sfl3", @".sfl2", @".sfl"];
28+
for (NSString *ext in extensions) {
29+
NSString *testPath = [basePath stringByAppendingString:ext];
30+
BOOL isDir = NO;
31+
if ([manager fileExistsAtPath:testPath isDirectory:&isDir] && !isDir) {
32+
return testPath;
33+
}
34+
}
35+
return nil;
36+
}
37+
1438
- (BOOL)indexIsValidFromDate:(NSDate *)indexDate forEntry:(NSDictionary *)theEntry
1539
{
1640
NSDictionary *settings = [theEntry objectForKey:kItemSettings];
1741
NSString *sflPath = [settings objectForKey:kItemPath];
1842
if (!sflPath) {
1943
return YES;
2044
}
21-
NSString *path = [sflPath stringByStandardizingPath];
22-
if ([NSApplication isHighSierra]) {
23-
path = [path stringByReplacingOccurrencesOfString:@".sfl" withString:@".sfl2"];
24-
}
25-
NSFileManager *manager = [NSFileManager defaultManager];
26-
BOOL isDir = NO;
27-
if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir] || isDir) {
45+
46+
NSString *path = [self validPathForSfl:sflPath];
47+
if (!path) {
2848
return YES;
2949
}
50+
51+
NSFileManager *manager = [NSFileManager defaultManager];
3052
NSDate *modDate = [[manager attributesOfItemAtPath:path error:NULL] fileModificationDate];
3153
if ([modDate compare:indexDate] == NSOrderedDescending) {
3254
return NO;
@@ -39,29 +61,45 @@ - (NSArray *)objectsForEntry:(NSDictionary *)theEntry
3961
NSDictionary *settings = [theEntry objectForKey:kItemSettings];
4062
NSMutableArray *sflItemArray = [NSMutableArray arrayWithCapacity:0];
4163
NSString *sflPath = [settings objectForKey:kItemPath];
42-
NSString *path = [sflPath stringByStandardizingPath];
43-
if ([NSApplication isHighSierra]) {
44-
path = [path stringByReplacingOccurrencesOfString:@".sfl" withString:@".sfl2"];
45-
}
46-
BOOL isDir = NO;
47-
if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir] || isDir) {
64+
65+
NSString *path = [self validPathForSfl:sflPath];
66+
if (!path) {
4867
return nil;
4968
}
69+
70+
NSString *extension = [path pathExtension];
71+
5072
NSDictionary *sflData = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
5173
NSString *kItems = @"items";
5274
if (![[sflData allKeys] containsObject:kItems]) {
5375
return nil;
5476
}
55-
if ([NSApplication isHighSierra]) {
77+
78+
// Parse based on file extension: sfl2 and sfl3 use bookmark data, sfl uses SFLListItem
79+
if ([extension isEqualToString:@"sfl2"] || [extension isEqualToString:@"sfl3"]) {
5680
return [sflData[kItems] arrayByEnumeratingArrayUsingBlock:^id(NSDictionary *item) {
57-
NSData *bookmarkData = item[@"Bookmark"];
81+
// Bookmark data might be direct NSData or wrapped in a dictionary with NS.data key
82+
id bookmarkValue = item[@"Bookmark"];
83+
NSData *bookmarkData = nil;
84+
85+
if ([bookmarkValue isKindOfClass:[NSData class]]) {
86+
bookmarkData = bookmarkValue;
87+
} else if ([bookmarkValue isKindOfClass:[NSDictionary class]]) {
88+
// Try NS.data key (common in sfl3)
89+
bookmarkData = bookmarkValue[@"NS.data"];
90+
}
91+
92+
if (!bookmarkData) {
93+
return nil;
94+
}
95+
5896
NSURL *url = [NSURL URLByResolvingBookmarkData:bookmarkData options:NSURLBookmarkResolutionWithoutUI|NSURLBookmarkResolutionWithoutMounting relativeToURL:nil bookmarkDataIsStale:nil error:nil];
5997
if ([url isFileURL]) {
6098
return [QSObject fileObjectWithFileURL:url];
6199
}
62100
return [QSObject URLObjectWithURL:[url absoluteString] title:item[@"Name"]];
63101
}];
64-
} else {
102+
} else if ([extension isEqualToString:@"sfl"]) {
65103
for (SFLListItem *item in sflData[kItems]) {
66104
// item's class is SFLListItem
67105
if ([item URL]) {

Quicksilver/PlugIns-Main/QSCorePlugIn/QSCorePlugIn-Info.plist

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,6 @@
652652
<key>feature</key>
653653
<integer>1</integer>
654654
</dict>
655-
656655
</array>
657656
<key>catalogPath</key>
658657
<string>/</string>
@@ -1139,8 +1138,8 @@
11391138
</array>
11401139
<key>icon</key>
11411140
<string>QSDirectObjectIconProxy</string>
1142-
<key>runInMainThread</key>
1143-
<true/>
1141+
<key>runInMainThread</key>
1142+
<true/>
11441143
</dict>
11451144
<key>QSObjectShowChildMenu</key>
11461145
<dict>

Quicksilver/PlugIns-Main/QSCorePlugIn/Resources/en.lproj/QSCatalogPreset.name.strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@
212212
<string>Shelf &amp; Clipboard</string>
213213
<key>QSPresetSidebarItems</key>
214214
<string>Finder Sidebar</string>
215+
<key>QSPresetSidebarFavorites</key>
216+
<string>Finder Favorites</string>
215217
<key>QSPresetSogudiShortcuts</key>
216218
<string>Sogudi Shortcuts</string>
217219
<key>QSPresetSpeakableItems</key>

Quicksilver/Quicksilver.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@
12331233
4DFE7DA10E081A30000B9AA3 /* README.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = README.rtf; sourceTree = "<group>"; };
12341234
4DFE7DAD0E081BFD000B9AA3 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = /System/Library/Frameworks/QuickLook.framework; sourceTree = "<absolute>"; };
12351235
6008C51E2AAF433900512CB2 /* QSPathsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QSPathsTests.m; sourceTree = "<group>"; };
1236-
600950BC2ABB76AF00F67DEB /* QSCorePlugIn-Info-Testing.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QSCorePlugIn-Info-Testing.plist"; sourceTree = "<group>"; };
1236+
600950BC2ABB76AF00F67DEB /* QSCorePlugIn-Info-Testing.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = "QSCorePlugIn-Info-Testing.plist"; sourceTree = "<group>"; };
12371237
604EAB042CDE5B1E005B3451 /* QSSwiftObj.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QSSwiftObj.swift; sourceTree = "<group>"; };
12381238
60FCBED02844C9770091AB6B /* OSAKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OSAKit.framework; path = System/Library/Frameworks/OSAKit.framework; sourceTree = SDKROOT; };
12391239
6535A8DE1086EF23009D5C90 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -2086,7 +2086,7 @@
20862086
D46D3C7916B33D0B00387EA9 /* countBadge4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "countBadge4@2x.png"; sourceTree = "<group>"; };
20872087
D46D3C7A16B33D0B00387EA9 /* countBadge5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "countBadge5@2x.png"; sourceTree = "<group>"; };
20882088
D48F231B1C99CCC4006504A8 /* QSSharedFileListSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QSSharedFileListSource.h; sourceTree = "<group>"; };
2089-
D48F231C1C99CCC4006504A8 /* QSSharedFileListSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QSSharedFileListSource.m; sourceTree = "<group>"; };
2089+
D48F231C1C99CCC4006504A8 /* QSSharedFileListSource.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = QSSharedFileListSource.m; sourceTree = "<group>"; usesTabs = 1; };
20902090
D48FC4FB1FBE89B4009600EB /* QSWebSource.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QSWebSource.xib; sourceTree = "<group>"; };
20912091
D49399091350078E00B908C6 /* QSDownloads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QSDownloads.h; sourceTree = "<group>"; usesTabs = 1; };
20922092
D493990A1350078E00B908C6 /* QSDownloads.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QSDownloads.m; sourceTree = "<group>"; usesTabs = 1; };
@@ -2186,7 +2186,7 @@
21862186
E180011607B2B48900010DB0 /* QSTextSource.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = QSTextSource.m; sourceTree = "<group>"; };
21872187
E180011707B2B48900010DB0 /* QSWebSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = QSWebSource.h; sourceTree = "<group>"; };
21882188
E180011807B2B48900010DB0 /* QSWebSource.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = QSWebSource.m; sourceTree = "<group>"; };
2189-
E180011907B2B48900010DB0 /* QSCorePlugIn-Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.info; fileEncoding = 30; path = "QSCorePlugIn-Info.plist"; sourceTree = "<group>"; };
2189+
E180011907B2B48900010DB0 /* QSCorePlugIn-Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.info; fileEncoding = 4; path = "QSCorePlugIn-Info.plist"; sourceTree = "<group>"; };
21902190
E18001C507B2BBB800010DB0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; usesTabs = 1; };
21912191
E18001C807B2BBB800010DB0 /* QSApp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = QSApp.h; sourceTree = "<group>"; usesTabs = 1; };
21922192
E18001C907B2BBB800010DB0 /* QSApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QSApp.m; sourceTree = "<group>"; usesTabs = 1; };

0 commit comments

Comments
 (0)