Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catalog protocols #2250

Merged
merged 3 commits into from Aug 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 10 additions & 3 deletions Quicksilver/Code-App/QSCatalogPrefPane.m
Expand Up @@ -352,10 +352,17 @@ - (void)updateEntrySelection {
currentItemHasSettings = NO;
if ([source respondsToSelector:@selector(settingsView)])
currentItemHasSettings = nil != (settingsView = [source settingsView]);
if ([source respondsToSelector:@selector(setCurrentEntry:)])
[source setCurrentEntry:[currentItem info]];
if ([source respondsToSelector:@selector(setSelection:)])

// Make the object source edit the currently selected entry
// The various names are here because of back-compat
if ([source respondsToSelector:@selector(setSelectedEntry:)]) {
[source setSelectedEntry:currentItem];
} else if ([source respondsToSelector:@selector(setSelection:)]) {
[source setSelection:currentItem];
} else if ([source respondsToSelector:@selector(setCurrentEntry:)]) {
[source setCurrentEntry:[currentItem info]];
}

if ([source respondsToSelector:@selector(populateFields)])
[source populateFields];
if (settingsView) {
Expand Down
1 change: 1 addition & 0 deletions Quicksilver/Code-QuickStepCore/QSCore.h
Expand Up @@ -46,6 +46,7 @@
#import "QSObject_StringHandling.h"
#import "QSObject_URLHandling.h"
#import "QSObjectFormatter.h"
#import "QSObjectHandler.h"
#import "QSObjectRanker.h"
#import "QSObjectSource.h"
#import "QSParser.h"
Expand Down
2 changes: 1 addition & 1 deletion Quicksilver/Code-QuickStepCore/QSExecutor.m
Expand Up @@ -304,7 +304,7 @@ - (NSArray *)rankedActionsForDirectObject:(QSObject *)dObject indirectObject:(QS
}
NSArray *actions = nil;
if ([[dObject handler] respondsToSelector:@selector(actionsForDirectObject:indirectObject:)])
actions = (NSMutableArray *)[[dObject handler] actionsForDirectObject:dObject indirectObject:iObject];
actions = [[dObject handler] actionsForDirectObject:dObject indirectObject:iObject];

BOOL bypassValidation =
(bypass && [dObject isProxyObject] && [(QSProxyObject *)dObject bypassValidation]);
Expand Down
32 changes: 3 additions & 29 deletions Quicksilver/Code-QuickStepCore/QSObject.h
@@ -1,38 +1,12 @@
#import <Foundation/Foundation.h>

#import <QSCore/QSBasicObject.h>
#import <QSCore/QSObjectHandler.h>

@class QSObject, QSBasicObject;

extern NSSize QSMaxIconSize;

@interface NSObject (QSObjectHandlerInformalProtocol)
//@protocol QSObjectHandler <NSObject>
- (BOOL)objectHasChildren:(QSObject *)object;
- (BOOL)objectHasValidChildren:(QSObject *)object;

- (BOOL)loadChildrenForObject:(QSObject *)object;
- (NSArray *)childrenForObject:(QSObject *)object;
- (QSObject *)parentOfObject:(QSObject *)object;
- (NSString *)detailsOfObject:(QSObject *)object;
- (NSString *)identifierForObject:(QSObject *)object;
- (NSString *)kindOfObject:(QSObject *)object;
- (void)setQuickIconForObject:(QSObject *)object;
- (BOOL)loadIconForObject:(QSObject *)object;
- (BOOL)drawIconForObject:(QSObject *)object inRect:(NSRect)rect flipped:(BOOL)flipped;

- (id)dataForObject:(QSObject *)object pasteboardType:(NSString *)type;
- (NSDragOperation)operationForDrag:(id <NSDraggingInfo>)sender ontoObject:(QSObject *)dObject withObject:(QSBasicObject *)iObject;
- (NSString *)actionForDragMask:(NSDragOperation)operation ontoObject:(QSObject *)dObject withObject:(QSBasicObject *)iObject;

//- (NSArray *)actionsForDirectObject:(QSObject *)dObject indirectObject:(QSObject *)iObject;

- (NSAppleEventDescriptor *)AEDescriptorForObject:(QSObject *)object;

- (QSObject *)initFileObject:(QSObject *)object ofType:(NSString *)type QS_DEPRECATED NS_RETURNS_NOT_RETAINED;
@end


#define itemForKey(k) [data objectForKey:k]

// meta dictionary keys
Expand Down Expand Up @@ -120,8 +94,8 @@ typedef struct _QSObjectFlags {
- (NSUInteger) primaryCount;
- (NSArray *)types;
- (NSArray *)decodedTypes;
- (id)handler;
- (id)handlerForType:(NSString *)type selector:(SEL)selector;
- (id <QSObjectHandler>)handler;
- (id <QSObjectHandler>)handlerForType:(NSString *)type selector:(SEL)selector;
- (id)objectForType:(id)aKey;
- (void)setObject:(id)object forType:(id)aKey;
- (id)objectForCache:(id)aKey;
Expand Down
7 changes: 4 additions & 3 deletions Quicksilver/Code-QuickStepCore/QSObject.m
@@ -1,6 +1,7 @@
#import "QSObject.h"
#import "QSLibrarian.h"
#import "QSDebug.h"
#import "QSObjectHandler.h"

static NSMutableSet *iconLoadedSet;
static NSMutableSet *childLoadedSet;
Expand Down Expand Up @@ -295,7 +296,7 @@ - (NSString *)descriptionWithLocale:(NSDictionary *)locale indent:(NSUInteger)le
return [data descriptionWithLocale:locale indent:level];
}

- (id)handlerForType:(NSString *)type selector:(SEL)selector {
- (id <QSObjectHandler>)handlerForType:(NSString *)type selector:(SEL)selector {
id __block handler = [[QSReg objectHandlers] objectForKey:type];
if (!handler) {
[[QSReg objectHandlers] enumerateKeysAndObjectsUsingBlock:^(NSString *handlerType, id anyHandler, BOOL *stop) {
Expand All @@ -312,11 +313,11 @@ - (id)handlerForType:(NSString *)type selector:(SEL)selector {
return (selector == NULL ? handler : ([handler respondsToSelector:selector] ? handler : nil ));
}

- (id)handlerForSelector:(SEL)selector {
- (id <QSObjectHandler>)handlerForSelector:(SEL)selector {
return [self handlerForType:[self primaryType] selector:selector];
}

- (id)handler {
- (id <QSObjectHandler>)handler {
return [self handlerForType:[self primaryType] selector:nil];
}

Expand Down
37 changes: 37 additions & 0 deletions Quicksilver/Code-QuickStepCore/QSObjectHandler.h
@@ -0,0 +1,37 @@
//
// QSObjectHandler.h
// Quicksilver
//
// Created by Etienne on 22/07/2016.
//
//

@class QSObject, QSBasicObject;

@protocol QSObjectHandler <NSObject>
@optional
- (BOOL)objectHasChildren:(QSObject *)object;
- (BOOL)objectHasValidChildren:(QSObject *)object;

- (BOOL)loadChildrenForObject:(QSObject *)object;
- (NSArray *)childrenForObject:(QSObject *)object;
- (QSObject *)parentOfObject:(QSObject *)object;
- (NSString *)detailsOfObject:(QSObject *)object;
- (NSString *)identifierForObject:(QSObject *)object;
- (NSString *)kindOfObject:(QSObject *)object;
- (void)setQuickIconForObject:(QSObject *)object;
- (BOOL)loadIconForObject:(QSObject *)object;
- (BOOL)drawIconForObject:(QSObject *)object inRect:(NSRect)rect flipped:(BOOL)flipped;

- (id)dataForObject:(QSObject *)object pasteboardType:(NSString *)type;
- (NSDragOperation)operationForDrag:(id <NSDraggingInfo>)sender ontoObject:(QSObject *)dObject withObject:(QSBasicObject *)iObject;
- (NSString *)actionForDragMask:(NSDragOperation)operation ontoObject:(QSObject *)dObject withObject:(QSBasicObject *)iObject;

- (NSArray *)actionsForDirectObject:(QSObject *)dObject indirectObject:(QSObject *)iObject;

- (NSAppleEventDescriptor *)AEDescriptorForObject:(QSObject *)object;

- (QSObject *)initFileObject:(QSObject *)object ofType:(NSString *)type QS_DEPRECATED NS_RETURNS_NOT_RETAINED;
@end


104 changes: 79 additions & 25 deletions Quicksilver/Code-QuickStepCore/QSObjectSource.h
@@ -1,49 +1,103 @@


#import <Foundation/Foundation.h>
@interface NSObject (QSObjectSourceInformal)


@protocol QSObjectSource

/**
* Return the icon appropriate for the entry
*
* @param theEntry The entry whose icon should be returned.
*
* @return The image to use as icon.
*/
- (NSImage *)iconForEntry:(NSDictionary *)theEntry;
//- (NSString *)nameForEntry:(NSDictionary *)theEntry;

/**
* Return the objects scanned by the source
*
* @param theEntry The entry to be scanned.
*
* @return An array of QSObjects.
*/
- (NSArray *)objectsForEntry:(NSDictionary *)theEntry;

/**
* Check if an entry has changed before scanning
*
* @param indexDate The last indexation date.
* @param theEntry The entry currently being scanned.
*
* @return YES if the entries' contents should be refreshed, NO otherwise.
*/
- (BOOL)indexIsValidFromDate:(NSDate *)indexDate forEntry:(NSDictionary *)theEntry;
- (void)populateFields;
- (NSMutableDictionary *)currentEntry;
- (void)setCurrentEntry:(NSMutableDictionary *)newCurrentEntry;
- (NSView *)settingsView;
- (void)setSettingsView:(NSView *)newSettingsView;
- (BOOL)isVisibleSource;

@optional

/**
* Can the entry's contents be stored to disk
*
* @param theEntry The entry currently being considered for indexation.
*
* @return YES if saving the current contents of the entry makes sense (to speed up QS startup)
* NO if the entry's contents are something transient.
*/
- (BOOL)entryCanBeIndexed:(NSDictionary *)theEntry;

/**
* Informs the source that the entry was enabled
*/
- (void)enableEntry:(QSCatalogEntry *)entry;
/**
* Informs the source that the entry was disabled
*/
- (void)disableEntry:(QSCatalogEntry *)entry;

/**
* Can this object source be created by the user.
*
* @return YES to show the source in the Catalog's pref pane Add button
*/
- (BOOL)isVisibleSource;

/**
* Does the source stores its settings globally.
*
* @note Right now it's only used by the Process source, because it stores settings
* in the pref file.
*
* @return YES, if you care.
*/
- (BOOL)usesGlobalSettings;

@end

@class QSCatalogEntry;
@interface QSObjectSource : NSObject {
IBOutlet NSView *settingsView;
QSCatalogEntry *selection;
NSMutableDictionary *currentEntry;

@interface QSObjectSource : NSObject <QSObjectSource> {
/* The following is deprecated because it duplicates -selection.
* But it can't be removed because dyld will notice and plugins will fail to load
*/
NSMutableDictionary *currentEntry QS_DEPRECATED;
}

- (void)invalidateSelf;
- (NSImage *)iconForEntry:(NSDictionary *)theEntry;
//- (NSString *)nameForEntry:(NSDictionary *)theEntry;
- (NSArray *)objectsForEntry:(NSDictionary *)theEntry;
- (BOOL)indexIsValidFromDate:(NSDate *)indexDate forEntry:(NSDictionary *)theEntry;
- (void)populateFields;

- (void)updateCurrentEntryModificationDate;
- (NSMutableDictionary *)currentEntry;
//- (void)setCurrentEntry:(NSMutableDictionary *)newCurrentEntry;
- (NSView *)settingsView;
- (void)setSettingsView:(NSView *)newSettingsView;

- (QSCatalogEntry *)selection;
- (void)setSelection:(QSCatalogEntry *)newSelection;

@end
/* Catalog settings pane-related methods */
/* XXX: This would feel better in some NSViewController subclass ;-) */

- (void)populateFields;

@property (retain) QSCatalogEntry *selectedEntry;
@property (retain) IBOutlet NSView *settingsView;

// Please use -selectedEntry instead of those
// The rational being that between -currentEntry, -selection and direct Ivar
// everything can go wrong.
@property (retain) NSMutableDictionary *currentEntry QS_DEPRECATED;
@property (retain) QSCatalogEntry *selection QS_DEPRECATED;

@end
40 changes: 18 additions & 22 deletions Quicksilver/Code-QuickStepCore/QSObjectSource.m
Expand Up @@ -13,49 +13,45 @@ @implementation QSObjectSource

// KVO
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];

if ([key isEqualToString:@"currentEntry"]) {
keyPaths = [keyPaths setByAddingObject:@"selection"];
}
return keyPaths;
if ([key isEqualToString:@"currentEntry"]) {
keyPaths = [keyPaths setByAddingObject:@"selection"];
}
return keyPaths;
}

- (NSImage *)iconForEntry:(NSDictionary *)theEntry {return nil;}

- (NSString *)nameForEntry:(NSDictionary *)theEntry {return nil;}

- (NSArray *)objectsForEntry:(NSDictionary *)theEntry {return nil;}

- (void)invalidateSelf {
// NSLog(@"invalidated %@", self);
[[NSNotificationCenter defaultCenter] postNotificationName:QSCatalogSourceInvalidated object:NSStringFromClass([self class])];
}

- (BOOL)indexIsValidFromDate:(NSDate *)indexDate forEntry:(NSDictionary *)theEntry {
// NSDate *specDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[[theEntry objectForKey:kItemModificationDate] floatValue]];
// return ([specDate compare:indexDate] == NSOrderedDescending);
// //return NO; //Catalog Specification is more recent than index
// NSDate *specDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[[theEntry objectForKey:kItemModificationDate] floatValue]];
// return ([specDate compare:indexDate] == NSOrderedDescending);
// //return NO; //Catalog Specification is more recent than index
// ***warning * should switch to using this!
return NO;
}
- (void)populateFields {return;}

- (void)updateCurrentEntryModificationDate {
[currentEntry setObject:[NSNumber numberWithDouble:[NSDate timeIntervalSinceReferenceDate]] forKey:kItemModificationDate];
}

- (NSMutableDictionary *)currentEntry {
return [[self selection] info];
return self.selection.info;
}

- (QSCatalogEntry *)selection { return selection; }
- (void)setSelection:(QSCatalogEntry *)newSelection {
if(newSelection != selection){
selection = newSelection;
}
}
- (void)setCurrentEntry:(NSMutableDictionary *)currentEntry {}

- (NSView *)settingsView { return settingsView; }
- (void)setSettingsView:(NSView *)newSettingsView {
settingsView = newSettingsView;
- (void)updateCurrentEntryModificationDate {
self.selectedEntry.sourceSettings[kItemModificationDate] = @([NSDate timeIntervalSinceReferenceDate]);
}

- (QSCatalogEntry *)selection { return self.selectedEntry; }
- (void)setSelection:(QSCatalogEntry *)selection { self.selectedEntry = selection; }

@end
Expand Up @@ -161,7 +161,7 @@ - (IBAction)showTargetPicker:(id)sender
// Convert the sender (NSButton)'s rect to screen co-ords
NSRect relativeToWindow = [sender convertRect:[sender bounds] toView:nil];
// the position of the button on screen
NSRect targetRect = [settingsView.window convertRectToScreen:relativeToWindow];
NSRect targetRect = [self.settingsView.window convertRectToScreen:relativeToWindow];
[targetPickerWindow setFrame:targetRect display:YES];
[[targetPickerWindow searchObjView] setFrame:NSMakeRect(0, 0, targetRect.size.width, targetRect.size.height)];
[targetPickerWindow makeKeyAndOrderFront:self];
Expand Down
4 changes: 4 additions & 0 deletions Quicksilver/Quicksilver.xcodeproj/project.pbxproj
Expand Up @@ -132,6 +132,7 @@
4D7CDDB217E9154E00E54AB9 /* QSTaskController_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D7CDDB117E9154E00E54AB9 /* QSTaskController_Private.h */; };
4D7DF45416ADC7CA004BA4BE /* DefaultsMap.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4D7DF45316ADC7CA004BA4BE /* DefaultsMap.plist */; };
4D7DF45716ADCDEF004BA4BE /* QSAdvancedPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D7DF45516ADCDEF004BA4BE /* QSAdvancedPrefPane.strings */; };
4D8410DC1D428A1D004C3A6F /* QSObjectHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D8410DB1D428A1D004C3A6F /* QSObjectHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
4D89177514758620009C1C14 /* QSMainMenuPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D89177714758620009C1C14 /* QSMainMenuPrefPane.strings */; };
4D89177B14758DC6009C1C14 /* QSApplicationPrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D89177D14758DC6009C1C14 /* QSApplicationPrefPane.strings */; };
4D891783147595A5009C1C14 /* QSAppearancePrefPane.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D891785147595A5009C1C14 /* QSAppearancePrefPane.strings */; };
Expand Down Expand Up @@ -1144,6 +1145,7 @@
4D7DF45F16ADD6C0004BA4BE /* de */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/QSAdvancedPrefPane.strings; sourceTree = "<group>"; };
4D7DF46116ADD989004BA4BE /* es */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/QSAdvancedPrefPane.strings; sourceTree = "<group>"; };
4D7DF46316ADDAC2004BA4BE /* tr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/QSAdvancedPrefPane.strings; sourceTree = "<group>"; };
4D8410DB1D428A1D004C3A6F /* QSObjectHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QSObjectHandler.h; sourceTree = "<group>"; };
4D89177614758620009C1C14 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/QSMainMenuPrefPane.strings; sourceTree = "<group>"; };
4D89177814758641009C1C14 /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/QSMainMenuPrefPane.strings; sourceTree = "<group>"; };
4D89177C14758DC6009C1C14 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/QSApplicationPrefPane.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3406,6 +3408,7 @@
7FB37EB3080997EF00A2B2B4 /* QSURLDownloadWrapper.m */,
E1E5FBCC07B20DD20044D6EF /* QSVoyeur.h */,
E1E5FBCD07B20DD20044D6EF /* QSVoyeur.m */,
4D8410DB1D428A1D004C3A6F /* QSObjectHandler.h */,
);
path = "Code-QuickStepCore";
sourceTree = "<group>";
Expand Down Expand Up @@ -3608,6 +3611,7 @@
4DD89F270EBDDBA9005A15AE /* QSKeys.h in Headers */,
E1E5FBF207B20DD20044D6EF /* QSLibrarian.h in Headers */,
E1E5FBF407B20DD20044D6EF /* QSLocalization.h in Headers */,
4D8410DC1D428A1D004C3A6F /* QSObjectHandler.h in Headers */,
929052FA0D0FEAD600579DAE /* QSMiscFunctions.h in Headers */,
E1E5FBFA07B20DD20044D6EF /* QSMnemonics.h in Headers */,
4DD89F290EBDDBA9005A15AE /* QSNotifications.h in Headers */,
Expand Down