From 998f031399ff089f2cc5fedd5d851abc1940a345 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:03:31 +0200 Subject: [PATCH 01/51] Hide our ivar in a class extension. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 15 +-------------- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index fd9f2495d..e60b65a98 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -8,20 +8,7 @@ #import -@interface QSCatalogEntry : NSObject { - __block NSDate *indexDate; - BOOL isPreset; - - NSString *name; - - id parent; - NSMutableArray *children; - dispatch_queue_t scanQueue; - NSMutableDictionary *info; - NSArray *contents; - NSBundle *bundle; - BOOL isScanning; -} +@interface QSCatalogEntry : NSObject @property (assign, atomic) BOOL isScanning; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 94a7e6028..46a1c3c74 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -25,8 +25,21 @@ - (void)disableEntry:(QSCatalogEntry *)entry; #define kUseNSArchiveForIndexes NO; -/*NSDictionary *entriesByID; -NSDictionary *enabledPresetDictionary;*/ +@interface QSCatalogEntry () { + __block NSDate *indexDate; + BOOL isPreset; + + NSString *name; + + id parent; + NSMutableArray *children; + dispatch_queue_t scanQueue; + NSMutableDictionary *info; + NSArray *contents; + NSBundle *bundle; +} + +@end @implementation QSCatalogEntry From e816dfad5d6df3154ceb7330d189a25eaeb967fd Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:03:50 +0200 Subject: [PATCH 02/51] No need for that in the public API. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index e60b65a98..8d29eebe4 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -19,7 +19,6 @@ - (NSDictionary *)dictionaryRepresentation; - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; -- (void)dealloc; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; - (BOOL)isSuppressed; From 6bb358a9fe5445dfe942738e587ac2eb04b29fca Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:04:54 +0200 Subject: [PATCH 03/51] Use a property for `isScanning`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 4 +--- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 10 ++++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 8d29eebe4..30b7e74c3 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -10,7 +10,7 @@ @interface QSCatalogEntry : NSObject -@property (assign, atomic) BOOL isScanning; +@property (readonly, getter=isScanning) BOOL scanning; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -63,8 +63,6 @@ - (NSDate *)indexDate; - (void)setIndexDate:(NSDate *)anIndexDate; -- (BOOL)isScanning; -- (void)setIsScanning:(BOOL)flag; //- (NSString *)countString; - (NSUInteger) count; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 46a1c3c74..3955f498f 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -39,11 +39,13 @@ @interface QSCatalogEntry () { NSBundle *bundle; } +@property (getter=isScanning) BOOL scanning; + @end @implementation QSCatalogEntry -@synthesize isScanning, contents = contents; +@synthesize contents = contents; + (BOOL)accessInstanceVariablesDirectly {return YES;} @@ -539,7 +541,7 @@ - (BOOL)canBeIndexed { } - (NSArray *)scanAndCache { - if (isScanning) { + if (self.isScanning) { #ifdef DEBUG if (VERBOSE) NSLog(@"%@ is already being scanned", [self name]); #endif @@ -548,7 +550,7 @@ - (NSArray *)scanAndCache { __block NSArray *itemContents = nil; // Use a serial queue to do the grunt of the scan work. Ensures that no more than one thread can scan at any one time. QSGCDQueueSync(scanQueue, ^{ - [self setIsScanning:YES]; + self.scanning = YES; [self willChangeValueForKey:@"self"]; NSString *ID = [self identifier]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; @@ -565,7 +567,7 @@ - (NSArray *)scanAndCache { } [self didChangeValueForKey:@"self"]; [nc postNotificationName:QSCatalogEntryIndexed object:self]; - [self setIsScanning:NO]; + self.scanning = NO; }); return itemContents; } From 61b770739ce1a3e5979a2b0e15af86f8a229bb47 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:05:08 +0200 Subject: [PATCH 04/51] Cruft cleanup. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 30b7e74c3..ac30990b3 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -26,10 +26,10 @@ - (BOOL)isSeparator; - (BOOL)isGroup; - (BOOL)isEditable; -- (NSInteger) state; -- (NSInteger) hasEnabledChildren; - (BOOL)isEnabled; - (void)setEnabled:(BOOL)enabled; +- (NSInteger)state; +- (NSInteger)hasEnabledChildren; - (void)setDeepEnabled:(BOOL)enabled; - (void)pruneInvalidChildren; - (NSArray *)leafIDs; @@ -63,8 +63,7 @@ - (NSDate *)indexDate; - (void)setIndexDate:(NSDate *)anIndexDate; -//- (NSString *)countString; -- (NSUInteger) count; +- (NSUInteger)count; - (NSIndexPath *)catalogSetIndexPath; @end From e0f0e0f527e7af22133681b38334dadef9297a53 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:09:59 +0200 Subject: [PATCH 05/51] Property-fy `isSuppressed`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 +- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index ac30990b3..dbec57e34 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -11,6 +11,7 @@ @interface QSCatalogEntry : NSObject @property (readonly, getter=isScanning) BOOL scanning; +@property (readonly, getter=isSuppressed) BOOL suppressed; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -21,7 +22,6 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; -- (BOOL)isSuppressed; - (BOOL)isPreset; - (BOOL)isSeparator; - (BOOL)isGroup; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 3955f498f..79b76edf9 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -254,9 +254,9 @@ - (void)setDeepEnabled:(BOOL)enabled { - (void)pruneInvalidChildren { NSMutableArray *children2 = [children copy]; - for(QSCatalogEntry * child in children2) { + for (QSCatalogEntry *child in children2) { if ([child isSeparator]) break; //Stop when at end of presets - if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && [child isSuppressed]) { + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && child.isSuppressed) { #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", [child identifier]); From 9296aa9cdcd1dcffc81798e7797c1fcef25893f4 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:15:24 +0200 Subject: [PATCH 06/51] Property-fy `isPreset`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 2 +- .../Code-QuickStepCore/QSCatalogEntry.m | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index dbec57e34..8fa700706 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -12,6 +12,7 @@ @property (readonly, getter=isScanning) BOOL scanning; @property (readonly, getter=isSuppressed) BOOL suppressed; +@property (readonly, getter=isPreset) BOOL preset; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -22,7 +23,6 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; -- (BOOL)isPreset; - (BOOL)isSeparator; - (BOOL)isGroup; - (BOOL)isEditable; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 79b76edf9..c6286538a 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -27,7 +27,6 @@ - (void)disableEntry:(QSCatalogEntry *)entry; @interface QSCatalogEntry () { __block NSDate *indexDate; - BOOL isPreset; NSString *name; @@ -167,14 +166,20 @@ - (NSDate *)lastScanDate { } - (BOOL)deletable { - if ([self isPreset]) - return NO; + if (self.isPreset) return NO; + return ![[info objectForKey:@"permanent"] boolValue]; } - (BOOL)isEditable { id source = [self source]; - return ([source respondsToSelector:@selector(usesGlobalSettings)] && [source performSelector:@selector(usesGlobalSettings)]) ? YES : ![self isPreset]; + + if ([source respondsToSelector:@selector(usesGlobalSettings)] + && [source performSelector:@selector(usesGlobalSettings)]) { + return YES; + } + + return !self.isPreset; } - (NSString *)type { @@ -218,7 +223,7 @@ - (BOOL)shouldIndex { } - (BOOL)isEnabled { - if ([self isPreset]) { + if (self.isPreset) { NSNumber *value; if (value = [[QSLibrarian sharedInstance] presetIsEnabled:self]) return [value boolValue]; @@ -233,7 +238,7 @@ - (BOOL)isEnabled { - (void)setEnabled:(BOOL)enabled { NSString *theID = [info objectForKey:kItemID]; - if ([theID hasPrefix:@"QSPreset"]) + if (self.isPreset) [[QSLibrarian sharedInstance] setPreset:self isEnabled:enabled]; else [info setObject:[NSNumber numberWithBool:enabled] forKey:kItemEnabled]; @@ -648,7 +653,7 @@ - (NSArray *)enabledContents - (QSCatalogEntry *)uniqueCopy { NSMutableDictionary *newDictionary = [info mutableCopy]; - if ([self isPreset]) { + if (self.isPreset) { [newDictionary setObject:[NSNumber numberWithBool:[self isEnabled]] forKey:kItemEnabled]; [newDictionary setObject:[self name] forKey:kItemName]; } From 587e020d79dc9cb4b30d53d33e695fad0cd86a3e Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:17:03 +0200 Subject: [PATCH 07/51] Property-fy `isSeparator`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 +- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 8fa700706..f0062bc23 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -13,6 +13,7 @@ @property (readonly, getter=isScanning) BOOL scanning; @property (readonly, getter=isSuppressed) BOOL suppressed; @property (readonly, getter=isPreset) BOOL preset; +@property (readonly, getter=isSeparator) BOOL separator; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -23,7 +24,6 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; -- (BOOL)isSeparator; - (BOOL)isGroup; - (BOOL)isEditable; - (BOOL)isEnabled; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index c6286538a..bef5c6341 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -260,7 +260,7 @@ - (void)setDeepEnabled:(BOOL)enabled { - (void)pruneInvalidChildren { NSMutableArray *children2 = [children copy]; for (QSCatalogEntry *child in children2) { - if ([child isSeparator]) break; //Stop when at end of presets + if (child.isSeparator) break; //Stop when at end of presets if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && child.isSuppressed) { #ifdef DEBUG @@ -382,8 +382,7 @@ - (NSComparisonResult) compare:(QSCatalogEntry *)other { - (NSString *)name { NSString *ID = [self identifier]; - if ([ID isEqualToString:@"QSSeparator"]) - return @""; + if (self.isSeparator) return @""; if (!name) name = [info objectForKey:kItemName]; if (!name) { @@ -579,7 +578,7 @@ - (NSArray *)scanAndCache { } - (void)scanForced:(BOOL)force { - if ([self isSeparator] || ![self isEnabled]) { + if (self.isSeparator || ![self isEnabled]) { return; } if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { From 822b1de86b002b426569488b42003c5e4b5e5404 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:20:01 +0200 Subject: [PATCH 08/51] Property-fy `isGroup`. Also remove the direct accesses to the `info` ivar. --- .../Code-QuickStepCore/QSCatalogEntry.h | 2 +- .../Code-QuickStepCore/QSCatalogEntry.m | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index f0062bc23..35865b3ad 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -14,6 +14,7 @@ @property (readonly, getter=isSuppressed) BOOL suppressed; @property (readonly, getter=isPreset) BOOL preset; @property (readonly, getter=isSeparator) BOOL separator; +@property (readonly, getter=isGroup) BOOL group; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -24,7 +25,6 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; -- (BOOL)isGroup; - (BOOL)isEditable; - (BOOL)isEnabled; - (void)setEnabled:(BOOL)enabled; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index bef5c6341..9569b89a4 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -196,11 +196,12 @@ - (BOOL)isCatalog { return self == [[QSLibrarian sharedInstance] catalog]; } - (BOOL)isPreset { return [[self identifier] hasPrefix:@"QSPreset"]; } - (BOOL)isSeparator { return [[self identifier] hasPrefix:@"QSSeparator"]; } - (BOOL)isGroup { return [[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]; } -- (BOOL)isLeaf { return ![self isGroup]; } +- (BOOL)isLeaf { return !self.isGroup; } + - (NSInteger)state { BOOL enabled = [self isEnabled]; if (!enabled) return 0; - if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + if (self.isGroup) { for(QSCatalogEntry * child in [self deepChildrenWithGroups:NO leaves:YES disabled:YES]) { if (![child isEnabled]) return -1*enabled; } @@ -209,7 +210,7 @@ - (NSInteger)state { } - (NSInteger)hasEnabledChildren { - if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + if (self.isGroup) { BOOL hasEnabledChildren = NO; for (id loopItem in children) hasEnabledChildren |= [loopItem isEnabled]; @@ -250,7 +251,7 @@ - (void)setEnabled:(BOOL)enabled { - (void)setDeepEnabled:(BOOL)enabled { [self setEnabled:enabled]; - if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + if (self.isGroup) { NSArray *deepChildren = [self deepChildrenWithGroups:YES leaves:YES disabled:YES]; for(QSCatalogEntry * child in deepChildren) [child setEnabled:enabled]; @@ -268,7 +269,7 @@ - (void)pruneInvalidChildren { #endif [children removeObject:child]; - } else if ([child isGroup]) { + } else if (child.isGroup) { [child pruneInvalidChildren]; if (![(NSArray *)[child children] count]) // Remove empty groups [children removeObject:child]; @@ -279,7 +280,7 @@ - (void)pruneInvalidChildren { - (NSArray *)leafIDs { if (![self isEnabled]) { return nil; - } else if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + } else if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; for(QSCatalogEntry * child in children) { [childObjects addObjectsFromArray:[child leafIDs]]; @@ -301,7 +302,7 @@ - (NSMutableDictionary *)info { - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled { if (!(disabled || [self isEnabled])) return nil; - if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; if (groups) [childObjects addObject:self]; @@ -581,7 +582,7 @@ - (void)scanForced:(BOOL)force { if (self.isSeparator || ![self isEnabled]) { return; } - if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + if (self.isGroup) { @autoreleasepool { for(QSCatalogEntry * child in children) { [child scanForced:force]; @@ -626,7 +627,7 @@ - (NSArray *)contentsScanIfNeeded:(BOOL)canScan { if (![self isEnabled]) { return nil; } - if ([[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]) { + if (self.isGroup) { NSMutableSet *childObjects = [NSMutableSet setWithCapacity:1]; for(QSCatalogEntry * child in children) { From 0408a1eecdbd8e013bcad2567baa44bd37c3e901 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:21:28 +0200 Subject: [PATCH 09/51] Property-fy `isEditable`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 35865b3ad..05a7b3f60 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -15,6 +15,7 @@ @property (readonly, getter=isPreset) BOOL preset; @property (readonly, getter=isSeparator) BOOL separator; @property (readonly, getter=isGroup) BOOL group; +@property (readonly, getter=isEditable) BOOL editable; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -25,7 +26,6 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; -- (BOOL)isEditable; - (BOOL)isEnabled; - (void)setEnabled:(BOOL)enabled; - (NSInteger)state; From cc4b0dd052ea2ae1797471ba4adac8ca72cf11dd Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:31:13 +0200 Subject: [PATCH 10/51] Property-fy `isEnabled`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 3 +- .../Code-QuickStepCore/QSCatalogEntry.m | 96 ++++++++++--------- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 05a7b3f60..f4831f95c 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -17,6 +17,7 @@ @property (readonly, getter=isGroup) BOOL group; @property (readonly, getter=isEditable) BOOL editable; +@property (getter=isEnabled) BOOL enabled; @property (strong, atomic, getter=_contents) NSArray *contents; @@ -26,8 +27,6 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; - (QSCatalogEntry *)childWithID:(NSString *)theID; - (QSCatalogEntry *)childWithPath:(NSString *)path; -- (BOOL)isEnabled; -- (void)setEnabled:(BOOL)enabled; - (NSInteger)state; - (NSInteger)hasEnabledChildren; - (void)setDeepEnabled:(BOOL)enabled; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 9569b89a4..565f4a5ae 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -165,6 +165,7 @@ - (NSDate *)lastScanDate { return [[[NSFileManager defaultManager] attributesOfItemAtPath:[self indexLocation] error:nil] objectForKey:NSFileModificationDate]; } +#warning should rename... - (BOOL)deletable { if (self.isPreset) return NO; @@ -199,11 +200,11 @@ - (BOOL)isGroup { return [[info objectForKey:kItemSource] isEqualToString:@"QSGr - (BOOL)isLeaf { return !self.isGroup; } - (NSInteger)state { - BOOL enabled = [self isEnabled]; + BOOL enabled = self.isEnabled; if (!enabled) return 0; if (self.isGroup) { - for(QSCatalogEntry * child in [self deepChildrenWithGroups:NO leaves:YES disabled:YES]) { - if (![child isEnabled]) return -1*enabled; + for(QSCatalogEntry *child in [self deepChildrenWithGroups:NO leaves:YES disabled:YES]) { + if (!child.isEnabled) return -1*enabled; } } return enabled; @@ -212,49 +213,49 @@ - (NSInteger)state { - (NSInteger)hasEnabledChildren { if (self.isGroup) { BOOL hasEnabledChildren = NO; - for (id loopItem in children) - hasEnabledChildren |= [loopItem isEnabled]; + for (QSCatalogEntry *child in children) + hasEnabledChildren |= child.isEnabled; return hasEnabledChildren; } else return YES; } - (BOOL)shouldIndex { - return [self isEnabled]; + return self.isEnabled; } - (BOOL)isEnabled { - if (self.isPreset) { - NSNumber *value; - if (value = [[QSLibrarian sharedInstance] presetIsEnabled:self]) - return [value boolValue]; - else if (value = [info objectForKey:kItemEnabled]) - return [value boolValue]; - // ***warning * this is just a little silly... - return YES; - } else { + if (!self.isPreset) return [[info objectForKey:kItemEnabled] boolValue]; - } + + NSNumber *value; + if (value = [[QSLibrarian sharedInstance] presetIsEnabled:self]) + return [value boolValue]; + else if (value = [info objectForKey:kItemEnabled]) + return [value boolValue]; + +#warning this is just a little silly... + return YES; } - (void)setEnabled:(BOOL)enabled { - NSString *theID = [info objectForKey:kItemID]; if (self.isPreset) [[QSLibrarian sharedInstance] setPreset:self isEnabled:enabled]; else - [info setObject:[NSNumber numberWithBool:enabled] forKey:kItemEnabled]; + [info setObject:@(enabled) forKey:kItemEnabled]; if (enabled && ![[self contents] count]) { [self scanForced:YES]; } + [QSLib writeCatalog:self]; } - (void)setDeepEnabled:(BOOL)enabled { - [self setEnabled:enabled]; + self.enabled = YES; if (self.isGroup) { NSArray *deepChildren = [self deepChildrenWithGroups:YES leaves:YES disabled:YES]; - for(QSCatalogEntry * child in deepChildren) - [child setEnabled:enabled]; + for(QSCatalogEntry *child in deepChildren) + child.enabled = enabled; } } @@ -278,17 +279,17 @@ - (void)pruneInvalidChildren { } - (NSArray *)leafIDs { - if (![self isEnabled]) { - return nil; - } else if (self.isGroup) { + if (!self.isEnabled) return nil; + + if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; - for(QSCatalogEntry * child in children) { + for(QSCatalogEntry *child in children) { [childObjects addObjectsFromArray:[child leafIDs]]; } return childObjects; - } else { - return [NSArray arrayWithObject:[self identifier]]; - } + } + + return [NSArray arrayWithObject:[self identifier]]; } - (NSArray *)leafEntries { @@ -300,19 +301,23 @@ - (NSMutableDictionary *)info { } - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled { - if (!(disabled || [self isEnabled])) - return nil; + if (!(disabled || self.isEnabled)) return nil; + if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; if (groups) [childObjects addObject:self]; - for(QSCatalogEntry * child in children) { + + for (QSCatalogEntry *child in children) { [childObjects addObjectsFromArray:[child deepChildrenWithGroups:groups leaves:leaves disabled:disabled]]; } return childObjects; - } else if (leaves) { + } + + if (leaves) { return [NSArray arrayWithObject:self]; } + return nil; } @@ -441,7 +446,7 @@ - (NSString *)indexLocation { } - (BOOL)loadIndex { - if ([self isEnabled]) { + if (self.isEnabled) { NSString *path = [self indexLocation]; NSMutableArray *dictionaryArray = nil; @try { @@ -579,9 +584,8 @@ - (NSArray *)scanAndCache { } - (void)scanForced:(BOOL)force { - if (self.isSeparator || ![self isEnabled]) { - return; - } + if (self.isSeparator || !self.isEnabled) return; + if (self.isGroup) { @autoreleasepool { for(QSCatalogEntry * child in children) { @@ -624,23 +628,21 @@ - (void)setChildren:(NSArray *)newChildren { - (NSArray *)contents { return [self contentsScanIfNeeded:NO]; } - (NSArray *)contentsScanIfNeeded:(BOOL)canScan { - if (![self isEnabled]) { - return nil; - } + if (!self.isEnabled) return nil; + if (self.isGroup) { NSMutableSet *childObjects = [NSMutableSet setWithCapacity:1]; - for(QSCatalogEntry * child in children) { - [childObjects addObjectsFromArray:[child contentsScanIfNeeded:(BOOL)canScan]]; + for(QSCatalogEntry *child in children) { + [childObjects addObjectsFromArray:[child contentsScanIfNeeded:canScan]]; } return [childObjects allObjects]; + } - } else { + if (!contents && canScan) + return [self scanAndCache]; - if (!contents && canScan) - return [self scanAndCache]; - return contents; - } + return contents; } - (NSArray *)enabledContents @@ -654,7 +656,7 @@ - (NSArray *)enabledContents - (QSCatalogEntry *)uniqueCopy { NSMutableDictionary *newDictionary = [info mutableCopy]; if (self.isPreset) { - [newDictionary setObject:[NSNumber numberWithBool:[self isEnabled]] forKey:kItemEnabled]; + [newDictionary setObject:@(self.isEnabled) forKey:kItemEnabled]; [newDictionary setObject:[self name] forKey:kItemName]; } [newDictionary setObject:[NSString uniqueString] forKey:kItemID]; From 1bac51b0b39d703b81a1f9fb82faaca67f292d47 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:40:21 +0200 Subject: [PATCH 11/51] Property-fy `name`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 3 +- .../Code-QuickStepCore/QSCatalogEntry.m | 58 ++++++++++--------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index f4831f95c..171e4d4d2 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -19,6 +19,7 @@ @property (getter=isEnabled) BOOL enabled; +@property (copy) NSString *name; @property (strong, atomic, getter=_contents) NSArray *contents; + (QSCatalogEntry *)entryWithDictionary:(NSDictionary *)dict; @@ -36,7 +37,6 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled; - (NSString *)identifier; - (NSArray *)ancestors; -- (NSString *)name; - (NSImage *)icon; - (NSUInteger) deepObjectCount; - (BOOL)loadIndex; @@ -58,7 +58,6 @@ - (NSMutableDictionary *)info; - (QSCatalogEntry *)uniqueCopy; - (NSString *)indexLocation; -- (void)setName:(NSString *)newName; - (NSDate *)indexDate; - (void)setIndexDate:(NSDate *)anIndexDate; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 565f4a5ae..4f31b66cc 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -26,10 +26,9 @@ - (void)disableEntry:(QSCatalogEntry *)entry; #define kUseNSArchiveForIndexes NO; @interface QSCatalogEntry () { + NSString *_name; __block NSDate *indexDate; - NSString *name; - id parent; NSMutableArray *children; dispatch_queue_t scanQueue; @@ -70,7 +69,7 @@ + (QSCatalogEntry *)entryWithDictionary:(NSDictionary *)dict { } - (NSString *)description { - return [NSString stringWithFormat:@"[%@] ", [self name]]; + return [NSString stringWithFormat:@"[%@] ", self.name]; } - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { @@ -379,37 +378,42 @@ - (NSArray *)ancestors { } - (NSComparisonResult) compare:(QSCatalogEntry *)other { - if ([other name] != nil) { - return [[self name] compare:[other name]]; + if (other.name != nil) { + return [self.name compare:other.name]; } // othername is nil, so make the receiver higher in the list return NSOrderedAscending; } - (NSString *)name { - NSString *ID = [self identifier]; - if (self.isSeparator) return @""; - if (!name) - name = [info objectForKey:kItemName]; - if (!name) { - name = [bundle?bundle:[NSBundle mainBundle] safeLocalizedStringForKey:ID value:ID table:@"QSCatalogPreset.name"]; - if (name) [self setValue:name forKey:@"name"]; - } - return name; + @synchronized (self) { + NSString *ID = [self identifier]; + if (self.isSeparator) return @""; + if (!_name) + _name = [info objectForKey:kItemName]; + if (!_name) { + _name = [bundle ? bundle : [NSBundle mainBundle] safeLocalizedStringForKey:ID value:ID table:@"QSCatalogPreset.name"]; + if (_name) + [self setValue:_name forKey:@"name"]; + } + return _name; + } } - (void)setName:(NSString *)newName { - [info setObject:newName forKey:kItemName]; - name = newName; + @synchronized (self) { + [info setObject:newName forKey:kItemName]; + _name = newName; + } } - (id)imageAndText { return self; } -- (void)setImageAndText:(id)object { [self setName:object]; } +- (void)setImageAndText:(id)object { self.name = object; } - (NSImage *)image { return [self icon]; } -- (NSString *)text { return [self name]; } +- (NSString *)text { return self.name; } - (NSImage *)icon { NSImage *image; @@ -453,7 +457,7 @@ - (BOOL)loadIndex { dictionaryArray = [QSObject objectsWithDictionaryArray:[NSArray arrayWithContentsOfFile:path]]; } @catch (NSException *e) { - NSLog(@"Error loading index of %@: %@", [self name] , e); + NSLog(@"Error loading index of %@: %@", self.name , e); } if (!dictionaryArray) @@ -481,7 +485,7 @@ - (void)saveIndex { [writeArray writeToFile:[[path stringByAppendingPathComponent:key] stringByAppendingPathExtension:@"qsindex"] atomically:YES]; } @catch (NSException *exception) { - NSLog(@"Exception whilst saving catalog entry %@\ncontents: %@\nException: %@",[self name],contents,exception); + NSLog(@"Exception whilst saving catalog entry %@\ncontents: %@\nException: %@", self.name, contents, exception); } }); } @@ -538,7 +542,7 @@ - (NSArray *)scannedObjects { itemContents = [source objectsForEntry:info]; } @catch (NSException *exception) { - NSLog(@"An error ocurred while scanning \"%@\": %@", [self name], exception); + NSLog(@"An error ocurred while scanning \"%@\": %@", self.name, exception); [exception printStackTrace]; } } @@ -553,7 +557,7 @@ - (BOOL)canBeIndexed { - (NSArray *)scanAndCache { if (self.isScanning) { #ifdef DEBUG - if (VERBOSE) NSLog(@"%@ is already being scanned", [self name]); + if (VERBOSE) NSLog(@"%@ is already being scanned", self.name); #endif return nil; } else { @@ -594,21 +598,21 @@ - (void)scanForced:(BOOL)force { } return; } - [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Checking: %@", @"Catalog task checking (%@ => source name)"), [self name]]]; + [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Checking: %@", @"Catalog task checking (%@ => source name)"), self.name]]; BOOL valid = [self indexIsValid]; if (valid && !force) { #ifdef DEBUG - if (DEBUG_CATALOG) NSLog(@"\tIndex is valid for source: %@", name); + if (DEBUG_CATALOG) NSLog(@"\tIndex is valid for source: %@", self.name); #endif return; } #ifdef DEBUG if (DEBUG_CATALOG) - NSLog(@"Scanning source: %@%@", [self name] , (force?@" (forced) ":@"")); + NSLog(@"Scanning source: %@%@", self.name , (force?@" (forced) ":@"")); #endif - [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Scanning: %@", @"Catalog task scanning (%@ => source name)"), [self name]]]; + [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Scanning: %@", @"Catalog task scanning (%@ => source name)"), self.name]]; [self scanAndCache]; return; } @@ -657,7 +661,7 @@ - (QSCatalogEntry *)uniqueCopy { NSMutableDictionary *newDictionary = [info mutableCopy]; if (self.isPreset) { [newDictionary setObject:@(self.isEnabled) forKey:kItemEnabled]; - [newDictionary setObject:[self name] forKey:kItemName]; + [newDictionary setObject:self.name forKey:kItemName]; } [newDictionary setObject:[NSString uniqueString] forKey:kItemID]; From c75e1b512bce8fe1fa3e6d9c2434f9a3d8f5fe3f Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 16:41:32 +0200 Subject: [PATCH 12/51] Property-fy `icon`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 +- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 171e4d4d2..b163fa6a2 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -20,6 +20,7 @@ @property (getter=isEnabled) BOOL enabled; @property (copy) NSString *name; +@property (readonly, retain) NSImage *icon; @property (strong, atomic, getter=_contents) NSArray *contents; + (QSCatalogEntry *)entryWithDictionary:(NSDictionary *)dict; @@ -37,7 +38,6 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled; - (NSString *)identifier; - (NSArray *)ancestors; -- (NSImage *)icon; - (NSUInteger) deepObjectCount; - (BOOL)loadIndex; - (void)saveIndex; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 4f31b66cc..97f8f83e9 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -411,7 +411,7 @@ - (id)imageAndText { return self; } - (void)setImageAndText:(id)object { self.name = object; } -- (NSImage *)image { return [self icon]; } +- (NSImage *)image { return self.icon; } - (NSString *)text { return self.name; } From 374e38137bd61a72d80bc9b72a377259ce9992be Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:00:34 +0200 Subject: [PATCH 13/51] Property-fy `contents`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 6 +- .../Code-QuickStepCore/QSCatalogEntry.m | 114 +++++++++++------- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 7 +- .../QSCorePlugIn/Code/QSWebSource.m | 2 +- 4 files changed, 77 insertions(+), 52 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index b163fa6a2..d17709b5c 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -21,7 +21,8 @@ @property (copy) NSString *name; @property (readonly, retain) NSImage *icon; -@property (strong, atomic, getter=_contents) NSArray *contents; + +@property (readonly, retain) NSArray *contents; + (QSCatalogEntry *)entryWithDictionary:(NSDictionary *)dict; - (NSDictionary *)dictionaryRepresentation; @@ -50,10 +51,7 @@ - (void)scanForced:(BOOL)force; - (NSMutableArray *)children; - (NSMutableArray *)getChildren; -- (NSArray *)contents; - (NSArray *)contentsScanIfNeeded:(BOOL)canScan; -- (void)setContents:(NSArray *)newContents; -- (NSArray *)enabledContents; - (NSIndexPath *)catalogIndexPath; - (NSMutableDictionary *)info; - (QSCatalogEntry *)uniqueCopy; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 97f8f83e9..05f07d5e9 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -27,24 +27,24 @@ - (void)disableEntry:(QSCatalogEntry *)entry; @interface QSCatalogEntry () { NSString *_name; + NSArray *_contents; + __block NSDate *indexDate; id parent; NSMutableArray *children; dispatch_queue_t scanQueue; NSMutableDictionary *info; - NSArray *contents; NSBundle *bundle; } @property (getter=isScanning) BOOL scanning; +@property (retain) NSArray *contents; @end @implementation QSCatalogEntry -@synthesize contents = contents; - + (BOOL)accessInstanceVariablesDirectly {return YES;} + (QSCatalogEntry *)entriesWithArray:(NSArray *)array { return nil; } @@ -52,7 +52,7 @@ + (QSCatalogEntry *)entriesWithArray:(NSArray *)array { return nil; } // KVO + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key]; - + if ([key isEqualToString:@"deepObjectCount"]) { NSSet *affectingKeys = [NSSet setWithObjects:@"contents", @"enabled",nil]; keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKeys]; @@ -72,23 +72,38 @@ - (NSString *)description { return [NSString stringWithFormat:@"[%@] ", self.name]; } +- (instancetype)init { + self = [super init]; + if (!self) return nil; + + _name = nil; + indexDate = nil; + parent = nil; + children = nil; + _contents = nil; + info = nil; + + return self; +} + - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { - if (self = [super init]) { - info = [dict mutableCopy]; - children = nil; contents = nil; indexDate = nil; - - NSArray *childDicts = [dict objectForKey:kItemChildren]; - if (childDicts) { - NSMutableArray *newChildren = [NSMutableArray array]; - for(NSDictionary * child in childDicts) { - [newChildren addObject:[QSCatalogEntry entryWithDictionary:child]]; - } - children = newChildren; - } - // create a serial dispatch queue to make scan processes serial for each catalog entry - scanQueue = dispatch_queue_create([[NSString stringWithFormat:@"QSCatalogEntry scanQueue: %@",[dict objectForKey:kItemID]] UTF8String], NULL); - dispatch_queue_set_specific(scanQueue, kQueueCatalogEntry, (__bridge void *)self, NULL); - } + self = [self init]; + if (!self) return nil; + + info = [dict mutableCopy]; + + NSArray *childDicts = [dict objectForKey:kItemChildren]; + if (childDicts) { + NSMutableArray *newChildren = [NSMutableArray array]; + for(NSDictionary *child in childDicts) { + [newChildren addObject:[QSCatalogEntry entryWithDictionary:child]]; + } + children = newChildren; + } + // create a serial dispatch queue to make scan processes serial for each catalog entry + scanQueue = dispatch_queue_create([[NSString stringWithFormat:@"QSCatalogEntry scanQueue: %@",[dict objectForKey:kItemID]] UTF8String], NULL); + dispatch_queue_set_specific(scanQueue, kQueueCatalogEntry, (__bridge void *)self, NULL); + return self; } @@ -263,11 +278,11 @@ - (void)pruneInvalidChildren { for (QSCatalogEntry *child in children2) { if (child.isSeparator) break; //Stop when at end of presets if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && child.isSuppressed) { - + #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", [child identifier]); #endif - + [children removeObject:child]; } else if (child.isGroup) { [child pruneInvalidChildren]; @@ -459,8 +474,8 @@ - (BOOL)loadIndex { @catch (NSException *e) { NSLog(@"Error loading index of %@: %@", self.name , e); } - - if (!dictionaryArray) + + if (!dictionaryArray) return NO; [self setContents:dictionaryArray]; @@ -475,17 +490,17 @@ - (void)saveIndex { #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"saving index for %@", self); #endif - + [self setIndexDate:[NSDate date]]; NSString *key = [self identifier]; NSString *path = [pIndexLocation stringByStandardizingPath]; @try { - NSArray *writeArray = [contents arrayByPerformingSelector:@selector(dictionaryRepresentation)]; + NSArray *writeArray = [self.contents arrayByPerformingSelector:@selector(dictionaryRepresentation)]; [writeArray writeToFile:[[path stringByAppendingPathComponent:key] stringByAppendingPathExtension:@"qsindex"] atomically:YES]; } @catch (NSException *exception) { - NSLog(@"Exception whilst saving catalog entry %@\ncontents: %@\nException: %@", self.name, contents, exception); + NSLog(@"Exception whilst saving catalog entry %@\ncontents: %@\nException: %@", self.name, self.contents, exception); } }); } @@ -571,13 +586,13 @@ - (NSArray *)scanAndCache { [nc postNotificationName:QSCatalogEntryIsIndexing object:self]; itemContents = [self scannedObjects]; if (itemContents && ID) { - [self setContents:itemContents]; + self.contents = itemContents; QSObjectSource *source = [self source]; if (![source respondsToSelector:@selector(entryCanBeIndexed:)] || [source entryCanBeIndexed:[self info]]) { [self saveIndex]; } } else if (ID) { - [self setContents:nil]; + self.contents = nil; } [self didChangeValueForKey:@"self"]; [nc postNotificationName:QSCatalogEntryIndexed object:self]; @@ -606,12 +621,12 @@ - (void)scanForced:(BOOL)force { #endif return; } - + #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"Scanning source: %@%@", self.name , (force?@" (forced) ":@"")); #endif - + [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Scanning: %@", @"Catalog task scanning (%@ => source name)"), self.name]]; [self scanAndCache]; return; @@ -623,30 +638,43 @@ - (NSMutableArray *)getChildren { children = [[NSMutableArray alloc] init]; return children; } + - (void)setChildren:(NSArray *)newChildren { if(newChildren != children){ children = [newChildren mutableCopy]; } } -- (NSArray *)contents { return [self contentsScanIfNeeded:NO]; } +- (NSArray *)contents { + @synchronized (self) { + return [self contentsScanIfNeeded:NO]; + } +} + +- (void)setContents:(NSArray *)newContents { + @synchronized (self) { + _contents = [newContents copy]; + } +} - (NSArray *)contentsScanIfNeeded:(BOOL)canScan { - if (!self.isEnabled) return nil; + @synchronized (self) { + if (!self.isEnabled) return nil; - if (self.isGroup) { - NSMutableSet *childObjects = [NSMutableSet setWithCapacity:1]; + if (self.isGroup) { + NSMutableSet *childObjects = [NSMutableSet setWithCapacity:1]; - for(QSCatalogEntry *child in children) { - [childObjects addObjectsFromArray:[child contentsScanIfNeeded:canScan]]; - } - return [childObjects allObjects]; - } + for (QSCatalogEntry *child in children) { + [childObjects addObjectsFromArray:[child contentsScanIfNeeded:canScan]]; + } + return [childObjects allObjects]; + } - if (!contents && canScan) - return [self scanAndCache]; + if (!_contents && canScan) + return [self scanAndCache]; - return contents; + return _contents; + } } - (NSArray *)enabledContents diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index 982659b09..14cdd067b 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -336,7 +336,7 @@ - (QSCatalogEntry *)entryForID:(NSString *)theID { - (QSCatalogEntry *)firstEntryContainingObject:(QSObject *)object { NSArray *entries = [catalog deepChildrenWithGroups:NO leaves:YES disabled:NO]; NSIndexSet *matchedIndexes = [entries indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(QSCatalogEntry *entry, NSUInteger idx, BOOL *stop) { - return [[entry _contents] containsObject:object]; + return [entry.contents containsObject:object]; }]; if ([matchedIndexes count]) { NSArray *matchedCatalogEntries = [entries objectsAtIndexes:matchedIndexes]; @@ -507,9 +507,8 @@ - (NSDictionary *)typeArraysFromArray:(NSArray *)array { - (void)loadMissingIndexes { NSArray *entries = [catalog leafEntries]; - id entry; - for (entry in entries) { - if (![entry canBeIndexed] || ![entry _contents]) { + for (QSCatalogEntry *entry in entries) { + if (![entry canBeIndexed] || !entry.contents) { //NSLog(@"Missing: %@", [entry name]); [entry scanAndCache]; } else { diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSWebSource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSWebSource.m index 01aef3f99..0da1499d5 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSWebSource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSWebSource.m @@ -26,7 +26,7 @@ - (NSArray *)objectsForEntry:(NSDictionary *)theEntry { NSArray *contents = [(QSHTMLLinkParser *)[QSReg getClassInstance:@"QSHTMLLinkParser"] objectsFromURL:[NSURL URLWithString:location] withSettings:settings]; if (!contents) { // return the original contents of the catalog entry if there was a problem getting data from the internet - return [[QSLib entryForID:[theEntry objectForKey:kItemID]] _contents]; + return [QSLib entryForID:[theEntry objectForKey:kItemID]].contents; } else { return contents; } From 77b40f9d4cd8a603fddb4561d3bc2d45bc3074ef Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:10:25 +0200 Subject: [PATCH 14/51] Property-fy `canBeIndexed`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 +- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 9 ++++++--- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 3 +-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index d17709b5c..a8b5be10b 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -16,6 +16,7 @@ @property (readonly, getter=isSeparator) BOOL separator; @property (readonly, getter=isGroup) BOOL group; @property (readonly, getter=isEditable) BOOL editable; +@property (readonly, getter=canBeIndexed) BOOL indexable; @property (getter=isEnabled) BOOL enabled; @@ -45,7 +46,6 @@ - (BOOL)indexIsValid; - (BOOL)isCatalog; - (id)source; -- (BOOL)canBeIndexed; - (NSArray *)scannedObjects; - (NSArray *)scanAndCache; - (void)scanForced:(BOOL)force; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 05f07d5e9..da889bcc2 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -566,7 +566,11 @@ - (NSArray *)scannedObjects { - (BOOL)canBeIndexed { QSObjectSource *source = [self source]; - return ![source respondsToSelector:@selector(entryCanBeIndexed:)] || [source entryCanBeIndexed:[self info]]; + + if (![source respondsToSelector:@selector(entryCanBeIndexed:)]) + return YES; + + return [source entryCanBeIndexed:[self info]]; } - (NSArray *)scanAndCache { @@ -587,8 +591,7 @@ - (NSArray *)scanAndCache { itemContents = [self scannedObjects]; if (itemContents && ID) { self.contents = itemContents; - QSObjectSource *source = [self source]; - if (![source respondsToSelector:@selector(entryCanBeIndexed:)] || [source entryCanBeIndexed:[self info]]) { + if (self.canBeIndexed) { [self saveIndex]; } } else if (ID) { diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index 14cdd067b..6bd9dcc44 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -508,8 +508,7 @@ - (NSDictionary *)typeArraysFromArray:(NSArray *)array { - (void)loadMissingIndexes { NSArray *entries = [catalog leafEntries]; for (QSCatalogEntry *entry in entries) { - if (![entry canBeIndexed] || !entry.contents) { - //NSLog(@"Missing: %@", [entry name]); + if (!entry.canBeIndexed || !entry.contents) { [entry scanAndCache]; } else { // NSLog(@"monster %d", [[catalogArrays objectForKey:[entry objectForKey:kItemID]]count]); From 52b6ce680df2908794c506c1c6214b99e5f52848 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:14:10 +0200 Subject: [PATCH 15/51] Use `instancetype`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index a8b5be10b..4148a7bc5 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -25,16 +25,20 @@ @property (readonly, retain) NSArray *contents; -+ (QSCatalogEntry *)entryWithDictionary:(NSDictionary *)dict; ++ (instancetype)entryWithDictionary:(NSDictionary *)dict; - (NSDictionary *)dictionaryRepresentation; -- (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict; -- (QSCatalogEntry *)childWithID:(NSString *)theID; -- (QSCatalogEntry *)childWithPath:(NSString *)path; +- (instancetype)initWithDictionary:(NSDictionary *)dict; +- (instancetype)childWithID:(NSString *)theID; +- (instancetype)childWithPath:(NSString *)path; + +- (instancetype)uniqueCopy; + - (NSInteger)state; - (NSInteger)hasEnabledChildren; - (void)setDeepEnabled:(BOOL)enabled; - (void)pruneInvalidChildren; + - (NSArray *)leafIDs; - (NSArray *)leafEntries; - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled; @@ -54,7 +58,6 @@ - (NSArray *)contentsScanIfNeeded:(BOOL)canScan; - (NSIndexPath *)catalogIndexPath; - (NSMutableDictionary *)info; -- (QSCatalogEntry *)uniqueCopy; - (NSString *)indexLocation; - (NSDate *)indexDate; From d0636bf41b27aadfcab66560a2d151553f412aec Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:18:36 +0200 Subject: [PATCH 16/51] Property-fy `identifier`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 2 +- .../Code-QuickStepCore/QSCatalogEntry.m | 33 +++++++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 4148a7bc5..f6ea81253 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -22,6 +22,7 @@ @property (copy) NSString *name; @property (readonly, retain) NSImage *icon; +@property (readonly, copy) NSString *identifier; @property (readonly, retain) NSArray *contents; @@ -42,7 +43,6 @@ - (NSArray *)leafIDs; - (NSArray *)leafEntries; - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled; -- (NSString *)identifier; - (NSArray *)ancestors; - (NSUInteger) deepObjectCount; - (BOOL)loadIndex; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index da889bcc2..f1b367a3a 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -128,9 +128,8 @@ - (NSDictionary *)dictionaryRepresentation { } - (QSCatalogEntry *)childWithID:(NSString *)theID { - QSCatalogEntry *child; - for(child in children) { - if ([[child identifier] isEqualToString:theID]) + for (QSCatalogEntry *child in children) { + if ([child.identifier isEqualToString:theID]) return child; } return nil; @@ -208,8 +207,8 @@ - (NSString *)type { } - (BOOL)isCatalog { return self == [[QSLibrarian sharedInstance] catalog]; } -- (BOOL)isPreset { return [[self identifier] hasPrefix:@"QSPreset"]; } -- (BOOL)isSeparator { return [[self identifier] hasPrefix:@"QSSeparator"]; } +- (BOOL)isPreset { return [self.identifier hasPrefix:@"QSPreset"]; } +- (BOOL)isSeparator { return [self.identifier hasPrefix:@"QSSeparator"]; } - (BOOL)isGroup { return [[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]; } - (BOOL)isLeaf { return !self.isGroup; } @@ -280,7 +279,7 @@ - (void)pruneInvalidChildren { if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && child.isSuppressed) { #ifdef DEBUG - if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", [child identifier]); + if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", child.identifier); #endif [children removeObject:child]; @@ -303,7 +302,7 @@ - (NSArray *)leafIDs { return childObjects; } - return [NSArray arrayWithObject:[self identifier]]; + return [NSArray arrayWithObject:self.identifier]; } - (NSArray *)leafEntries { @@ -402,11 +401,11 @@ - (NSComparisonResult) compare:(QSCatalogEntry *)other { - (NSString *)name { @synchronized (self) { - NSString *ID = [self identifier]; if (self.isSeparator) return @""; if (!_name) _name = [info objectForKey:kItemName]; if (!_name) { + NSString *ID = self.identifier; _name = [bundle ? bundle : [NSBundle mainBundle] safeLocalizedStringForKey:ID value:ID table:@"QSCatalogPreset.name"]; if (_name) [self setValue:_name forKey:@"name"]; @@ -461,15 +460,15 @@ - (NSUInteger)deepObjectCount { } - (NSString *)indexLocation { - return [[[pIndexLocation stringByStandardizingPath] stringByAppendingPathComponent:[self identifier]] stringByAppendingPathExtension:@"qsindex"]; + return [[[pIndexLocation stringByStandardizingPath] stringByAppendingPathComponent:self.identifier] stringByAppendingPathExtension:@"qsindex"]; } - (BOOL)loadIndex { if (self.isEnabled) { - NSString *path = [self indexLocation]; + NSString *indexPath = self.indexLocation; NSMutableArray *dictionaryArray = nil; @try { - dictionaryArray = [QSObject objectsWithDictionaryArray:[NSArray arrayWithContentsOfFile:path]]; + dictionaryArray = [QSObject objectsWithDictionaryArray:[NSMutableArray arrayWithContentsOfFile:indexPath]]; } @catch (NSException *e) { NSLog(@"Error loading index of %@: %@", self.name , e); @@ -492,12 +491,10 @@ - (void)saveIndex { #endif [self setIndexDate:[NSDate date]]; - NSString *key = [self identifier]; - NSString *path = [pIndexLocation stringByStandardizingPath]; @try { NSArray *writeArray = [self.contents arrayByPerformingSelector:@selector(dictionaryRepresentation)]; - [writeArray writeToFile:[[path stringByAppendingPathComponent:key] stringByAppendingPathExtension:@"qsindex"] atomically:YES]; + [writeArray writeToFile:self.indexLocation atomically:YES]; } @catch (NSException *exception) { NSLog(@"Exception whilst saving catalog entry %@\ncontents: %@\nException: %@", self.name, self.contents, exception); @@ -518,8 +515,8 @@ - (BOOL)indexIsValid { __block BOOL isValid = YES; QSGCDQueueSync(scanQueue,^{ NSFileManager *manager = [NSFileManager defaultManager]; - NSString *indexPath = [[[pIndexLocation stringByStandardizingPath] stringByAppendingPathComponent:[self identifier]]stringByAppendingPathExtension:@"qsindex"]; - if (![manager fileExistsAtPath:indexPath isDirectory:nil]) { + NSString *indexPath = self.indexLocation; + if (![manager fileExistsAtPath:self.indexLocation isDirectory:nil]) { isValid = NO; } if (isValid) { @@ -544,7 +541,7 @@ - (id)source { id source = [QSReg sourceNamed:[info objectForKey:kItemSource]]; #ifdef DEBUG if (!source && VERBOSE) - NSLog(@"Source not found: %@ for Entry: %@", [info objectForKey:kItemSource] , [self identifier]); + NSLog(@"Source not found: %@ for Entry: %@", [info objectForKey:kItemSource] , self.identifier); #endif return source; } @@ -585,7 +582,7 @@ - (NSArray *)scanAndCache { QSGCDQueueSync(scanQueue, ^{ self.scanning = YES; [self willChangeValueForKey:@"self"]; - NSString *ID = [self identifier]; + NSString *ID = self.identifier; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc postNotificationName:QSCatalogEntryIsIndexing object:self]; itemContents = [self scannedObjects]; From 15d0ebcd9ec8a2ed9e8f11207791470bec5de2ca Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:40:24 +0200 Subject: [PATCH 17/51] Property-fy `source`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 4 +- .../Code-QuickStepCore/QSCatalogEntry.m | 59 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index f6ea81253..46b21134b 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -8,6 +8,8 @@ #import +@class QSObjectSource; + @interface QSCatalogEntry : NSObject @property (readonly, getter=isScanning) BOOL scanning; @@ -23,6 +25,7 @@ @property (copy) NSString *name; @property (readonly, retain) NSImage *icon; @property (readonly, copy) NSString *identifier; +@property (readonly, retain) QSObjectSource *source; @property (readonly, retain) NSArray *contents; @@ -49,7 +52,6 @@ - (void)saveIndex; - (BOOL)indexIsValid; - (BOOL)isCatalog; -- (id)source; - (NSArray *)scannedObjects; - (NSArray *)scanAndCache; - (void)scanForced:(BOOL)force; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index f1b367a3a..8ab8f9e34 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -28,6 +28,7 @@ - (void)disableEntry:(QSCatalogEntry *)entry; @interface QSCatalogEntry () { NSString *_name; NSArray *_contents; + QSObjectSource *_source; __block NSDate *indexDate; @@ -107,16 +108,15 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { return self; } +#warning doesn't look used, and doesn't *actually* update enabled... - (void)enable { - id theSource = [self source]; - if ([theSource respondsToSelector:@selector(enableEntry:)]) - [theSource enableEntry:self]; + if ([self.source respondsToSelector:@selector(enableEntry:)]) + [self.source enableEntry:self]; } - (void)dealloc { - id theSource = [self source]; - if ([theSource respondsToSelector:@selector(disableEntry:)]) - [theSource disableEntry:self]; + if ([self.source respondsToSelector:@selector(disableEntry:)]) + [self.source disableEntry:self]; dispatch_release(scanQueue); scanQueue = NULL; } @@ -186,10 +186,8 @@ - (BOOL)deletable { } - (BOOL)isEditable { - id source = [self source]; - - if ([source respondsToSelector:@selector(usesGlobalSettings)] - && [source performSelector:@selector(usesGlobalSettings)]) { + if ([self.source respondsToSelector:@selector(usesGlobalSettings)] + && [self.source performSelector:@selector(usesGlobalSettings)]) { return YES; } @@ -197,9 +195,8 @@ - (BOOL)isEditable { } - (NSString *)type { - id source = [self source]; - NSString *theID = NSStringFromClass([source class]); - NSString *title = [[NSBundle bundleForClass:[source class]] safeLocalizedStringForKey:theID value:theID table:@"QSObjectSource.name"]; + NSString *theID = NSStringFromClass([self.source class]); + NSString *title = [[NSBundle bundleForClass:[self.source class]] safeLocalizedStringForKey:theID value:theID table:@"QSObjectSource.name"]; if ([title isEqualToString:theID]) return [[NSBundle mainBundle] safeLocalizedStringForKey:theID value:theID table:@"QSObjectSource.name"]; else @@ -430,12 +427,13 @@ - (NSImage *)image { return self.icon; } - (NSString *)text { return self.name; } - (NSImage *)icon { - NSImage *image; - if(!(image = [QSResourceManager imageNamed:[info objectForKey:kItemIcon]])){ - if(!(image = [[QSReg sourceNamed:[info objectForKey:kItemSource]] iconForEntry:info])){ - image = [QSResourceManager imageNamed:@"Catalog"]; - } - } + NSImage *image = [QSResourceManager imageNamed:[info objectForKey:kItemIcon]]; + if (!image) + image = image = [self.source iconForEntry:info]; + + if (!image) + image = [QSResourceManager imageNamed:@"Catalog"]; + return image; } @@ -531,27 +529,28 @@ - (BOOL)indexIsValid { } } if (isValid) { - isValid = [[self source] indexIsValidFromDate:indexDate forEntry:info]; + isValid = [self.source indexIsValidFromDate:indexDate forEntry:info]; } }); return isValid; } -- (id)source { - id source = [QSReg sourceNamed:[info objectForKey:kItemSource]]; +- (QSObjectSource *)source { + if (!_source) { + _source = [QSReg sourceNamed:[info objectForKey:kItemSource]]; #ifdef DEBUG - if (!source && VERBOSE) - NSLog(@"Source not found: %@ for Entry: %@", [info objectForKey:kItemSource] , self.identifier); + if (!_source && VERBOSE) + NSLog(@"Source not found: %@ for Entry: %@", [info objectForKey:kItemSource], self.identifier); #endif - return source; + } + return _source; } - (NSArray *)scannedObjects { NSArray *itemContents = nil; @autoreleasepool { @try { - QSObjectSource *source = [self source]; - itemContents = [source objectsForEntry:info]; + itemContents = [self.source objectsForEntry:info]; } @catch (NSException *exception) { NSLog(@"An error ocurred while scanning \"%@\": %@", self.name, exception); @@ -562,12 +561,10 @@ - (NSArray *)scannedObjects { } - (BOOL)canBeIndexed { - QSObjectSource *source = [self source]; - - if (![source respondsToSelector:@selector(entryCanBeIndexed:)]) + if (![self.source respondsToSelector:@selector(entryCanBeIndexed:)]) return YES; - return [source entryCanBeIndexed:[self info]]; + return [self.source entryCanBeIndexed:[self info]]; } - (NSArray *)scanAndCache { From 4a5d6e1f8d63dc943f98ed9b6ec04a3ad1378e2b Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:40:53 +0200 Subject: [PATCH 18/51] Move some selectors to the QSObjectSource protocol. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 5 ----- Quicksilver/Code-QuickStepCore/QSObjectSource.h | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 8ab8f9e34..825aebdca 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -18,11 +18,6 @@ #import "QSTask.h" #import -@interface NSObject (QSCatalogSourceInformal) -- (void)enableEntry:(QSCatalogEntry *)entry; -- (void)disableEntry:(QSCatalogEntry *)entry; -@end - #define kUseNSArchiveForIndexes NO; @interface QSCatalogEntry () { diff --git a/Quicksilver/Code-QuickStepCore/QSObjectSource.h b/Quicksilver/Code-QuickStepCore/QSObjectSource.h index 5a31aa3f2..2673cdd31 100644 --- a/Quicksilver/Code-QuickStepCore/QSObjectSource.h +++ b/Quicksilver/Code-QuickStepCore/QSObjectSource.h @@ -13,6 +13,10 @@ - (void)setSettingsView:(NSView *)newSettingsView; - (BOOL)isVisibleSource; - (BOOL)entryCanBeIndexed:(NSDictionary *)theEntry; + +- (void)enableEntry:(QSCatalogEntry *)entry; +- (void)disableEntry:(QSCatalogEntry *)entry; + - (BOOL)usesGlobalSettings; @end From 623e1a2462de51c93fd8e745c605b1dd1c9ba559 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 17:45:58 +0200 Subject: [PATCH 19/51] Property-fy `indexDate`. --- .../Code-QuickStepCore/QSCatalogEntry.h | 3 +-- .../Code-QuickStepCore/QSCatalogEntry.m | 20 ++++++------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 46b21134b..0f94928bd 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -26,6 +26,7 @@ @property (readonly, retain) NSImage *icon; @property (readonly, copy) NSString *identifier; @property (readonly, retain) QSObjectSource *source; +@property (retain) NSDate *indexDate; @property (readonly, retain) NSArray *contents; @@ -62,8 +63,6 @@ - (NSMutableDictionary *)info; - (NSString *)indexLocation; -- (NSDate *)indexDate; -- (void)setIndexDate:(NSDate *)anIndexDate; - (NSUInteger)count; - (NSIndexPath *)catalogSetIndexPath; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 825aebdca..17e038d19 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -25,8 +25,6 @@ @interface QSCatalogEntry () { NSArray *_contents; QSObjectSource *_source; - __block NSDate *indexDate; - id parent; NSMutableArray *children; dispatch_queue_t scanQueue; @@ -73,7 +71,7 @@ - (instancetype)init { if (!self) return nil; _name = nil; - indexDate = nil; + _indexDate = nil; parent = nil; children = nil; _contents = nil; @@ -483,7 +481,7 @@ - (void)saveIndex { if (DEBUG_CATALOG) NSLog(@"saving index for %@", self); #endif - [self setIndexDate:[NSDate date]]; + self.indexDate = [NSDate date]; @try { NSArray *writeArray = [self.contents arrayByPerformingSelector:@selector(dictionaryRepresentation)]; @@ -513,18 +511,18 @@ - (BOOL)indexIsValid { isValid = NO; } if (isValid) { - if (!indexDate) - [self setIndexDate:[[manager attributesOfItemAtPath:indexPath error:NULL] fileModificationDate]]; + if (!self.indexDate) + self.indexDate = [[manager attributesOfItemAtPath:indexPath error:NULL] fileModificationDate]; NSNumber *modInterval = [info objectForKey:kItemModificationDate]; if (modInterval) { NSDate *specDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[modInterval doubleValue]]; - if ([specDate compare:indexDate] == NSOrderedDescending) { + if ([specDate compare:self.indexDate] == NSOrderedDescending) { isValid = NO; //Catalog Specification is more recent than index } } } if (isValid) { - isValid = [self.source indexIsValidFromDate:indexDate forEntry:info]; + isValid = [self.source indexIsValidFromDate:self.indexDate forEntry:info]; } }); return isValid; @@ -692,10 +690,4 @@ - (QSCatalogEntry *)uniqueCopy { return newEntry; } -- (NSDate *)indexDate { return indexDate; } -- (void)setIndexDate:(NSDate *)anIndexDate { - // NSLog(@"date %@ ->%@", indexDate, anIndexDate); - indexDate = anIndexDate; -} - @end From ff039bc9655b3a9c54ee57bc689002573d39b6bb Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 18:13:00 +0200 Subject: [PATCH 20/51] Private method. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 -- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 0f94928bd..60d747a7b 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -61,8 +61,6 @@ - (NSArray *)contentsScanIfNeeded:(BOOL)canScan; - (NSIndexPath *)catalogIndexPath; - (NSMutableDictionary *)info; -- (NSString *)indexLocation; - - (NSUInteger)count; - (NSIndexPath *)catalogSetIndexPath; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 17e038d19..740da5262 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -35,6 +35,8 @@ @interface QSCatalogEntry () { @property (getter=isScanning) BOOL scanning; @property (retain) NSArray *contents; +- (NSString *)indexLocation; + @end @implementation QSCatalogEntry From f2e17e0384159c97fdd2d398704e986e7e33f285 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 18:04:29 +0200 Subject: [PATCH 21/51] Property-fy `children`. This one adds a bunch of warnings, which I plan to fix. --- .../Code-QuickStepCore/QSCatalogEntry.h | 3 +- .../Code-QuickStepCore/QSCatalogEntry.m | 66 +++++++++---------- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 27 ++++---- 3 files changed, 43 insertions(+), 53 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 60d747a7b..e6b221536 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -29,6 +29,7 @@ @property (retain) NSDate *indexDate; @property (readonly, retain) NSArray *contents; +@property (readonly, retain) NSMutableArray *children; + (instancetype)entryWithDictionary:(NSDictionary *)dict; - (NSDictionary *)dictionaryRepresentation; @@ -56,8 +57,6 @@ - (NSArray *)scannedObjects; - (NSArray *)scanAndCache; - (void)scanForced:(BOOL)force; -- (NSMutableArray *)children; -- (NSMutableArray *)getChildren; - (NSArray *)contentsScanIfNeeded:(BOOL)canScan; - (NSIndexPath *)catalogIndexPath; - (NSMutableDictionary *)info; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 740da5262..d1b8c9f0b 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -26,7 +26,7 @@ @interface QSCatalogEntry () { QSObjectSource *_source; id parent; - NSMutableArray *children; + NSMutableArray *_children; dispatch_queue_t scanQueue; NSMutableDictionary *info; NSBundle *bundle; @@ -34,6 +34,7 @@ @interface QSCatalogEntry () { @property (getter=isScanning) BOOL scanning; @property (retain) NSArray *contents; +@property (retain) NSMutableArray *children; - (NSString *)indexLocation; @@ -75,7 +76,7 @@ - (instancetype)init { _name = nil; _indexDate = nil; parent = nil; - children = nil; + _children = [NSMutableArray array]; _contents = nil; info = nil; @@ -90,12 +91,13 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { NSArray *childDicts = [dict objectForKey:kItemChildren]; if (childDicts) { - NSMutableArray *newChildren = [NSMutableArray array]; - for(NSDictionary *child in childDicts) { + NSMutableArray *newChildren = [NSMutableArray arrayWithCapacity:childDicts.count]; + for (NSDictionary *child in childDicts) { [newChildren addObject:[QSCatalogEntry entryWithDictionary:child]]; } - children = newChildren; + self.children = newChildren; } + // create a serial dispatch queue to make scan processes serial for each catalog entry scanQueue = dispatch_queue_create([[NSString stringWithFormat:@"QSCatalogEntry scanQueue: %@",[dict objectForKey:kItemID]] UTF8String], NULL); dispatch_queue_set_specific(scanQueue, kQueueCatalogEntry, (__bridge void *)self, NULL); @@ -117,13 +119,13 @@ - (void)dealloc { } - (NSDictionary *)dictionaryRepresentation { - if (children) - [info setObject:[children valueForKey:@"dictionaryRepresentation"] forKey:kItemChildren]; + if (self.children) + [info setObject:[self.children valueForKey:@"dictionaryRepresentation"] forKey:kItemChildren]; return info; } - (QSCatalogEntry *)childWithID:(NSString *)theID { - for (QSCatalogEntry *child in children) { + for (QSCatalogEntry *child in self.children) { if ([child.identifier isEqualToString:theID]) return child; } @@ -208,7 +210,7 @@ - (NSInteger)state { BOOL enabled = self.isEnabled; if (!enabled) return 0; if (self.isGroup) { - for(QSCatalogEntry *child in [self deepChildrenWithGroups:NO leaves:YES disabled:YES]) { + for (QSCatalogEntry *child in [self deepChildrenWithGroups:NO leaves:YES disabled:YES]) { if (!child.isEnabled) return -1*enabled; } } @@ -218,7 +220,7 @@ - (NSInteger)state { - (NSInteger)hasEnabledChildren { if (self.isGroup) { BOOL hasEnabledChildren = NO; - for (QSCatalogEntry *child in children) + for (QSCatalogEntry *child in self.children) hasEnabledChildren |= child.isEnabled; return hasEnabledChildren; } else @@ -259,26 +261,33 @@ - (void)setDeepEnabled:(BOOL)enabled { self.enabled = YES; if (self.isGroup) { NSArray *deepChildren = [self deepChildrenWithGroups:YES leaves:YES disabled:YES]; - for(QSCatalogEntry *child in deepChildren) + for (QSCatalogEntry *child in deepChildren) child.enabled = enabled; } } - (void)pruneInvalidChildren { - NSMutableArray *children2 = [children copy]; - for (QSCatalogEntry *child in children2) { + // Make a copy because we're gonna change our children in the loop below + NSMutableArray *originalChildren = self.children.copy; +#warning There ought to be a better looping method + // Right now this makes a copy, loops, and lookup/remove the object in the original... + for (QSCatalogEntry *child in originalChildren) { +#warning What does "end of presets" means ? + // Let me guess, we're depending on the order in which the presets appear in the file... + if (child.isSeparator) break; //Stop when at end of presets + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && child.isSuppressed) { #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", child.identifier); #endif - [children removeObject:child]; + [self.children removeObject:child]; } else if (child.isGroup) { [child pruneInvalidChildren]; - if (![(NSArray *)[child children] count]) // Remove empty groups - [children removeObject:child]; + if (!child.children.count == 0) // Remove empty groups + [self.children removeObject:child]; } } } @@ -288,7 +297,7 @@ - (NSArray *)leafIDs { if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; - for(QSCatalogEntry *child in children) { + for(QSCatalogEntry *child in self.children) { [childObjects addObjectsFromArray:[child leafIDs]]; } return childObjects; @@ -313,7 +322,7 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(B if (groups) [childObjects addObject:self]; - for (QSCatalogEntry *child in children) { + for (QSCatalogEntry *child in self.children) { [childObjects addObjectsFromArray:[child deepChildrenWithGroups:groups leaves:leaves disabled:disabled]]; } return childObjects; @@ -599,7 +608,7 @@ - (void)scanForced:(BOOL)force { if (self.isGroup) { @autoreleasepool { - for(QSCatalogEntry * child in children) { + for(QSCatalogEntry *child in self.children) { [child scanForced:force]; } } @@ -624,19 +633,6 @@ - (void)scanForced:(BOOL)force { return; } -- (NSMutableArray *)children { return children; } -- (NSMutableArray *)getChildren { - if (!children) - children = [[NSMutableArray alloc] init]; - return children; -} - -- (void)setChildren:(NSArray *)newChildren { - if(newChildren != children){ - children = [newChildren mutableCopy]; - } -} - - (NSArray *)contents { @synchronized (self) { return [self contentsScanIfNeeded:NO]; @@ -656,7 +652,7 @@ - (NSArray *)contentsScanIfNeeded:(BOOL)canScan { if (self.isGroup) { NSMutableSet *childObjects = [NSMutableSet setWithCapacity:1]; - for (QSCatalogEntry *child in children) { + for (QSCatalogEntry *child in self.children) { [childObjects addObjectsFromArray:[child contentsScanIfNeeded:canScan]]; } return [childObjects allObjects]; @@ -686,8 +682,8 @@ - (QSCatalogEntry *)uniqueCopy { [newDictionary setObject:[NSString uniqueString] forKey:kItemID]; QSCatalogEntry *newEntry = [[QSCatalogEntry alloc] initWithDictionary:newDictionary]; - if ([self children]) - [newEntry setChildren:[[self children] valueForKey:@"uniqueCopy"]]; + if (self.children) + newEntry.children = [self.children valueForKey:@"uniqueCopy"]; return newEntry; } diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index 6bd9dcc44..d7d1fc14d 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -138,22 +138,17 @@ - (NSNumber *)presetIsEnabled:(QSCatalogEntry *)preset { - (void)registerPresets:(NSArray *)newPresets inBundle:(NSBundle *)bundle scan:(BOOL)scan { - - //NSLog(@"prestes %@", newPresets); - NSMutableDictionary *dict; - QSCatalogEntry *entry, *parent; - NSString *path; - NSMutableArray *children; - for(dict in newPresets) { - parent = nil; - entry = [QSCatalogEntry entryWithDictionary:dict]; - path = [dict objectForKey:@"catalogPath"]; - [dict setObject:bundle forKey:@"bundle"]; + for (NSMutableDictionary *dict in newPresets) { + // Set `bundle` before the entry gets created + dict[@"bundle"] = bundle; + QSCatalogEntry *entry = [QSCatalogEntry entryWithDictionary:dict]; + NSString *path = [dict objectForKey:@"catalogPath"]; NSArray *grandchildren = [entry deepChildrenWithGroups:YES leaves:YES disabled:YES]; [grandchildren setValue:bundle forKey:@"bundle"]; + QSCatalogEntry *parent = nil; if ([path isEqualToString:@"/"]) parent = catalog; else if (path) @@ -164,9 +159,10 @@ - (void)registerPresets:(NSArray *)newPresets inBundle:(NSBundle *)bundle scan:( parent = [catalog childWithPath:@"QSPresetModules"]; // NSLog(@"register failed %@ %@ %@", parent, path, [entry identifier]); } - children = [parent getChildren]; - [children addObject:entry]; - [children sortUsingFunction:presetSort context:(__bridge void *)(self)]; +// children = [parent getChildren]; + [parent.children addObject:entry]; +#warning oh yeah, while we're at it, sort on each loop ! + [parent.children sortUsingFunction:presetSort context:(__bridge void *)(self)]; if (scan) [entry scanForced:YES]; } //[catalogChildren replaceObjectsInRange:NSMakeRange(0, 0) withObjectsFromArray:newPresets]; @@ -175,7 +171,6 @@ - (void)registerPresets:(NSArray *)newPresets inBundle:(NSBundle *)bundle scan:( - (void)initCatalog {} - (void)loadCatalogInfo { - NSMutableArray *catalogChildren = [catalog getChildren]; // NSLog(@"load Catalog %p %@", catalog, [catalog getChildren]); //[catalogChildren addObject:[QSCatalogEntry entryWithDictionary:[NSDictionary dictionaryWithObjectsAndKeys:@"QSSeparator", kItemID, nil]]]; @@ -188,7 +183,7 @@ - (void)loadCatalogInfo { [NSNumber numberWithBool:YES] , @"permanent", [NSNumber numberWithBool:YES] , kItemEnabled, nil]]; - [catalogChildren addObject:customEntry]; + [catalog.children addObject:customEntry]; NSMutableDictionary *catalogStorage = [NSMutableDictionary dictionaryWithContentsOfFile:[pCatalogSettings stringByStandardizingPath]]; From 8665f2f18db79f969e1eea4a8f6cc996a702d864 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 18:47:38 +0200 Subject: [PATCH 22/51] Correct the prune mechanism. This fixes a bug introduced in the previous commit that caused all preset entries to disappear. This makes the prune loop cleaner by : - testing for entries being presets or not (the previous test depended on the ordering of presets relative to custom entries, which the previous commit changed). - not making a copy at all. --- .../Code-QuickStepCore/QSCatalogEntry.m | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index d1b8c9f0b..b495b99ed 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -267,29 +267,24 @@ - (void)setDeepEnabled:(BOOL)enabled { } - (void)pruneInvalidChildren { - // Make a copy because we're gonna change our children in the loop below - NSMutableArray *originalChildren = self.children.copy; -#warning There ought to be a better looping method - // Right now this makes a copy, loops, and lookup/remove the object in the original... - for (QSCatalogEntry *child in originalChildren) { -#warning What does "end of presets" means ? - // Let me guess, we're depending on the order in which the presets appear in the file... - - if (child.isSeparator) break; //Stop when at end of presets - - if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"] && child.isSuppressed) { + /* Do a "manual" reverse enumeration because we'd be mutating-while-enumerating + * and we don't want our index to move around. */ + for (NSInteger i = self.children.count - 1; i >= 0; --i) { + QSCatalogEntry *child = self.children[i]; + if (!child.isPreset) continue; // Prune presets only + if (child.isSuppressed && ![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"]) { #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", child.identifier); #endif - - [self.children removeObject:child]; - } else if (child.isGroup) { - [child pruneInvalidChildren]; - if (!child.children.count == 0) // Remove empty groups - [self.children removeObject:child]; - } - } + [self.children removeObjectAtIndex:i]; + } else if (child.isGroup) { + // Prune subgroup and remove it if empty + [child pruneInvalidChildren]; + if (child.children.count == 0) + [self.children removeObjectAtIndex:i]; + } + } } - (NSArray *)leafIDs { From 39ae1e6eba6074177f23bffbdbc133cfc10bdf9c Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 20:09:45 +0200 Subject: [PATCH 23/51] Make QSCatalogEntry info dictionary private. Also updates accesses to keyed-subscript + document the keys in the `_Private` file. --- .../Code-QuickStepCore/QSCatalogEntry.h | 1 - .../Code-QuickStepCore/QSCatalogEntry.m | 87 +++++++++---------- .../QSCatalogEntry_Private.h | 32 +++++++ .../Quicksilver.xcodeproj/project.pbxproj | 4 + 4 files changed, 78 insertions(+), 46 deletions(-) create mode 100644 Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index e6b221536..b4dd4e385 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -59,7 +59,6 @@ - (void)scanForced:(BOOL)force; - (NSArray *)contentsScanIfNeeded:(BOOL)canScan; - (NSIndexPath *)catalogIndexPath; -- (NSMutableDictionary *)info; - (NSUInteger)count; - (NSIndexPath *)catalogSetIndexPath; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index b495b99ed..d4520d73e 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -6,7 +6,9 @@ // Copyright 2005 Blacktree. All rights reserved. // +#import #import "QSCatalogEntry.h" +#import "QSCatalogEntry_Private.h" #import "QSRegistry.h" #import "QSLibrarian.h" #import "QSResourceManager.h" @@ -16,7 +18,6 @@ #import "QSTaskController.h" #import "QSObject_PropertyList.h" #import "QSTask.h" -#import #define kUseNSArchiveForIndexes NO; @@ -28,7 +29,6 @@ @interface QSCatalogEntry () { id parent; NSMutableArray *_children; dispatch_queue_t scanQueue; - NSMutableDictionary *info; NSBundle *bundle; } @@ -78,7 +78,7 @@ - (instancetype)init { parent = nil; _children = [NSMutableArray array]; _contents = nil; - info = nil; + _info = [NSMutableDictionary dictionary]; return self; } @@ -87,9 +87,12 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { self = [self init]; if (!self) return nil; - info = [dict mutableCopy]; + _info = [dict mutableCopy]; + NSDictionary *settings = _info[kItemSettings]; + if (settings) + _info[kItemSettings] = settings.mutableCopy; - NSArray *childDicts = [dict objectForKey:kItemChildren]; + NSArray *childDicts = dict[kItemChildren]; if (childDicts) { NSMutableArray *newChildren = [NSMutableArray arrayWithCapacity:childDicts.count]; for (NSDictionary *child in childDicts) { @@ -119,9 +122,10 @@ - (void)dealloc { } - (NSDictionary *)dictionaryRepresentation { + NSMutableDictionary *dict = self.info.mutableCopy; if (self.children) - [info setObject:[self.children valueForKey:@"dictionaryRepresentation"] forKey:kItemChildren]; - return info; + dict[kItemChildren] = [self.children valueForKey:@"dictionaryRepresentation"]; + return dict; } - (QSCatalogEntry *)childWithID:(NSString *)theID { @@ -143,18 +147,15 @@ - (QSCatalogEntry *)childWithPath:(NSString *)path { } - (BOOL)isSuppressed { -#ifdef DEBUG - return NO; -#endif - NSString *path = [info objectForKey:@"requiresPath"]; + NSString *path = self.info[@"requiresPath"]; if (path && ![[NSFileManager defaultManager] fileExistsAtPath:[path stringByResolvingWildcardsInPath]]) return YES; - if ([[info objectForKey:@"requiresSettingsPath"] boolValue]) { - path = [[info objectForKey:@"settings"] objectForKey:kItemPath]; + if ([self.info[@"requiresSettingsPath"] boolValue]) { + path = self.info[kItemSettings][kItemPath]; if (path && ![[NSFileManager defaultManager] fileExistsAtPath:[path stringByResolvingWildcardsInPath]]) return YES; } - NSString *requiredBundle = [info objectForKey:@"requiresBundle"]; + NSString *requiredBundle = self.info[@"requiresBundle"]; if (requiredBundle && ![[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:requiredBundle]) return YES; return NO; @@ -179,7 +180,7 @@ - (NSDate *)lastScanDate { - (BOOL)deletable { if (self.isPreset) return NO; - return ![[info objectForKey:@"permanent"] boolValue]; + return ![self.info[@"permanent"] boolValue]; } - (BOOL)isEditable { @@ -203,7 +204,7 @@ - (NSString *)type { - (BOOL)isCatalog { return self == [[QSLibrarian sharedInstance] catalog]; } - (BOOL)isPreset { return [self.identifier hasPrefix:@"QSPreset"]; } - (BOOL)isSeparator { return [self.identifier hasPrefix:@"QSSeparator"]; } -- (BOOL)isGroup { return [[info objectForKey:kItemSource] isEqualToString:@"QSGroupObjectSource"]; } +- (BOOL)isGroup { return [self.info[kItemSource] isEqualToString:@"QSGroupObjectSource"]; } - (BOOL)isLeaf { return !self.isGroup; } - (NSInteger)state { @@ -233,12 +234,12 @@ - (BOOL)shouldIndex { - (BOOL)isEnabled { if (!self.isPreset) - return [[info objectForKey:kItemEnabled] boolValue]; + return [self.info[kItemEnabled] boolValue]; NSNumber *value; if (value = [[QSLibrarian sharedInstance] presetIsEnabled:self]) return [value boolValue]; - else if (value = [info objectForKey:kItemEnabled]) + else if (value = self.info[kItemEnabled]) return [value boolValue]; #warning this is just a little silly... @@ -249,7 +250,7 @@ - (void)setEnabled:(BOOL)enabled { if (self.isPreset) [[QSLibrarian sharedInstance] setPreset:self isEnabled:enabled]; else - [info setObject:@(enabled) forKey:kItemEnabled]; + self.info[kItemEnabled] = @(enabled); if (enabled && ![[self contents] count]) { [self scanForced:YES]; } @@ -305,10 +306,6 @@ - (NSArray *)leafEntries { return [self deepChildrenWithGroups:NO leaves:YES disabled:NO]; } -- (NSMutableDictionary *)info { - return info; -} - - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled { if (!(disabled || self.isEnabled)) return nil; @@ -331,12 +328,12 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(B } - (NSString *)identifier { - NSString *ID = [info objectForKey:kItemID]; - if (!ID && [info isKindOfClass:[NSMutableDictionary class]]) { - [(NSMutableDictionary *)info setObject:[NSString uniqueString] forKey:kItemID]; - return [info objectForKey:kItemID]; - } else - return ID; + NSString *ID = self.info[kItemID]; + if (!ID) { + ID = [NSString uniqueString]; + self.info[kItemID] = ID; + } + return ID; } - (NSIndexPath *)catalogIndexPath { @@ -398,13 +395,12 @@ - (NSComparisonResult) compare:(QSCatalogEntry *)other { - (NSString *)name { @synchronized (self) { if (self.isSeparator) return @""; +#warning this is tampering with localization if (!_name) - _name = [info objectForKey:kItemName]; + _name = self.info[kItemName]; if (!_name) { NSString *ID = self.identifier; _name = [bundle ? bundle : [NSBundle mainBundle] safeLocalizedStringForKey:ID value:ID table:@"QSCatalogPreset.name"]; - if (_name) - [self setValue:_name forKey:@"name"]; } return _name; } @@ -412,7 +408,7 @@ - (NSString *)name { - (void)setName:(NSString *)newName { @synchronized (self) { - [info setObject:newName forKey:kItemName]; + self.info[kItemName] = newName; _name = newName; } } @@ -426,9 +422,9 @@ - (NSImage *)image { return self.icon; } - (NSString *)text { return self.name; } - (NSImage *)icon { - NSImage *image = [QSResourceManager imageNamed:[info objectForKey:kItemIcon]]; + NSImage *image = [QSResourceManager imageNamed:self.info[kItemIcon]]; if (!image) - image = image = [self.source iconForEntry:info]; + image = image = [self.source iconForEntry:self.info]; if (!image) image = [QSResourceManager imageNamed:@"Catalog"]; @@ -519,7 +515,7 @@ - (BOOL)indexIsValid { if (isValid) { if (!self.indexDate) self.indexDate = [[manager attributesOfItemAtPath:indexPath error:NULL] fileModificationDate]; - NSNumber *modInterval = [info objectForKey:kItemModificationDate]; + NSNumber *modInterval = self.info[kItemModificationDate]; if (modInterval) { NSDate *specDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[modInterval doubleValue]]; if ([specDate compare:self.indexDate] == NSOrderedDescending) { @@ -528,7 +524,7 @@ - (BOOL)indexIsValid { } } if (isValid) { - isValid = [self.source indexIsValidFromDate:self.indexDate forEntry:info]; + isValid = [self.source indexIsValidFromDate:self.indexDate forEntry:self.info]; } }); return isValid; @@ -536,10 +532,10 @@ - (BOOL)indexIsValid { - (QSObjectSource *)source { if (!_source) { - _source = [QSReg sourceNamed:[info objectForKey:kItemSource]]; + _source = [QSReg sourceNamed:self.info[kItemSource]]; #ifdef DEBUG if (!_source && VERBOSE) - NSLog(@"Source not found: %@ for Entry: %@", [info objectForKey:kItemSource], self.identifier); + NSLog(@"Source not found: %@ for Entry: %@", self.info[kItemSource], self.identifier); #endif } return _source; @@ -549,7 +545,7 @@ - (NSArray *)scannedObjects { NSArray *itemContents = nil; @autoreleasepool { @try { - itemContents = [self.source objectsForEntry:info]; + itemContents = [self.source objectsForEntry:self.info]; } @catch (NSException *exception) { NSLog(@"An error ocurred while scanning \"%@\": %@", self.name, exception); @@ -563,7 +559,7 @@ - (BOOL)canBeIndexed { if (![self.source respondsToSelector:@selector(entryCanBeIndexed:)]) return YES; - return [self.source entryCanBeIndexed:[self info]]; + return [self.source entryCanBeIndexed:self.info]; } - (NSArray *)scanAndCache { @@ -669,12 +665,13 @@ - (NSArray *)enabledContents } - (QSCatalogEntry *)uniqueCopy { - NSMutableDictionary *newDictionary = [info mutableCopy]; + NSMutableDictionary *newDictionary = [self.info mutableCopy]; if (self.isPreset) { - [newDictionary setObject:@(self.isEnabled) forKey:kItemEnabled]; - [newDictionary setObject:self.name forKey:kItemName]; + newDictionary[kItemEnabled] = @(self.isEnabled); +#warning this is tampering with localization + newDictionary[kItemName] = self.name; } - [newDictionary setObject:[NSString uniqueString] forKey:kItemID]; + newDictionary[kItemID] = [NSString uniqueString]; QSCatalogEntry *newEntry = [[QSCatalogEntry alloc] initWithDictionary:newDictionary]; if (self.children) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h new file mode 100644 index 000000000..92799402f --- /dev/null +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h @@ -0,0 +1,32 @@ +// +// QSCatalogEntry_Private.h +// Quicksilver +// +// Created by Etienne on 15/09/13. +// +// + +#import + +@interface QSCatalogEntry () +/** + * The receiver's private info dictionary + * + * This is considered private API (some other parts of QS access it directly). + * It contains the following keys: + * - kItemChildren - an array of QSCatalogEntry in dictionary format. + * - @"requiresPath" - a path to a required "file-system object" + * - @"requiresSettingsPath" - a BOOL indicating if the kItemPath in kItemSettings is required + * - @"requiresBundle" - a required bundle identifier + * - @"permanent" - a BOOL indicating if the receiver can be deleted + * - kItemSource - the QSObjectSource identifier of the receiver + * - kItemEnabled - a BOOL representing the enabled state of the receiver + * - kItemID - the identifier for the receiver (will be assigned an UUID if missing) + * - kItemName - the name of the receiver (deprecated because it prevents localization) + * - kItemIcon - the name of the icon to use for the receiver + * - kItemModificationDate - The last modification date of the receiver, as a time interval + * - kItemSettings - a dictionary containing source-specific keys + * - kItemPath - a path to a required "file-system object" + */ +@property (readonly, retain) NSMutableDictionary *info; +@end diff --git a/Quicksilver/Quicksilver.xcodeproj/project.pbxproj b/Quicksilver/Quicksilver.xcodeproj/project.pbxproj index d4531adb6..c9bf277cb 100644 --- a/Quicksilver/Quicksilver.xcodeproj/project.pbxproj +++ b/Quicksilver/Quicksilver.xcodeproj/project.pbxproj @@ -127,6 +127,7 @@ 4D66BC5D1487027E00351C42 /* NSURL+NDCarbonUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D66BBF11486FFF000351C42 /* NSURL+NDCarbonUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4D66BC5E1487027E00351C42 /* NSURL+NDCarbonUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D66BBF21486FFF000351C42 /* NSURL+NDCarbonUtilities.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4D6A663410AB2A2F00898CA4 /* QSTreeController.h in Headers */ = {isa = PBXBuildFile; fileRef = 92D9C9680D134BDD00D91825 /* QSTreeController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4D6D369F17E61F93007017A6 /* QSCatalogEntry_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D6D369E17E61F93007017A6 /* QSCatalogEntry_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4D7DF45416ADC7CA004BA4BE /* DefaultsMap.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4D7DF45316ADC7CA004BA4BE /* DefaultsMap.plist */; }; 4D7DF45716ADCDEF004BA4BE /* QSAdvancedPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D7DF45516ADCDEF004BA4BE /* QSAdvancedPrefPane.strings */; }; 4D89177514758620009C1C14 /* QSMainMenuPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D89177714758620009C1C14 /* QSMainMenuPrefPane.strings */; }; @@ -1132,6 +1133,7 @@ 4D66BC3A1487024500351C42 /* NDScriptData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NDScriptData.m; sourceTree = ""; }; 4D66BC3B1487024500351C42 /* NSString+NDUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+NDUtilities.h"; sourceTree = ""; }; 4D66BC3C1487024500351C42 /* NSString+NDUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+NDUtilities.m"; sourceTree = ""; }; + 4D6D369E17E61F93007017A6 /* QSCatalogEntry_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QSCatalogEntry_Private.h; sourceTree = ""; }; 4D7DF45316ADC7CA004BA4BE /* DefaultsMap.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = DefaultsMap.plist; sourceTree = ""; }; 4D7DF45616ADCDEF004BA4BE /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/QSAdvancedPrefPane.strings; sourceTree = ""; }; 4D7DF45816ADD014004BA4BE /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/QSAdvancedPrefPane.strings; sourceTree = ""; }; @@ -3253,6 +3255,7 @@ 4DD2CF350E7B345500BA1128 /* QSBasicObject.m */, 7FB8D6FA07B98B1300062022 /* QSCatalogEntry.h */, 7FB8D6FB07B98B1300062022 /* QSCatalogEntry.m */, + 4D6D369E17E61F93007017A6 /* QSCatalogEntry_Private.h */, 42ADF4FD1317237900C68070 /* QSClangAnalyzer.h */, E1E5FB6F07B20DD10044D6EF /* QSCollection.h */, E1E5FB7007B20DD10044D6EF /* QSCollection.m */, @@ -3615,6 +3618,7 @@ D413172F15DEE5D90021479B /* LaunchAtLoginController.h in Headers */, CD39DE6016B43FC40087B09E /* (null) in Headers */, CD65B12916FA1BD000932A9C /* QSPluginUpdaterWindowController.h in Headers */, + 4D6D369F17E61F93007017A6 /* QSCatalogEntry_Private.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; From 7af8949be05deee1c2e36865fae92e0f55c019cc Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 20:11:21 +0200 Subject: [PATCH 24/51] Fix QSTriggerCenter now that the declaration for `info` it was using disappeared. Also giggle the code around so it's easier to understand. --- .../Code-QuickStepCore/QSTriggerCenter.m | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSTriggerCenter.m b/Quicksilver/Code-QuickStepCore/QSTriggerCenter.m index 90bceff40..d1b0cccde 100644 --- a/Quicksilver/Code-QuickStepCore/QSTriggerCenter.m +++ b/Quicksilver/Code-QuickStepCore/QSTriggerCenter.m @@ -254,24 +254,31 @@ - (NSDictionary *)triggerManagers { @implementation QSTriggerCenter (QSPlugInInfo) - (BOOL)handleInfo:(id)info ofType:(NSString *)type fromBundle:(NSBundle *)bundle { - id matchEntry = nil; - for(__strong NSDictionary * value in info) { - NSString *iden = [value objectForKey:kItemID]; - //NSLog(@"info %@ %@", iden, value); - if (matchEntry = [triggersDict objectForKey:iden]) { - [[matchEntry info] addEntriesFromDictionary:value]; + for (NSDictionary *triggerDict in info) { + NSString *iden = triggerDict[kItemID]; + QSTrigger *matchEntry = self.triggersDict[iden]; + if (matchEntry) { + /* We found that trigger. + * Update the trigger's info dictionary with the new values + * and remove its defaults. + */ + [[matchEntry info] addEntriesFromDictionary:triggerDict]; [[matchEntry info] removeObjectForKey:@"defaults"]; } else if (iden) { - NSMutableDictionary *defaults = [[value objectForKey:@"defaults"] mutableCopy]; + /* No trigger known with that ID. + * Make ourselves a copy, take the values under @"default" specified + * in triggerDict, remove those values from the final dict, and add + * them back at the root of the new trigger dict. + */ +#warning should the @"defaults" key be removed like the above did ? + NSMutableDictionary *newTriggerDict = [triggerDict mutableCopy]; + NSMutableDictionary *defaults = newTriggerDict[@"defaults"]; if (defaults) { - [defaults removeObjectsForKeys:[value allKeys]]; - value = [value mutableCopy]; - [(NSMutableDictionary *)value addEntriesFromDictionary:defaults]; + [defaults removeObjectsForKeys:[newTriggerDict allKeys]]; + [newTriggerDict addEntriesFromDictionary:defaults]; } - //NSLog(@"create %@, %@", value, [QSTrigger triggerWithInfo:value]); - [triggersDict setObject:[QSTrigger triggerWithDictionary:value] forKey:iden]; + [triggersDict setObject:[QSTrigger triggerWithDictionary:newTriggerDict] forKey:iden]; } - //NSLog(@"info %@ %@ %@", info, matchEntry, triggersDict); } return YES; } From 71c6d77174a52806fe866afea9418b5495d9fbc0 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 20:29:17 +0200 Subject: [PATCH 25/51] Make icon property `readwrite` so that the pref pane can set it. I've put a warning in because I want to check that it works, but it never would have worked in the first place (the pref pane was placing image data in the info dict, which QSCatalogEntry was parsing as an image name). We're lucky that nobody ever tried to customize their catalog entries icons ;). --- Quicksilver/Code-App/QSCatalogPrefPane.m | 3 +- .../Code-QuickStepCore/QSCatalogEntry.h | 2 +- .../Code-QuickStepCore/QSCatalogEntry.m | 34 +++++++++++++++---- .../QSCatalogEntry_Private.h | 3 +- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Quicksilver/Code-App/QSCatalogPrefPane.m b/Quicksilver/Code-App/QSCatalogPrefPane.m index bb7525df9..6cf0aa0d0 100644 --- a/Quicksilver/Code-App/QSCatalogPrefPane.m +++ b/Quicksilver/Code-App/QSCatalogPrefPane.m @@ -539,8 +539,7 @@ - (void)populateCatalogEntryFields { - (IBAction)setValueForSenderForCatalogEntry:(id)sender { if (sender == itemIconField) { - NSData *imageData = [[sender image] TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:0]; - [[currentItem info] setObject:imageData forKey:kItemIcon]; + currentItem.icon = [sender image]; [itemTable reloadData]; } } diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index b4dd4e385..2d63a1117 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -23,7 +23,7 @@ @property (getter=isEnabled) BOOL enabled; @property (copy) NSString *name; -@property (readonly, retain) NSImage *icon; +@property (retain) NSImage *icon; @property (readonly, copy) NSString *identifier; @property (readonly, retain) QSObjectSource *source; @property (retain) NSDate *indexDate; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index d4520d73e..0581a2c8f 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -24,6 +24,7 @@ @interface QSCatalogEntry () { NSString *_name; NSArray *_contents; + NSImage *_icon; QSObjectSource *_source; id parent; @@ -422,14 +423,35 @@ - (NSImage *)image { return self.icon; } - (NSString *)text { return self.name; } - (NSImage *)icon { - NSImage *image = [QSResourceManager imageNamed:self.info[kItemIcon]]; - if (!image) - image = image = [self.source iconForEntry:self.info]; + @synchronized (self) { + _icon = [QSResourceManager imageNamed:self.info[kItemIcon]]; + if (!_icon) + _icon = [self.source iconForEntry:self.info]; + + if (!_icon) + _icon = [QSResourceManager imageNamed:@"Catalog"]; - if (!image) - image = [QSResourceManager imageNamed:@"Catalog"]; +#warning tiennou: must check that this actually works + NSData *iconData = self.info[@"iconData"]; + if (!_icon && iconData) { + _icon = [[NSImage alloc] initWithData:iconData]; + } + + return _icon; + } +} - return image; +- (void)setIcon:(NSImage *)icon { + @synchronized (self) { + if (icon) { + if (_icon.name) { + self.info[kItemIcon] = icon.name; + } else { + self.info[@"iconData"] = [icon TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:0]; + } + } + _icon = icon; + } } - (NSString *)getCount { diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h index 92799402f..5755ffd8f 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h @@ -23,7 +23,8 @@ * - kItemEnabled - a BOOL representing the enabled state of the receiver * - kItemID - the identifier for the receiver (will be assigned an UUID if missing) * - kItemName - the name of the receiver (deprecated because it prevents localization) - * - kItemIcon - the name of the icon to use for the receiver + * - kItemIcon - the name of the icon to use + * - @"iconData" - data for the icon to use * - kItemModificationDate - The last modification date of the receiver, as a time interval * - kItemSettings - a dictionary containing source-specific keys * - kItemPath - a path to a required "file-system object" From 5acadb69ccb8d028ef42d1b14a7df402784ab312 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 20:29:54 +0200 Subject: [PATCH 26/51] We need to include that one because those access `info` directly. --- Quicksilver/Code-App/QSCatalogPrefPane.m | 1 + Quicksilver/Code-QuickStepCore/QSLibrarian.m | 5 ++++- Quicksilver/Code-QuickStepCore/QSObjectSource.m | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Quicksilver/Code-App/QSCatalogPrefPane.m b/Quicksilver/Code-App/QSCatalogPrefPane.m index 6cf0aa0d0..c4bd52d12 100644 --- a/Quicksilver/Code-App/QSCatalogPrefPane.m +++ b/Quicksilver/Code-App/QSCatalogPrefPane.m @@ -31,6 +31,7 @@ #include #import "QSOutlineView.h" #import "QSTableView.h" +#import "QSCatalogEntry_Private.h" @interface QSObject (NSTreeNodePrivate) //- (NSIndexPath *)indexPath; diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index d7d1fc14d..b6dc90468 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -11,6 +11,9 @@ #import "QSTask.h" #import "QSTaskController.h" +#import "QSCatalogEntry.h" +#import "QSCatalogEntry_Private.h" + //#define compGT(a, b) (a < b) CGFloat QSMinScore = 0.333333; @@ -274,7 +277,7 @@ - (void)reloadEntrySources:(NSNotification *)notif { [entriesBySource removeAllObjects]; for (QSCatalogEntry *thisEntry in entries) { - NSString *source = [[thisEntry info] objectForKey:kItemSource]; + NSString *source = [thisEntry.info objectForKey:kItemSource]; NSMutableArray *sourceArray = [entriesBySource objectForKey:source]; if (!sourceArray) { diff --git a/Quicksilver/Code-QuickStepCore/QSObjectSource.m b/Quicksilver/Code-QuickStepCore/QSObjectSource.m index 853065f6e..73b473d07 100644 --- a/Quicksilver/Code-QuickStepCore/QSObjectSource.m +++ b/Quicksilver/Code-QuickStepCore/QSObjectSource.m @@ -7,6 +7,7 @@ #import "QSResourceManager.h" #import "QSNotifications.h" #import "QSCatalogEntry.h" +#import "QSCatalogEntry_Private.h" @implementation QSObjectSource From 2b82ae24c8c4b2d4629d485461c9b2a9e10cb7e4 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 20:33:04 +0200 Subject: [PATCH 27/51] Add a convenience method for object source settings, and use it instead of going though `info`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 2 ++ Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 4 ++++ .../QSCorePlugIn/Code/QSDefaultsObjectSource.m | 4 ++-- .../QSCorePlugIn/Code/QSFileSystemObjectSource.m | 10 +++++----- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 2d63a1117..34f42cc7d 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -31,6 +31,8 @@ @property (readonly, retain) NSArray *contents; @property (readonly, retain) NSMutableArray *children; +@property (readonly, retain) NSMutableDictionary *sourceSettings; + + (instancetype)entryWithDictionary:(NSDictionary *)dict; - (NSDictionary *)dictionaryRepresentation; diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 0581a2c8f..12767cfca 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -702,4 +702,8 @@ - (QSCatalogEntry *)uniqueCopy { return newEntry; } +- (NSMutableDictionary *)sourceSettings { + return self.info[kItemSettings]; +} + @end diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSDefaultsObjectSource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSDefaultsObjectSource.m index 9a5e35248..e06e56b4e 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSDefaultsObjectSource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSDefaultsObjectSource.m @@ -24,8 +24,8 @@ - (BOOL)isVisibleSource { return YES; } - (BOOL)usesGlobalSettings { return NO; } - (void)enableEntry:(QSCatalogEntry *)entry { - NSMutableDictionary *settings = [[entry info] objectForKey:kItemSettings]; - if ([[settings objectForKey:@"watchTarget"] boolValue]) { + NSDictionary *settings = entry.sourceSettings; + if ([settings[@"watchTarget"] boolValue]) { NSString *path = [self prefFileForBundle:[settings objectForKey:kDefaultsObjectSourceBundleID]]; // See VDKQueue.h for more information on queues [[QSVoyeur sharedInstance] addPath:path notifyingAbout:NOTE_DELETE | NOTE_WRITE]; diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m index dc5a85d73..4d797a67e 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m @@ -297,17 +297,17 @@ - (IBAction)endContainingSheet:(id)sender { } - (void)enableEntry:(QSCatalogEntry *)entry { - NSMutableDictionary *settings = [[entry info] objectForKey:kItemSettings]; + NSMutableDictionary *settings = entry.sourceSettings; NSString *path = [self fullPathForSettings:settings]; NSNotificationCenter *wsNotif = [[NSWorkspace sharedWorkspace] notificationCenter]; - if ([[settings objectForKey:@"watchTarget"] boolValue]) { + if ([settings[@"watchTarget"] boolValue]) { [[QSVoyeur sharedInstance] addPath:path notifyingAbout:NOTE_DELETE | NOTE_WRITE]; #ifdef DEBUG if (VERBOSE) NSLog(@"Watching Path %@", path); #endif [wsNotif addObserver:entry selector:@selector(invalidateIndex:) name:nil object:path]; } - NSArray *paths = [settings objectForKey:@"watchPaths"]; + NSArray *paths = settings[@"watchPaths"]; for (NSString * p in paths) { [[QSVoyeur sharedInstance] addPath:p]; #ifdef DEBIG @@ -318,9 +318,9 @@ - (void)enableEntry:(QSCatalogEntry *)entry { } - (void)disableEntry:(QSCatalogEntry *)entry { - NSMutableDictionary *settings = [[entry info] objectForKey:kItemSettings]; + NSMutableDictionary *settings = entry.sourceSettings; NSString *path = [self fullPathForSettings:settings]; - if ([[settings objectForKey:@"watchTarget"] boolValue]) { + if ([settings[@"watchTarget"] boolValue]) { [[QSVoyeur sharedInstance] removePath:path]; [[NSNotificationCenter defaultCenter] removeObserver:entry]; } From 1660469b8354cc8a21fb9de7b3a8062756da329e Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 15 Sep 2013 20:34:04 +0200 Subject: [PATCH 28/51] Build the complete dictionary before creating a new entry from it. --- .../QSCorePlugIn/Code/QSCatalogEntrySource.m | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m index a2632a843..e5816006e 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m @@ -156,22 +156,23 @@ - (QSObject *)addCatalogEntry:(QSObject *)dObject { NSString *file = [[dObject objectForType:QSFilePathType] stringByStandardizingPath]; NSString *uniqueString = [NSString uniqueString]; - - NSMutableDictionary *childDict = [NSMutableDictionary dictionary]; - [childDict setObject:uniqueString forKey:kItemID]; - [childDict setObject:[NSNumber numberWithBool:YES] forKey:kItemEnabled]; - [childDict setObject:[file lastPathComponent] forKey:kItemName]; - [childDict setObject:@"QSFileSystemObjectSource" forKey:kItemSource]; + NSDictionary *childDict = @{ + kItemID: uniqueString, + kItemEnabled: @(YES), + kItemName: [file lastPathComponent], + kItemSource: @"QSFileSystemObjectSource", + kItemPath: [dObject arrayForType:QSFilePathType], + kItemModificationDate: @([NSDate timeIntervalSinceReferenceDate]), + kItemSettings: @{ + kItemPath: file, + } + }; - [childDict setObject:[dObject arrayForType:QSFilePathType] forKey:kItemPath]; - [childDict setObject:[NSNumber numberWithFloat:[NSDate timeIntervalSinceReferenceDate]] forKey:kItemModificationDate]; - QSCatalogEntry *childEntry = [QSCatalogEntry entryWithDictionary:childDict]; - + [[parentEntry children] addObject:childEntry]; - [[childEntry info] setObject:[NSMutableDictionary dictionaryWithObject:file forKey:kItemPath] forKey:kItemSettings]; - [[childEntry info] setObject:[NSNumber numberWithDouble:[NSDate timeIntervalSinceReferenceDate]] forKey:kItemModificationDate]; + [childEntry scanForced:YES]; [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogStructureChanged object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:childEntry]; From 4db88580365eb1ba459202f4848c647f4479bbfb Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 16:52:43 +0200 Subject: [PATCH 29/51] Bug: we don't always want to enable when deepEnabling. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 12767cfca..87dca29a3 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -260,7 +260,7 @@ - (void)setEnabled:(BOOL)enabled { } - (void)setDeepEnabled:(BOOL)enabled { - self.enabled = YES; + self.enabled = enabled; if (self.isGroup) { NSArray *deepChildren = [self deepChildrenWithGroups:YES leaves:YES disabled:YES]; for (QSCatalogEntry *child in deepChildren) From 8d1459cf7216c4f3f798bb0743b46230b2fd6a15 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 16:54:53 +0200 Subject: [PATCH 30/51] Style: use braces. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 87dca29a3..be002f231 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -283,14 +283,17 @@ - (void)pruneInvalidChildren { } else if (child.isGroup) { // Prune subgroup and remove it if empty [child pruneInvalidChildren]; - if (child.children.count == 0) + if (child.children.count == 0) { [self.children removeObjectAtIndex:i]; + } } } } - (NSArray *)leafIDs { - if (!self.isEnabled) return nil; + if (!self.isEnabled) { + return nil; + } if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; From 12c6b632468e9a49df031ea135305b28f8261392 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 19:41:59 +0200 Subject: [PATCH 31/51] Style: dot-syntax, missing braces. --- .../Code-QuickStepCore/QSCatalogEntry.m | 148 +++++++++++------- 1 file changed, 91 insertions(+), 57 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index be002f231..5306fff3b 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -72,7 +72,9 @@ - (NSString *)description { - (instancetype)init { self = [super init]; - if (!self) return nil; + if (!self) { + return nil; + } _name = nil; _indexDate = nil; @@ -86,7 +88,9 @@ - (instancetype)init { - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { self = [self init]; - if (!self) return nil; + if (!self) { + return nil; + } _info = [dict mutableCopy]; NSDictionary *settings = _info[kItemSettings]; @@ -111,37 +115,44 @@ - (QSCatalogEntry *)initWithDictionary:(NSDictionary *)dict { #warning doesn't look used, and doesn't *actually* update enabled... - (void)enable { - if ([self.source respondsToSelector:@selector(enableEntry:)]) + if ([self.source respondsToSelector:@selector(enableEntry:)]) { [self.source enableEntry:self]; + } } - (void)dealloc { - if ([self.source respondsToSelector:@selector(disableEntry:)]) + if ([self.source respondsToSelector:@selector(disableEntry:)]) { [self.source disableEntry:self]; + } + dispatch_release(scanQueue); scanQueue = NULL; } - (NSDictionary *)dictionaryRepresentation { NSMutableDictionary *dict = self.info.mutableCopy; - if (self.children) + if (self.children) { dict[kItemChildren] = [self.children valueForKey:@"dictionaryRepresentation"]; + } return dict; } - (QSCatalogEntry *)childWithID:(NSString *)theID { for (QSCatalogEntry *child in self.children) { - if ([child.identifier isEqualToString:theID]) + if ([child.identifier isEqualToString:theID]) { return child; + } } return nil; } - (QSCatalogEntry *)childWithPath:(NSString *)path { - if (![path length]) + if (path.length == 0) { return self; + } + QSCatalogEntry *object = self; - for(NSString *s in [path pathComponents]) { + for (NSString *s in path.pathComponents) { object = [object childWithID:s]; } return object; @@ -149,37 +160,43 @@ - (QSCatalogEntry *)childWithPath:(NSString *)path { - (BOOL)isSuppressed { NSString *path = self.info[@"requiresPath"]; - if (path && ![[NSFileManager defaultManager] fileExistsAtPath:[path stringByResolvingWildcardsInPath]]) + if (path && ![NSFileManager.defaultManager fileExistsAtPath:path.stringByResolvingWildcardsInPath]) { return YES; + } if ([self.info[@"requiresSettingsPath"] boolValue]) { path = self.info[kItemSettings][kItemPath]; - if (path && ![[NSFileManager defaultManager] fileExistsAtPath:[path stringByResolvingWildcardsInPath]]) + if (path && ![NSFileManager.defaultManager fileExistsAtPath:path.stringByResolvingWildcardsInPath]) { return YES; + } } NSString *requiredBundle = self.info[@"requiresBundle"]; - if (requiredBundle && ![[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:requiredBundle]) + if (requiredBundle && ![NSWorkspace.sharedWorkspace absolutePathForAppBundleWithIdentifier:requiredBundle]) { return YES; + } return NO; } - (NSDate *)lastScanDate { - if ([[self type] isEqualToString:@"Group"]) { - // It's a group entry. Loop through the child catalog entries to find the one with the latest scan date - NSDate *latestScan = nil; - for (QSCatalogEntry *child in [self children]) { - NSDate *childScanDate = [child lastScanDate]; - if (childScanDate && (childScanDate > latestScan || latestScan == nil)) { - latestScan = childScanDate; - } - } - return latestScan; - } - return [[[NSFileManager defaultManager] attributesOfItemAtPath:[self indexLocation] error:nil] objectForKey:NSFileModificationDate]; + /* tiennou: The one with the latest scan date ? Really ? */ + if ([[self type] isEqualToString:@"Group"]) { + // It's a group entry. Loop through the child catalog entries to find the one with the latest scan date + NSDate *latestScan = nil; + for (QSCatalogEntry *child in [self children]) { + NSDate *childScanDate = [child lastScanDate]; + if (childScanDate && (childScanDate > latestScan || latestScan == nil)) { + latestScan = childScanDate; + } + } + return latestScan; + } + return [[NSFileManager.defaultManager attributesOfItemAtPath:self.indexLocation error:NULL] objectForKey:NSFileModificationDate]; } #warning should rename... - (BOOL)deletable { - if (self.isPreset) return NO; + if (self.isPreset) { + return NO; + } return ![self.info[@"permanent"] boolValue]; } @@ -196,10 +213,11 @@ - (BOOL)isEditable { - (NSString *)type { NSString *theID = NSStringFromClass([self.source class]); NSString *title = [[NSBundle bundleForClass:[self.source class]] safeLocalizedStringForKey:theID value:theID table:@"QSObjectSource.name"]; - if ([title isEqualToString:theID]) + if ([title isEqualToString:theID]) { return [[NSBundle mainBundle] safeLocalizedStringForKey:theID value:theID table:@"QSObjectSource.name"]; - else + } else { return title; + } } - (BOOL)isCatalog { return self == [[QSLibrarian sharedInstance] catalog]; } @@ -213,7 +231,9 @@ - (NSInteger)state { if (!enabled) return 0; if (self.isGroup) { for (QSCatalogEntry *child in [self deepChildrenWithGroups:NO leaves:YES disabled:YES]) { - if (!child.isEnabled) return -1*enabled; + if (!child.isEnabled) { + return -1*enabled; + } } } return enabled; @@ -225,8 +245,9 @@ - (NSInteger)hasEnabledChildren { for (QSCatalogEntry *child in self.children) hasEnabledChildren |= child.isEnabled; return hasEnabledChildren; - } else - return YES; + } + + return YES; } - (BOOL)shouldIndex { @@ -263,8 +284,9 @@ - (void)setDeepEnabled:(BOOL)enabled { self.enabled = enabled; if (self.isGroup) { NSArray *deepChildren = [self deepChildrenWithGroups:YES leaves:YES disabled:YES]; - for (QSCatalogEntry *child in deepChildren) + for (QSCatalogEntry *child in deepChildren) { child.enabled = enabled; + } } } @@ -303,7 +325,7 @@ - (NSArray *)leafIDs { return childObjects; } - return [NSArray arrayWithObject:self.identifier]; + return @[self.identifier]; } - (NSArray *)leafEntries { @@ -311,7 +333,9 @@ - (NSArray *)leafEntries { } - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled { - if (!(disabled || self.isEnabled)) return nil; + if (!(disabled || self.isEnabled)) { + return nil; + } if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; @@ -325,7 +349,7 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(B } if (leaves) { - return [NSArray arrayWithObject:self]; + return @[self]; } return nil; @@ -365,21 +389,22 @@ - (NSIndexPath *)catalogSetIndexPath { } - (NSArray *)ancestors { - id catalog = [[QSLibrarian sharedInstance] catalog]; + QSCatalogEntry *catalog = [QSLibrarian.sharedInstance catalog]; NSArray *groups = [catalog deepChildrenWithGroups:YES leaves:NO disabled:YES]; NSMutableArray *entryChain = [NSMutableArray arrayWithCapacity:0]; - id thisItem = self; + QSCatalogEntry *thisItem = self; + QSCatalogEntry *theGroup = nil; NSUInteger i; + [entryChain addObject:self]; - id theGroup = nil; - while(thisItem != catalog) { - for (i = 0; i < [groups count]; i++) { - theGroup = [groups objectAtIndex:i]; - if ([[theGroup children] containsObject:thisItem]) { + while (thisItem != catalog) { + for (i = 0; i < groups.count; i++) { + theGroup = groups[i]; + if ([theGroup.children containsObject:thisItem]) { [entryChain insertObject:theGroup atIndex:0]; thisItem = theGroup; break; - } else if (i == [groups count] - 1) { + } else if (i == groups.count - 1) { NSLog(@"couldn't find parent of %@", thisItem); return nil; } @@ -392,16 +417,19 @@ - (NSComparisonResult) compare:(QSCatalogEntry *)other { if (other.name != nil) { return [self.name compare:other.name]; } - // othername is nil, so make the receiver higher in the list + // other.name is nil, so make the receiver higher in the list return NSOrderedAscending; } - (NSString *)name { @synchronized (self) { - if (self.isSeparator) return @""; + if (self.isSeparator) { + return @""; + } #warning this is tampering with localization - if (!_name) + if (!_name) { _name = self.info[kItemName]; + } if (!_name) { NSString *ID = self.identifier; _name = [bundle ? bundle : [NSBundle mainBundle] safeLocalizedStringForKey:ID value:ID table:@"QSCatalogPreset.name"]; @@ -466,14 +494,18 @@ - (NSString *)getCount { } - (NSUInteger)count { - return [self deepObjectCount]; + return self.deepObjectCount; } - (NSUInteger)deepObjectCount { NSArray *leaves = [self deepChildrenWithGroups:NO leaves:YES disabled:NO]; NSUInteger i, count = 0; - for (i = 0; i < [leaves count]; i++) - count += [(NSArray *)[[leaves objectAtIndex:i] enabledContents] count]; + + for (i = 0; i < leaves.count; i++) { + QSCatalogEntry *leaf = leaves[i]; + count += leaf.enabledContents.count; + } + return count; } @@ -483,21 +515,21 @@ - (NSString *)indexLocation { - (BOOL)loadIndex { if (self.isEnabled) { - NSString *indexPath = self.indexLocation; NSMutableArray *dictionaryArray = nil; @try { - dictionaryArray = [QSObject objectsWithDictionaryArray:[NSMutableArray arrayWithContentsOfFile:indexPath]]; + dictionaryArray = [QSObject objectsWithDictionaryArray:@[self.indexLocation]]; } @catch (NSException *e) { NSLog(@"Error loading index of %@: %@", self.name , e); } - if (!dictionaryArray) + if (!dictionaryArray) { return NO; + } [self setContents:dictionaryArray]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIndexed object:self]; - [[QSLibrarian sharedInstance] recalculateTypeArraysForItem:self]; + [NSNotificationCenter.defaultCenter postNotificationName:QSCatalogEntryIndexed object:self]; + [QSLibrarian.sharedInstance recalculateTypeArraysForItem:self]; } return YES; } @@ -532,14 +564,14 @@ - (void)invalidateIndex:(NSNotification *)notif { - (BOOL)indexIsValid { __block BOOL isValid = YES; QSGCDQueueSync(scanQueue,^{ - NSFileManager *manager = [NSFileManager defaultManager]; - NSString *indexPath = self.indexLocation; - if (![manager fileExistsAtPath:self.indexLocation isDirectory:nil]) { + NSFileManager *manager = NSFileManager.defaultManager; + NSString *indexLocation = self.indexLocation; + if (![manager fileExistsAtPath:indexLocation isDirectory:nil]) { isValid = NO; } if (isValid) { if (!self.indexDate) - self.indexDate = [[manager attributesOfItemAtPath:indexPath error:NULL] fileModificationDate]; + self.indexDate = [[manager attributesOfItemAtPath:indexLocation error:NULL] fileModificationDate]; NSNumber *modInterval = self.info[kItemModificationDate]; if (modInterval) { NSDate *specDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[modInterval doubleValue]]; @@ -620,7 +652,9 @@ - (NSArray *)scanAndCache { } - (void)scanForced:(BOOL)force { - if (self.isSeparator || !self.isEnabled) return; + if (self.isSeparator || !self.isEnabled) { + return; + } if (self.isGroup) { @autoreleasepool { From 6a12884203355d25301c6239ef76d5185f4a7f8f Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 19:42:38 +0200 Subject: [PATCH 32/51] Rewrite that so its clearer. Also adds a @synchronized. --- .../Code-QuickStepCore/QSCatalogEntry.m | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 5306fff3b..f6d8be11b 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -255,29 +255,32 @@ - (BOOL)shouldIndex { } - (BOOL)isEnabled { - if (!self.isPreset) - return [self.info[kItemEnabled] boolValue]; - - NSNumber *value; - if (value = [[QSLibrarian sharedInstance] presetIsEnabled:self]) - return [value boolValue]; - else if (value = self.info[kItemEnabled]) - return [value boolValue]; + @synchronized (self) { + /* Check our enabled state, defaulting to YES if not defined yet. */ + if (self.isPreset) { + NSNumber *value = [[QSLibrarian sharedInstance] presetIsEnabled:self]; + return (value != nil ? value.boolValue : YES); + } -#warning this is just a little silly... - return YES; + NSNumber *value = self.info[kItemEnabled]; + return (value != nil ? value.boolValue : YES); + } } - (void)setEnabled:(BOOL)enabled { - if (self.isPreset) - [[QSLibrarian sharedInstance] setPreset:self isEnabled:enabled]; - else - self.info[kItemEnabled] = @(enabled); - if (enabled && ![[self contents] count]) { - [self scanForced:YES]; - } + @synchronized (self) { + if (self.isPreset) { + [[QSLibrarian sharedInstance] setPreset:self isEnabled:enabled]; + return; + } - [QSLib writeCatalog:self]; + self.info[kItemEnabled] = @(enabled); + if (enabled && self.contents.count == 0) { + [self scanForced:YES]; + } + + [QSLib writeCatalog:self]; + } } - (void)setDeepEnabled:(BOOL)enabled { From f6167ae586b3049f3bdfb12196533054a77dce1f Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 19:43:15 +0200 Subject: [PATCH 33/51] Use `indexesOfObjectsPassingTest:`. I'm not sure how it behaves with the recursion though... --- .../Code-QuickStepCore/QSCatalogEntry.m | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index f6d8be11b..fc6ce7afe 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -296,23 +296,24 @@ - (void)setDeepEnabled:(BOOL)enabled { - (void)pruneInvalidChildren { /* Do a "manual" reverse enumeration because we'd be mutating-while-enumerating * and we don't want our index to move around. */ - for (NSInteger i = self.children.count - 1; i >= 0; --i) { - QSCatalogEntry *child = self.children[i]; - if (!child.isPreset) continue; // Prune presets only + NSIndexSet *prunedChildren = [self.children indexesOfObjectsPassingTest:^BOOL(QSCatalogEntry *child, NSUInteger idx, BOOL *stop) { + if (!child.isPreset) { + /* Prune presets only */ + return NO; + } - if (child.isSuppressed && ![[NSUserDefaults standardUserDefaults] boolForKey:@"Show All Catalog Entries"]) { + if (child.isSuppressed && ![NSUserDefaults.standardUserDefaults boolForKey:@"Show All Catalog Entries"]) { #ifdef DEBUG if (DEBUG_CATALOG) NSLog(@"Suppressing Preset:%@", child.identifier); #endif - [self.children removeObjectAtIndex:i]; + return TRUE; } else if (child.isGroup) { - // Prune subgroup and remove it if empty [child pruneInvalidChildren]; - if (child.children.count == 0) { - [self.children removeObjectAtIndex:i]; - } + return child.children.count == 0; } - } + return NO; + }]; + [self.children removeObjectsAtIndexes:prunedChildren]; } - (NSArray *)leafIDs { From a1861bd327d4d4ad26a9c7b1e954ba8d16f727c0 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 19:43:42 +0200 Subject: [PATCH 34/51] More @synchronize. --- .../Code-QuickStepCore/QSCatalogEntry.m | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index fc6ce7afe..301365203 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -360,12 +360,14 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(B } - (NSString *)identifier { - NSString *ID = self.info[kItemID]; - if (!ID) { - ID = [NSString uniqueString]; - self.info[kItemID] = ID; - } - return ID; + @synchronized (self) { + NSString *ID = self.info[kItemID]; + if (!ID) { + ID = [NSString uniqueString]; + self.info[kItemID] = ID; + } + return ID; + } } - (NSIndexPath *)catalogIndexPath { @@ -592,14 +594,17 @@ - (BOOL)indexIsValid { } - (QSObjectSource *)source { - if (!_source) { - _source = [QSReg sourceNamed:self.info[kItemSource]]; + @synchronized (self) { + if (!_source) { + _source = [QSReg sourceNamed:self.info[kItemSource]]; #ifdef DEBUG - if (!_source && VERBOSE) - NSLog(@"Source not found: %@ for Entry: %@", self.info[kItemSource], self.identifier); + if (!_source && VERBOSE) + NSLog(@"Source not found: %@ for Entry: %@", self.info[kItemSource], self.identifier); #endif + } + return _source; + } - return _source; } - (NSArray *)scannedObjects { From a29c27efcfbd25855b3d877fdfa9753438318775 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 19:43:54 +0200 Subject: [PATCH 35/51] Style + duplicate method. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 301365203..bff8bb1e5 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -371,27 +371,19 @@ - (NSString *)identifier { } - (NSIndexPath *)catalogIndexPath { - NSArray *anc = [self ancestors]; + NSArray *anc = self.ancestors; NSUInteger i; NSUInteger index; NSIndexPath *p = nil; - for (i = 0; i < ([anc count] - 1); i++) { - index = [[[anc objectAtIndex:i] children] indexOfObject:[anc objectAtIndex:i+1]]; + for (i = 0; i < (anc.count - 1); i++) { + index = [[anc[i] children] indexOfObject:anc[i + 1]]; p = (p) ? [p indexPathByAddingIndex:index] : [NSIndexPath indexPathWithIndex:index]; } return p; } - (NSIndexPath *)catalogSetIndexPath { - NSArray *anc = [self ancestors]; - NSUInteger i; - NSUInteger index; - NSIndexPath *p = nil; - for (i = 1; i < ([anc count] - 1); i++) { - index = [[[anc objectAtIndex:i] children] indexOfObject:[anc objectAtIndex:i+1]]; - p = (p) ? [p indexPathByAddingIndex:index] : [NSIndexPath indexPathWithIndex:index]; - } - return p; + return self.catalogIndexPath; } - (NSArray *)ancestors { From d89f89d406db0a3f032b8a69978c9eadf92764dc Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 17 Sep 2013 21:19:55 +0200 Subject: [PATCH 36/51] Oops, that's `arrayWithContentsOfFile:`. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index bff8bb1e5..ddf132136 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -515,7 +515,7 @@ - (BOOL)loadIndex { if (self.isEnabled) { NSMutableArray *dictionaryArray = nil; @try { - dictionaryArray = [QSObject objectsWithDictionaryArray:@[self.indexLocation]]; + dictionaryArray = [QSObject objectsWithDictionaryArray:[NSMutableArray arrayWithContentsOfFile:self.indexLocation]]; } @catch (NSException *e) { NSLog(@"Error loading index of %@: %@", self.name , e); From 62c0f7d9d1c18a70d0fddd9d65a76bf1df2f73f0 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Fri, 20 Sep 2013 00:34:23 +0200 Subject: [PATCH 37/51] Unused. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index ddf132136..6bcee334c 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -27,7 +27,6 @@ @interface QSCatalogEntry () { NSImage *_icon; QSObjectSource *_source; - id parent; NSMutableArray *_children; dispatch_queue_t scanQueue; NSBundle *bundle; @@ -78,7 +77,6 @@ - (instancetype)init { _name = nil; _indexDate = nil; - parent = nil; _children = [NSMutableArray array]; _contents = nil; _info = [NSMutableDictionary dictionary]; From 4ce4a34059b6c8cb1edcc4c426b374c37eb47f7c Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 24 Sep 2013 19:34:03 +0200 Subject: [PATCH 38/51] Move QSMacros.h down to QSFoundation. --- Quicksilver/Code-QuickStepCore/QSCore.h | 1 - .../Code-QuickStepFoundation/QSFoundation.h | 1 + .../QSMacros.h | 0 .../Quicksilver.xcodeproj/project.pbxproj | 20 ++++++++++++++++--- 4 files changed, 18 insertions(+), 4 deletions(-) rename Quicksilver/{Code-QuickStepCore => Code-QuickStepFoundation}/QSMacros.h (100%) diff --git a/Quicksilver/Code-QuickStepCore/QSCore.h b/Quicksilver/Code-QuickStepCore/QSCore.h index 0972ff21a..b02292ced 100644 --- a/Quicksilver/Code-QuickStepCore/QSCore.h +++ b/Quicksilver/Code-QuickStepCore/QSCore.h @@ -30,7 +30,6 @@ #import "QSKeys.h" #import "QSLibrarian.h" #import "QSLocalization.h" -#import "QSMacros.h" #import "QSMiscFunctions.h" #import "QSMnemonics.h" #import "QSNotifications.h" diff --git a/Quicksilver/Code-QuickStepFoundation/QSFoundation.h b/Quicksilver/Code-QuickStepFoundation/QSFoundation.h index 2293bb062..78bdff6c3 100644 --- a/Quicksilver/Code-QuickStepFoundation/QSFoundation.h +++ b/Quicksilver/Code-QuickStepFoundation/QSFoundation.h @@ -23,6 +23,7 @@ #import "NTViewLocalizer.h" #import "NSString+NDCarbonUtilities.h" +#import "QSMacros.h" #import "QSGCD.h" #import "QSThreadSafeMutableDictionary.h" #import "QSUTI.h" diff --git a/Quicksilver/Code-QuickStepCore/QSMacros.h b/Quicksilver/Code-QuickStepFoundation/QSMacros.h similarity index 100% rename from Quicksilver/Code-QuickStepCore/QSMacros.h rename to Quicksilver/Code-QuickStepFoundation/QSMacros.h diff --git a/Quicksilver/Quicksilver.xcodeproj/project.pbxproj b/Quicksilver/Quicksilver.xcodeproj/project.pbxproj index c9bf277cb..25cf62e60 100644 --- a/Quicksilver/Quicksilver.xcodeproj/project.pbxproj +++ b/Quicksilver/Quicksilver.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ 4D66BC5E1487027E00351C42 /* NSURL+NDCarbonUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D66BBF21486FFF000351C42 /* NSURL+NDCarbonUtilities.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4D6A663410AB2A2F00898CA4 /* QSTreeController.h in Headers */ = {isa = PBXBuildFile; fileRef = 92D9C9680D134BDD00D91825 /* QSTreeController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4D6D369F17E61F93007017A6 /* QSCatalogEntry_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D6D369E17E61F93007017A6 /* QSCatalogEntry_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4D7B9FA117F2040300A91F64 /* QSMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F1F0EBDDBA9005A15AE /* QSMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4D7DF45416ADC7CA004BA4BE /* DefaultsMap.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4D7DF45316ADC7CA004BA4BE /* DefaultsMap.plist */; }; 4D7DF45716ADCDEF004BA4BE /* QSAdvancedPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D7DF45516ADCDEF004BA4BE /* QSAdvancedPrefPane.strings */; }; 4D89177514758620009C1C14 /* QSMainMenuPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D89177714758620009C1C14 /* QSMainMenuPrefPane.strings */; }; @@ -152,7 +153,6 @@ 4DD89F240EBDDBA9005A15AE /* QSDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F1B0EBDDBA9005A15AE /* QSDebug.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4DD89F250EBDDBA9005A15AE /* QSDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F1C0EBDDBA9005A15AE /* QSDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4DD89F270EBDDBA9005A15AE /* QSKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F1E0EBDDBA9005A15AE /* QSKeys.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4DD89F280EBDDBA9005A15AE /* QSMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F1F0EBDDBA9005A15AE /* QSMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4DD89F290EBDDBA9005A15AE /* QSNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F200EBDDBA9005A15AE /* QSNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4DD89F2A0EBDDBA9005A15AE /* QSPreferenceKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F210EBDDBA9005A15AE /* QSPreferenceKeys.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4DD89F2B0EBDDBA9005A15AE /* QSTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD89F220EBDDBA9005A15AE /* QSTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -3156,6 +3156,21 @@ CD4FA6E1157A13DE00E549BD /* QSHotKeyEvent.m */, CDCC200E10A4C14B009C4EED /* QSMDPredicate.h */, CDCC200F10A4C14B009C4EED /* QSMDPredicate.m */, + 92D9C9680D134BDD00D91825 /* QSTreeController.h */, + 92D9C9690D134BDD00D91825 /* QSTreeController.m */, + 7F0843CC098ACB2F00F136CC /* QSLog.h */, + 7F0843CD098ACB2F00F136CC /* QSLog.m */, + 7F93148B07E8B626009B3C06 /* NSIndexSet+Extensions.h */, + 7F943F6308033961007EDC31 /* QSUTI.h */, + 7F943F6408033961007EDC31 /* QSUTI.m */, + 4DD89F1F0EBDDBA9005A15AE /* QSMacros.h */, + 7FDF342307F7D60A00594789 /* NSSortDescriptor+BLTRExtensions.h */, + 7FDF342407F7D60A00594789 /* NSSortDescriptor+BLTRExtensions.m */, + 7F93148C07E8B627009B3C06 /* NSIndexSet+Extensions.m */, + 7FDF341607F7D59E00594789 /* NSDictionary+BLTRExtensions.h */, + 7FDF341707F7D59E00594789 /* NSDictionary+BLTRExtensions.m */, + 7FF8BB3607B816A20088CEEF /* NSTask+BLTRExtensions.h */, + 7FF8BB3707B816A20088CEEF /* NSTask+BLTRExtensions.m */, E1E5FA6E07B204BE0044D6EF /* NDAlias+QSMods.h */, E1E5FA6F07B204BE0044D6EF /* NDAlias+QSMods.m */, E1E5FA7007B204BE0044D6EF /* NDProcess+QSMods.h */, @@ -3289,7 +3304,6 @@ E1E5FB8607B20DD10044D6EF /* QSLibrarian.m */, E1E5FB8707B20DD10044D6EF /* QSLocalization.h */, E1E5FB8807B20DD10044D6EF /* QSLocalization.m */, - 4DD89F1F0EBDDBA9005A15AE /* QSMacros.h */, 929052F80D0FEAD600579DAE /* QSMiscFunctions.h */, 929052F90D0FEAD600579DAE /* QSMiscFunctions.m */, E1E5FB8D07B20DD20044D6EF /* QSMnemonics.h */, @@ -3572,7 +3586,6 @@ 4DD89F270EBDDBA9005A15AE /* QSKeys.h in Headers */, E1E5FBF207B20DD20044D6EF /* QSLibrarian.h in Headers */, E1E5FBF407B20DD20044D6EF /* QSLocalization.h in Headers */, - 4DD89F280EBDDBA9005A15AE /* QSMacros.h in Headers */, 929052FA0D0FEAD600579DAE /* QSMiscFunctions.h in Headers */, E1E5FBFA07B20DD20044D6EF /* QSMnemonics.h in Headers */, 4DD89F290EBDDBA9005A15AE /* QSNotifications.h in Headers */, @@ -3710,6 +3723,7 @@ CD14B79018D06604000FE86A /* QSThreadSafeMutableDictionary.h in Headers */, 2E34EDAA134C9F25005E66A1 /* QSLog.h in Headers */, 7FF447EA080479E200316DB6 /* QSLSTools.h in Headers */, + 4D7B9FA117F2040300A91F64 /* QSMacros.h in Headers */, CDCC201010A4C14B009C4EED /* QSMDPredicate.h in Headers */, 7F943F6508033961007EDC31 /* QSUTI.h in Headers */, 4D6A663410AB2A2F00898CA4 /* QSTreeController.h in Headers */, From 4a0bc55a1bdf7eabfb065d0237317f7d8f6365f2 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 24 Sep 2013 19:35:26 +0200 Subject: [PATCH 39/51] Remove some cruft. --- Quicksilver/Code-QuickStepFoundation/QSMacros.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Quicksilver/Code-QuickStepFoundation/QSMacros.h b/Quicksilver/Code-QuickStepFoundation/QSMacros.h index 236114be6..e13eb75ec 100644 --- a/Quicksilver/Code-QuickStepFoundation/QSMacros.h +++ b/Quicksilver/Code-QuickStepFoundation/QSMacros.h @@ -1,11 +1,3 @@ -#import - -//#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 -// #define foreach(x, y) id x; NSEnumerator *rwEnum = [y objectEnumerator]; while(x = [rwEnum nextObject]) -//#else -// // use fast enumeration on Mac OS X 10.5+ -// #define foreach(x, y) for (id (x) in (y)) -//#endif #define foreachkey(k, x, y) id x = nil; NSString *k = nil; NSEnumerator *kEnum = [y keyEnumerator]; while((k = [kEnum nextObject]) && (x = [y objectForKey:k]) ) #define defaultBool(x) [[NSUserDefaults standardUserDefaults] boolForKey:x] #define mOptionKeyIsDown (GetCurrentKeyModifiers() &optionKey) From a2ae7defa9b0df139288aae9c6650b2fe3e915c0 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 24 Sep 2013 19:35:40 +0200 Subject: [PATCH 40/51] Add QS_DEPRECATED as a macro. --- Quicksilver/Code-QuickStepFoundation/QSMacros.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Quicksilver/Code-QuickStepFoundation/QSMacros.h b/Quicksilver/Code-QuickStepFoundation/QSMacros.h index e13eb75ec..47dd75228 100644 --- a/Quicksilver/Code-QuickStepFoundation/QSMacros.h +++ b/Quicksilver/Code-QuickStepFoundation/QSMacros.h @@ -16,3 +16,6 @@ _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ Code; \ _Pragma("clang diagnostic pop") \ } while (0) + +#define QS_DEPRECATED __attribute__((deprecated)) + From 755f6d45bb380cfac624a1649500cc66a38b52ec Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Wed, 27 Nov 2013 23:04:58 +0100 Subject: [PATCH 41/51] Documentation + some implementation fixes. --- .../Code-QuickStepCore/QSCatalogEntry.h | 199 +++++++++++++++++- .../Code-QuickStepCore/QSCatalogEntry.m | 16 +- .../QSCatalogEntry_Private.h | 2 + 3 files changed, 201 insertions(+), 16 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 34f42cc7d..a96db8427 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -10,58 +10,241 @@ @class QSObjectSource; +/** + * QSCatalogEntry represent an entry in Quicksilver's catalog. + * + * It is built as tree of QSCatalogEntry, each having both `children` (more + * entries) and `contents` (as a list of `QSObject`s. + * It is also responsible for scanning its contents regularly, using one of the + * QSObjectSources provided by QS or a plugin. + */ @interface QSCatalogEntry : NSObject +//////////////////////////////////////////////////////////////////////////////// +/// @name Properties +//////////////////////////////////////////////////////////////////////////////// + +/** Is the receiver scanning ? */ @property (readonly, getter=isScanning) BOOL scanning; + +/** Is the receiver suppressed ? */ @property (readonly, getter=isSuppressed) BOOL suppressed; + +/** Is the receiver a default preset ? */ @property (readonly, getter=isPreset) BOOL preset; + +/** Is the receiver a separator ? */ @property (readonly, getter=isSeparator) BOOL separator; + +/** Is the receiver a group of more entries ? */ @property (readonly, getter=isGroup) BOOL group; + +/** Is the receiver modifiable ? */ @property (readonly, getter=isEditable) BOOL editable; + +/** Can the receiver be indexed ? */ @property (readonly, getter=canBeIndexed) BOOL indexable; +/** Is the receiver enabled ? */ @property (getter=isEnabled) BOOL enabled; +/** The receiver's displayable name. */ @property (copy) NSString *name; + +/** The receiver's icon. */ @property (retain) NSImage *icon; + +/** The receiver's identifier. */ @property (readonly, copy) NSString *identifier; + +/** The receiver's source. */ @property (readonly, retain) QSObjectSource *source; + +/** The receiver's last index date. */ @property (retain) NSDate *indexDate; +/** The contents of the receiver. */ @property (readonly, retain) NSArray *contents; + +/** The subentries of the receiver. */ @property (readonly, retain) NSMutableArray *children; +/** The settings for the receiver's object source. */ @property (readonly, retain) NSMutableDictionary *sourceSettings; +//////////////////////////////////////////////////////////////////////////////// +/// @name Lifetime +//////////////////////////////////////////////////////////////////////////////// + +/** + * Create a new instance of the receiver from a dictionary. + * + * @param dict A serialized entry as a dictionary. + * + * @see -[QSCatalogEntry initWithDictionary:]. + */ + (instancetype)entryWithDictionary:(NSDictionary *)dict; -- (NSDictionary *)dictionaryRepresentation; +/** + * Initialize the receiver from a dictionary. + * + * @param dict A dictionary containing + * + * @return A newly instantiated entry, or nil. + */ - (instancetype)initWithDictionary:(NSDictionary *)dict; + +/** + * Serialize the receiver to a dictionary. + * + * @warning This is an implementation detail. You should either use the + * receiver's properties, or the private info dictionary. + */ +- (NSDictionary *)dictionaryRepresentation; + +//////////////////////////////////////////////////////////////////////////////// +/// @name Basic methods +//////////////////////////////////////////////////////////////////////////////// + +/** + * Get the receiver's children with the given identifier. + * + * @param theID The identifier to lookup. + * + * @return An instance of QSCatalogEntry, or nil if there was no children with + * the given identifier. + */ - (instancetype)childWithID:(NSString *)theID; + +/** + * Get one of the receiver's children given an "identifier path". + * + * @param path A slash-separated string of entry identifiers. + * + * @return An instance of QSCatalogEntry, or nil if one of the identifiers in + * the path wasn't valid. + */ - (instancetype)childWithPath:(NSString *)path; +/** Make a new unique copy of the receiver */ - (instancetype)uniqueCopy; +/* + * The state the receiver is in. + * + * Depending on whether the receiver is a group or not, returns either its + * enabled state, or a negative number whose value represents the number of + * enabled leaf entries. + */ - (NSInteger)state; -- (NSInteger)hasEnabledChildren; + +/** Is any of receiver's children enabled ? */ +- (BOOL)hasEnabledChildren; + +/** + * Enable or disable the receiver and all its children + * + * @param enabled Whether to enable or disable the children. + */ - (void)setDeepEnabled:(BOOL)enabled; + +/** + * Prune all invalid children. + * + * If the receiver's a preset entry, this will recursively remove all children + * which have no contents. + */ - (void)pruneInvalidChildren; +/** + * Get the receiver's identifiers for its leaves. + * + * @return An array of all the enabled leaves's identifiers for the receiver. + */ - (NSArray *)leafIDs; + +/** + * Get the receiver's enabled leaves. + * + * @return An array of all the enabled leaves for the receiver. + */ - (NSArray *)leafEntries; + +/** + * Get the receiver's children. + * + * @param groups If YES, the resulting array will contain groups. + * @param leaves If YES, the resulting array will contain leaves. + * @param disabled If YES, the resulting array will contain disabled entries. + * + * @return An array of all the receiver's children matching the given options. + */ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled; + +/** + * Get the ancestors for the receiver. + * + * @return An array of the receiver's ancestor chain, starting with the root. + */ - (NSArray *)ancestors; -- (NSUInteger) deepObjectCount; + +/** Get the number of objects contained by the receiver and all its children. */ +- (NSUInteger)deepObjectCount; + +/** Same as deepObjectCount */ +- (NSUInteger)count; + +/** Returns whether the receiver is the root catalog entry. */ +- (BOOL)isCatalog; + +- (NSIndexPath *)catalogIndexPath; + +- (NSIndexPath *)catalogSetIndexPath; + +//////////////////////////////////////////////////////////////////////////////// +/// @name Indexing +//////////////////////////////////////////////////////////////////////////////// + +/** Load the receiver's index. */ - (BOOL)loadIndex; + +/** Save the receiver's index. */ - (void)saveIndex; + +/** Returns whether the index of the receiver is valid. */ - (BOOL)indexIsValid; -- (BOOL)isCatalog; + +//////////////////////////////////////////////////////////////////////////////// +/// @name Scanning +//////////////////////////////////////////////////////////////////////////////// + +/** + * Get the objects scanned by the receiver's object source. + * + * @warning This bypasses the index and the receiver's object cache. You should + * rarely need to call that method. + * + * @return An array of all object that the receiver's object source generated. + */ - (NSArray *)scannedObjects; + +/** + * Scan the receiver and refresh its cache. + * + * This queries the receiver's source for objects and refresh the index. + * + * @warning If the receiver's already being scanned, this *will* return nil. + * + * @return An array of all the objects generated by the object source. + */ - (NSArray *)scanAndCache; + +/** + * Scan the receiver. + * + * @param force If YES, the current index will be ignored. + */ - (void)scanForced:(BOOL)force; -- (NSArray *)contentsScanIfNeeded:(BOOL)canScan; -- (NSIndexPath *)catalogIndexPath; -- (NSUInteger)count; -- (NSIndexPath *)catalogSetIndexPath; +- (NSArray *)contentsScanIfNeeded:(BOOL)canScan; @end diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 6bcee334c..2ed909638 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -237,7 +237,7 @@ - (NSInteger)state { return enabled; } -- (NSInteger)hasEnabledChildren { +- (BOOL)hasEnabledChildren { if (self.isGroup) { BOOL hasEnabledChildren = NO; for (QSCatalogEntry *child in self.children) @@ -316,12 +316,12 @@ - (void)pruneInvalidChildren { - (NSArray *)leafIDs { if (!self.isEnabled) { - return nil; + return @[]; } if (self.isGroup) { NSMutableArray *childObjects = [NSMutableArray arrayWithCapacity:1]; - for(QSCatalogEntry *child in self.children) { + for (QSCatalogEntry *child in self.children) { [childObjects addObjectsFromArray:[child leafIDs]]; } return childObjects; @@ -335,8 +335,8 @@ - (NSArray *)leafEntries { } - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(BOOL)disabled { - if (!(disabled || self.isEnabled)) { - return nil; + if (!self.isEnabled && !disabled) { + return @[]; } if (self.isGroup) { @@ -350,11 +350,11 @@ - (NSArray *)deepChildrenWithGroups:(BOOL)groups leaves:(BOOL)leaves disabled:(B return childObjects; } - if (leaves) { - return @[self]; + if (!leaves) { + return @[]; } - return nil; + return @[self]; } - (NSString *)identifier { diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h index 5755ffd8f..fcc4e38a3 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry_Private.h @@ -13,7 +13,9 @@ * The receiver's private info dictionary * * This is considered private API (some other parts of QS access it directly). + * * It contains the following keys: + * * - kItemChildren - an array of QSCatalogEntry in dictionary format. * - @"requiresPath" - a path to a required "file-system object" * - @"requiresSettingsPath" - a BOOL indicating if the kItemPath in kItemSettings is required From 7f6e8dd3c6a0fb1d07c22c88629a41bb9ab5b4f8 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 28 Nov 2013 20:05:12 +0100 Subject: [PATCH 42/51] Make the entry's notifications real NSString, and change their name. --- Quicksilver/Code-App/QSCatalogPrefPane.m | 8 ++++---- Quicksilver/Code-App/QSSetupAssistant.m | 4 ++-- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 6 ++++++ Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 11 ++++++++--- Quicksilver/Code-QuickStepCore/QSHistoryController.m | 4 ++-- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 11 ++++++----- Quicksilver/Code-QuickStepCore/QSNotifications.h | 4 ---- .../QSCorePlugIn/Code/QSCatalogEntrySource.m | 2 +- .../QSCorePlugIn/Code/QSFileSystemObjectSource.m | 4 ++-- .../QSCorePlugIn/Code/QSUserDefinedProxySource.m | 2 +- 10 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Quicksilver/Code-App/QSCatalogPrefPane.m b/Quicksilver/Code-App/QSCatalogPrefPane.m index c4bd52d12..5590930f4 100644 --- a/Quicksilver/Code-App/QSCatalogPrefPane.m +++ b/Quicksilver/Code-App/QSCatalogPrefPane.m @@ -169,8 +169,8 @@ - (void)awakeFromNib { [[[itemContentsTable tableColumnWithIdentifier:kItemPath] dataCell] setFont:[NSFont labelFontOfSize:9]]; [[[itemContentsTable tableColumnWithIdentifier:kItemPath] dataCell] setWraps:NO]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogChanged:) name:QSCatalogEntryChanged object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogIndexed:) name:QSCatalogEntryIndexed object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogChanged:) name:QSCatalogEntryChangedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogIndexed:) name:QSCatalogEntryIndexedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateEntrySelection) name:NSOutlineViewSelectionDidChangeNotification object:nil]; [itemTable reloadData]; @@ -284,7 +284,7 @@ - (IBAction)addSource:(id)sender { [self showOptionsDrawer]; [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogStructureChanged object:nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:childEntry]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChangedNotification object:childEntry]; } - (IBAction)saveItem:(id)sender { @@ -574,7 +574,7 @@ - (BOOL)windowShouldClose:(id)sender { } - (IBAction)applySettings:(id)sender { - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChangedNotification object:nil]; [(QSController *)[NSApp delegate] rescanItems:sender]; } diff --git a/Quicksilver/Code-App/QSSetupAssistant.m b/Quicksilver/Code-App/QSSetupAssistant.m index b181729a7..6098f3cd1 100644 --- a/Quicksilver/Code-App/QSSetupAssistant.m +++ b/Quicksilver/Code-App/QSSetupAssistant.m @@ -78,7 +78,7 @@ - (void)windowDidLoad { // [setupTabView removeTabViewItem:[setupTabView tabViewItemAtIndex:[setupTabView indexOfTabViewItemWithIdentifier:@"network"]]]; //[setupTabView removeTabViewItem:[setupTabView tabViewItemAtIndex:[setupTabView indexOfTabViewItemWithIdentifier:@"features"]]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(installStatusChanged:) name:@"QSPlugInUpdatesFinished" object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogIndexed:) name:QSCatalogEntryIsIndexing object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogIndexed:) name:QSCatalogEntryIsIndexingNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(catalogIndexingFinished:) name:QSCatalogIndexingCompleted object:nil]; [[self window] setLevel:NSNormalWindowLevel]; @@ -145,7 +145,7 @@ - (void)catalogIndexingFinished:(id)notif { } } - (void)catalogIndexed:(NSNotification *)notif { - if ([[notif name] isEqualToString:QSCatalogEntryIsIndexing]) + if ([[notif name] isEqualToString:QSCatalogEntryIsIndexingNotification]) [scanStatusField setStringValue:[NSString stringWithFormat:@"Scanning %@", [(QSCatalogEntry *)[notif object] name]]]; } diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index a96db8427..215b0f93e 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -10,6 +10,12 @@ @class QSObjectSource; + +extern NSString *const QSCatalogEntryChangedNotification; +extern NSString *const QSCatalogEntryIsIndexingNotification; +extern NSString *const QSCatalogEntryIndexedNotification; +extern NSString *const QSCatalogEntryInvalidatedNotification; + /** * QSCatalogEntry represent an entry in Quicksilver's catalog. * diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 2ed909638..fc81ca3aa 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -21,6 +21,11 @@ #define kUseNSArchiveForIndexes NO; +NSString *const QSCatalogEntryChangedNotification = @"QSCatalogEntryChanged"; +NSString *const QSCatalogEntryIsIndexingNotification = @"QSCatalogEntryIsIndexing"; +NSString *const QSCatalogEntryIndexedNotification = @"QSCatalogEntryIndexed"; +NSString *const QSCatalogEntryInvalidatedNotification = @"QSCatalogEntryInvalidated"; + @interface QSCatalogEntry () { NSString *_name; NSArray *_contents; @@ -524,7 +529,7 @@ - (BOOL)loadIndex { } [self setContents:dictionaryArray]; - [NSNotificationCenter.defaultCenter postNotificationName:QSCatalogEntryIndexed object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:QSCatalogEntryIndexedNotification object:self]; [QSLibrarian.sharedInstance recalculateTypeArraysForItem:self]; } return YES; @@ -632,7 +637,7 @@ - (NSArray *)scanAndCache { [self willChangeValueForKey:@"self"]; NSString *ID = self.identifier; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc postNotificationName:QSCatalogEntryIsIndexing object:self]; + [nc postNotificationName:QSCatalogEntryIsIndexingNotification object:self]; itemContents = [self scannedObjects]; if (itemContents && ID) { self.contents = itemContents; @@ -643,7 +648,7 @@ - (NSArray *)scanAndCache { self.contents = nil; } [self didChangeValueForKey:@"self"]; - [nc postNotificationName:QSCatalogEntryIndexed object:self]; + [nc postNotificationName:QSCatalogEntryIndexedNotification object:self]; self.scanning = NO; }); return itemContents; diff --git a/Quicksilver/Code-QuickStepCore/QSHistoryController.m b/Quicksilver/Code-QuickStepCore/QSHistoryController.m index a5af36045..f363ee4d8 100644 --- a/Quicksilver/Code-QuickStepCore/QSHistoryController.m +++ b/Quicksilver/Code-QuickStepCore/QSHistoryController.m @@ -61,7 +61,7 @@ - (void)addCommand:(QSCommand *)command { [commandHistory removeLastObject]; } } - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryInvalidated object:@"QSPresetCommandHistory"]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryInvalidatedNotification object:@"QSPresetCommandHistory"]; } - (void)addObject:(id)object { @@ -72,7 +72,7 @@ - (void)addObject:(id)object { [objectHistory insertObject:object atIndex:0]; while ([objectHistory count] > MAXHIST) [objectHistory removeLastObject]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryInvalidated object:@"QSPresetObjectHistory"]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryInvalidatedNotification object:@"QSPresetObjectHistory"]; } @end diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index b6dc90468..e656daead 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -98,12 +98,12 @@ - (id)init { #endif // Register for Notifications - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(writeCatalog:) name:QSCatalogEntryChanged object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(writeCatalog:) name:QSCatalogEntryChangedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(writeCatalog:) name:QSCatalogStructureChanged object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadIDDictionary:) name:QSCatalogStructureChanged object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSets:) name:QSCatalogEntryIndexed object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSets:) name:QSCatalogEntryIndexedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSource:) name:QSCatalogSourceInvalidated object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadEntry:) name:QSCatalogEntryInvalidated object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadEntry:) name:QSCatalogEntryInvalidatedNotification object:nil]; #if 0 //Create proxy Images [(NSImage *)[[NSImage alloc] initWithSize:NSZeroSize] setName:@"QSDirectProxyImage"]; @@ -400,8 +400,9 @@ - (BOOL)loadCatalogArrays { NSLog(@"Indexes loaded (%fms) ", (-[date timeIntervalSinceNow] *1000)); #endif - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIndexed object:nil]; - if (invalidIndexes) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scanInvalidIndexes) name:NSApplicationDidFinishLaunchingNotification object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIndexedNotification object:catalog]; + if (invalidIndexes) + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scanInvalidIndexes) name:NSApplicationDidFinishLaunchingNotification object:nil]; return indexesValid; } diff --git a/Quicksilver/Code-QuickStepCore/QSNotifications.h b/Quicksilver/Code-QuickStepCore/QSNotifications.h index 7936ef42f..dfd840ecb 100644 --- a/Quicksilver/Code-QuickStepCore/QSNotifications.h +++ b/Quicksilver/Code-QuickStepCore/QSNotifications.h @@ -7,10 +7,6 @@ #define QSReleaseCaches @"QSReleaseCaches" #define QSCatalogStructureChanged @"QSCatalogStructureChanged" #define QSCatalogIndexingCompleted @"QSCatalogIndexingCompleted" -#define QSCatalogEntryChanged @"QSCatalogEntryChanged" -#define QSCatalogEntryIsIndexing @"QSCatalogEntryIsIndexing" -#define QSCatalogEntryIndexed @"QSCatalogEntryIndexed" -#define QSCatalogEntryInvalidated @"QSCatalogEntryInvalidated" #define QSCatalogSourceInvalidated @"QSCatalogSourceInvalidated" #define QSDebugLogRequest @"QSDebugLogRequest" diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m index e5816006e..8b04a6676 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSCatalogEntrySource.m @@ -175,7 +175,7 @@ - (QSObject *)addCatalogEntry:(QSObject *)dObject { [childEntry scanForced:YES]; [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogStructureChanged object:nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:childEntry]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChangedNotification object:childEntry]; [dObject setObject:uniqueString forType:QSCatalogEntryPboardType]; [self show:dObject]; diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m index 4d797a67e..25fe62113 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m @@ -271,7 +271,7 @@ - (IBAction)setValueForSender:(id)sender { [[self selection] scanAndCache]; [self populateFields]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:[self currentEntry]]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChangedNotification object:[self currentEntry]]; } - (BOOL)textShouldEndEditing:(NSText *)aTextObject { return YES; } @@ -375,7 +375,7 @@ - (BOOL)chooseFile { [self setValueForSender:itemLocationField]; [[self selection] setName:[[openPanel URL] lastPathComponent]]; [currentEntry setObject:[NSNumber numberWithDouble:[NSDate timeIntervalSinceReferenceDate]] forKey:kItemModificationDate]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:[self currentEntry]]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChangedNotification object:[self currentEntry]]; return YES; } diff --git a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSUserDefinedProxySource.m b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSUserDefinedProxySource.m index 88ab26dd6..7f25ae385 100644 --- a/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSUserDefinedProxySource.m +++ b/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSUserDefinedProxySource.m @@ -210,6 +210,6 @@ - (void)save [currentEntry setObject:[NSNumber numberWithFloat:[NSDate timeIntervalSinceReferenceDate]] forKey:kItemModificationDate]; [[self selection] scanAndCache]; [self populateFields]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChanged object:[self currentEntry]]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryChangedNotification object:[self currentEntry]]; } @end From 6023f91b71846cb5d207553487f237f4492b80b5 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 28 Nov 2013 20:08:01 +0100 Subject: [PATCH 43/51] Send the `isIndexing` notification when actually checking the index. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index fc81ca3aa..34573c056 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -564,7 +564,8 @@ - (void)invalidateIndex:(NSNotification *)notif { - (BOOL)indexIsValid { __block BOOL isValid = YES; - QSGCDQueueSync(scanQueue,^{ + QSGCDQueueSync(scanQueue, ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIsIndexingNotification object:self]; NSFileManager *manager = NSFileManager.defaultManager; NSString *indexLocation = self.indexLocation; if (![manager fileExistsAtPath:indexLocation isDirectory:nil]) { @@ -636,8 +637,6 @@ - (NSArray *)scanAndCache { self.scanning = YES; [self willChangeValueForKey:@"self"]; NSString *ID = self.identifier; - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc postNotificationName:QSCatalogEntryIsIndexingNotification object:self]; itemContents = [self scannedObjects]; if (itemContents && ID) { self.contents = itemContents; @@ -648,7 +647,7 @@ - (NSArray *)scanAndCache { self.contents = nil; } [self didChangeValueForKey:@"self"]; - [nc postNotificationName:QSCatalogEntryIndexedNotification object:self]; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIndexedNotification object:self]; self.scanning = NO; }); return itemContents; From d3d81164cf53209ab69f20887fbda19de1defdaf Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 28 Nov 2013 20:08:36 +0100 Subject: [PATCH 44/51] Make QSLibrarian responsible for its own task updating. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 3 --- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 34573c056..4298b8f68 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -667,7 +667,6 @@ - (void)scanForced:(BOOL)force { } return; } - [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Checking: %@", @"Catalog task checking (%@ => source name)"), self.name]]; BOOL valid = [self indexIsValid]; if (valid && !force) { #ifdef DEBUG @@ -681,9 +680,7 @@ - (void)scanForced:(BOOL)force { NSLog(@"Scanning source: %@%@", self.name , (force?@" (forced) ":@"")); #endif - [[[QSLibrarian sharedInstance] scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Scanning: %@", @"Catalog task scanning (%@ => source name)"), self.name]]; [self scanAndCache]; - return; } - (NSArray *)contents { diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index e656daead..343fa3586 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -104,6 +104,9 @@ - (id)init { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSets:) name:QSCatalogEntryIndexedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSource:) name:QSCatalogSourceInvalidated object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadEntry:) name:QSCatalogEntryInvalidatedNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateScanTask:) name:QSCatalogEntryIsIndexingNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateScanTask:) name:QSCatalogEntryIndexedNotification object:nil]; #if 0 //Create proxy Images [(NSImage *)[[NSImage alloc] initWithSize:NSZeroSize] setName:@"QSDirectProxyImage"]; @@ -325,6 +328,18 @@ - (void)reloadSets:(NSNotification *)notif { } } +- (void)updateScanTask:(NSNotification *)notif { + QSCatalogEntry *entry = [notif object]; + if (!entry) { + return; + } + if ([notif.name isEqualToString:QSCatalogEntryIsIndexingNotification]) { + [[self scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Checking: %@", @"Catalog task checking (%@ => source name)"), entry.name]]; + } else if ([notif.name isEqualToString:QSCatalogEntryIndexedNotification]) { + [[self scanTask] setStatus:[NSString stringWithFormat:NSLocalizedString(@"Scanning: %@", @"Catalog task scanning (%@ => source name)"), entry.name]]; + } +} + - (QSCatalogEntry *)entryForID:(NSString *)theID { QSCatalogEntry *entry = [entriesByID objectForKey:theID]; //if (!entry) From 8f9f5ef88cd33a64274a55fdd0de2484fb31d32c Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 28 Nov 2013 20:08:45 +0100 Subject: [PATCH 45/51] Whitespace. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 8 ++++---- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index 215b0f93e..ad703bb24 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -86,7 +86,7 @@ extern NSString *const QSCatalogEntryInvalidatedNotification; * Create a new instance of the receiver from a dictionary. * * @param dict A serialized entry as a dictionary. - * + * * @see -[QSCatalogEntry initWithDictionary:]. */ + (instancetype)entryWithDictionary:(NSDictionary *)dict; @@ -114,7 +114,7 @@ extern NSString *const QSCatalogEntryInvalidatedNotification; /** * Get the receiver's children with the given identifier. - * + * * @param theID The identifier to lookup. * * @return An instance of QSCatalogEntry, or nil if there was no children with @@ -226,10 +226,10 @@ extern NSString *const QSCatalogEntryInvalidatedNotification; /** * Get the objects scanned by the receiver's object source. - * + * * @warning This bypasses the index and the receiver's object cache. You should * rarely need to call that method. - * + * * @return An array of all object that the receiver's object source generated. */ - (NSArray *)scannedObjects; diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index 343fa3586..21ddf9d39 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -118,6 +118,7 @@ - (id)init { return self; } + - (void)enableEntries { [[catalog leafEntries] makeObjectsPerformSelector:@selector(enable)]; } @@ -426,8 +427,7 @@ - (void)scanCatalogWithDelay:(id)sender { } - (BOOL)scanInvalidIndexes { - for(QSCatalogEntry * entry in invalidIndexes) { - + for(QSCatalogEntry *entry in invalidIndexes) { NSLog(@"Forcing %@ to scan", entry); [entry scanForced:NO]; } From 81d808eadba5068df98b9a4054e4653a3ad65d7c Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 28 Nov 2013 20:35:33 +0100 Subject: [PATCH 46/51] Return a copy of the task's name to prevent someone from deallocating our ivar. --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 4298b8f68..6ee3381c6 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -435,14 +435,14 @@ - (NSString *)name { NSString *ID = self.identifier; _name = [bundle ? bundle : [NSBundle mainBundle] safeLocalizedStringForKey:ID value:ID table:@"QSCatalogPreset.name"]; } - return _name; + return [_name copy]; } } - (void)setName:(NSString *)newName { @synchronized (self) { - self.info[kItemName] = newName; - _name = newName; + _name = [newName copy]; + self.info[kItemName] = _name; } } From 79f65860a9c27b1b080b0a77e73bfcce2bd0e51e Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 28 Nov 2013 20:37:35 +0100 Subject: [PATCH 47/51] Return nil if self is nil. Because *somehow* some observation info would end up attached at the wrong object. --- Quicksilver/Code-QuickStepCore/QSTask.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSTask.m b/Quicksilver/Code-QuickStepCore/QSTask.m index dbcb43193..e9ae70971 100644 --- a/Quicksilver/Code-QuickStepCore/QSTask.m +++ b/Quicksilver/Code-QuickStepCore/QSTask.m @@ -75,9 +75,10 @@ - (id)init { } - (id)initWithIdentifier:(NSString *)newIdentifier { self = [super initWithNibName:@"QSTaskEntry" bundle:[NSBundle mainBundle]]; - if (self != nil) { - [self setIdentifier:newIdentifier]; - } + if (self == nil) return nil; + + [self setIdentifier:newIdentifier]; + return self; } From 59c0265071ea3b97ce606e7cba6299e55494b228 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 26 Oct 2014 01:26:12 +0200 Subject: [PATCH 48/51] Add a missing method to the public API --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h index ad703bb24..2562fdc6e 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.h @@ -207,6 +207,11 @@ extern NSString *const QSCatalogEntryInvalidatedNotification; - (NSIndexPath *)catalogSetIndexPath; +/** + * Get only the non-ommited objects from that entry and its children + */ +- (NSArray *)enabledContents; + //////////////////////////////////////////////////////////////////////////////// /// @name Indexing //////////////////////////////////////////////////////////////////////////////// From ce9b8be6f8d94b3f405313fe5bd2877c0f5e42be Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 26 Oct 2014 15:08:21 +0100 Subject: [PATCH 49/51] Rename `-deletable` method --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 6ee3381c6..7e7b50f3c 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -195,8 +195,7 @@ - (NSDate *)lastScanDate { return [[NSFileManager.defaultManager attributesOfItemAtPath:self.indexLocation error:NULL] objectForKey:NSFileModificationDate]; } -#warning should rename... -- (BOOL)deletable { +- (BOOL)canBeDeleted { if (self.isPreset) { return NO; } @@ -743,4 +742,8 @@ - (NSMutableDictionary *)sourceSettings { return self.info[kItemSettings]; } + +// Backward-compatibility +- (BOOL)deletable QS_DEPRECATED { return self.canBeDeleted; } + @end From 45ee9ab70b956cba5b601961690e6f4221a3edc9 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 26 Oct 2014 15:08:52 +0100 Subject: [PATCH 50/51] Send the notification *after* we complete scanning --- Quicksilver/Code-QuickStepCore/QSCatalogEntry.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m index 7e7b50f3c..be8e69f5a 100644 --- a/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m +++ b/Quicksilver/Code-QuickStepCore/QSCatalogEntry.m @@ -646,8 +646,8 @@ - (NSArray *)scanAndCache { self.contents = nil; } [self didChangeValueForKey:@"self"]; - [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIndexedNotification object:self]; self.scanning = NO; + [[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogEntryIndexedNotification object:self]; }); return itemContents; } From 11f17df69a55b89fd1f51568851a56470215dc79 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Sun, 26 Oct 2014 15:13:51 +0100 Subject: [PATCH 51/51] Force-scan invalidated entries --- Quicksilver/Code-QuickStepCore/QSLibrarian.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Quicksilver/Code-QuickStepCore/QSLibrarian.m b/Quicksilver/Code-QuickStepCore/QSLibrarian.m index 21ddf9d39..724fffd7d 100644 --- a/Quicksilver/Code-QuickStepCore/QSLibrarian.m +++ b/Quicksilver/Code-QuickStepCore/QSLibrarian.m @@ -297,7 +297,7 @@ - (void)reloadEntry:(NSNotification *)notif { QSCatalogEntry *entry = [self entryForID:[notif object]]; if (entry) { - [entry scanForced:NO]; + [entry scanForced:YES]; } }