├── Sparkle.framework ├── Versions │ ├── Current │ └── A │ │ ├── Sparkle │ │ ├── Resources │ │ ├── en.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUProfileInfo.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── classes.nib │ │ │ │ └── info.nib │ │ ├── SUStatus.nib │ │ │ ├── keyedobjects.nib │ │ │ ├── classes.nib │ │ │ └── info.nib │ │ └── Info.plist │ │ └── Headers │ │ ├── NSApplication+AppCopies.h │ │ ├── NSFileManager+Authentication.h │ │ ├── NSFileManager+Verification.h │ │ ├── SUAutomaticUpdateAlert.h │ │ ├── SUAppcast.h │ │ ├── Sparkle.h │ │ ├── SUUnarchiver.h │ │ ├── SUUtilities.h │ │ ├── SUConstants.h │ │ ├── SUStatusChecker.h │ │ ├── SUUpdateAlert.h │ │ ├── SUStatusController.h │ │ ├── SUAppcastItem.h │ │ ├── NSString+extras.h │ │ ├── RSS.h │ │ └── SUUpdater.h ├── Headers ├── Resources └── Sparkle ├── README.md ├── emptyApp16x16.png ├── Localizable.strings ├── emptyApp16x16@2x.png ├── English.lproj ├── InfoPlist.strings ├── Localizable.strings ├── MainMenu.nib │ └── keyedobjects.nib └── Credits.rtf ├── OpaqueView.h ├── hidpiicon.iconset ├── icon_16x16.png ├── icon_32x32.png ├── icon_128x128.png ├── icon_16x16@2x.png ├── icon_256x256.png ├── icon_32x32@2x.png ├── icon_512x512.png ├── icon_128x128@2x.png ├── icon_256x256@2x.png └── icon_512x512@2x.png ├── ThisService Help.help └── Contents │ ├── Resources │ ├── shrd │ │ └── icon.png │ └── English.lproj │ │ ├── gfx │ │ ├── icon.png │ │ ├── __icon.png │ │ ├── icon@2x.png │ │ ├── iconSmall.png │ │ ├── orngbullet.gif │ │ ├── splashScreenshot.png │ │ ├── ___splashScreenshot.png │ │ └── splashScreenshot@2x.png │ │ ├── index.helpindex │ │ ├── css │ │ ├── genlist.html │ │ ├── genlist_style.css │ │ ├── accessPage.css │ │ ├── indexPage.css │ │ └── topicPage.css │ │ ├── index.html │ │ └── pages │ │ ├── index.html │ │ ├── sharingconsiderations.html │ │ ├── writingscripts.html │ │ ├── explainingservices.html │ │ ├── testservice.html │ │ ├── serviceprerequisites.html │ │ ├── sharingservices.html │ │ ├── writingscripts-applescript.html │ │ ├── writingscripts-specialbehavior-applescript.html │ │ └── creatingservices.html │ └── Info.plist ├── ThisService_Prefix.pch ├── ThisService.xcodeproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── .gitignore ├── TSLineBox.h ├── WFMachTime.h ├── TSModeCell.h ├── TSZip.h ├── main.m ├── NSWorkspace+SmallIcon.h ├── TSTableView.h ├── OpaqueView.m ├── version.plist ├── TSDelegatingDropZoneView.h ├── TSServiceAppFilter.h ├── TSStubbornImageView.h ├── NSBezierPath+AttributedStringExtensions.h ├── ServiceSkeleton ├── NSAppleScript+HandlerCalls.h ├── ServiceSkeletonMagic.h ├── NSAppleScript+HandlerCalls.m └── ServiceSkeleton_main.m ├── ShortcutRecorder ├── SRCommon.h └── SRCommon.m ├── TSExtraCollectionView.h ├── TSServiceAppFilter.m ├── NDSDKCompatibility.h ├── TSWindowController.h ├── TSViewController.h ├── TSModeMatrix.h ├── TSViewController.m ├── TSCheckedListDataSource.h ├── NSWorkspace+SmallIcon.m ├── TSServiceInputRules.h ├── TSStubbornImageView.m ├── dsa_pub.pem ├── ServiceSkeleton-Info.plist ├── TSPackUpViewController.h ├── TSServiceAppFilterWindowController.h ├── WFMachTime.m ├── NDResourceFork+OtherSorces.m ├── license.txt ├── NSString+CarbonFSRefCreation.h ├── TSTableView.m ├── NSBezierPath+AttributedStringExtensions.m ├── TSServiceTester.h ├── TSServiceTesting.h ├── TSModeMatrix.m ├── TSServiceInputRulesWindowController.h ├── TSExtraCollectionView.m ├── WFFilePicker.h ├── Info.plist ├── NDResourceFork+OtherSorces.h ├── TSDelegatingDropZoneView.m ├── NSString+CarbonFSRefCreation.m ├── TSService.h ├── TSServiceTestWindowController.h ├── TSCreateServiceViewController.h ├── NDAlias+AliasFile.h ├── TSCheckedListDataSource.m ├── NDAlias+AliasFile.m ├── TSZip.m ├── TSServiceInputRules.m ├── TSServiceTester.m └── NSURL+NDCarbonUtilities.m /Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | See [ThisService](http://wafflesoftware.net/thisservice/). -------------------------------------------------------------------------------- /emptyApp16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/emptyApp16x16.png -------------------------------------------------------------------------------- /Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Localizable.strings -------------------------------------------------------------------------------- /emptyApp16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/emptyApp16x16@2x.png -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /English.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/English.lproj/Localizable.strings -------------------------------------------------------------------------------- /OpaqueView.h: -------------------------------------------------------------------------------- 1 | /* OpaqueView */ 2 | 3 | #import 4 | 5 | @interface OpaqueView : NSView 6 | { 7 | } 8 | @end 9 | -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_16x16.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_32x32.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_128x128.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_256x256.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_512x512.png -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /hidpiicon.iconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/hidpiicon.iconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /English.lproj/MainMenu.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/English.lproj/MainMenu.nib/keyedobjects.nib -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/shrd/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/shrd/icon.png -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/icon.png -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/__icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/__icon.png -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/icon@2x.png -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/index.helpindex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/index.helpindex -------------------------------------------------------------------------------- /ThisService_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ThisService' target in the 'ThisService' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/iconSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/iconSmall.png -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/orngbullet.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/orngbullet.gif -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/splashScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/splashScreenshot.png -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUProfileInfo.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Sparkle.framework/Versions/A/Resources/en.lproj/SUProfileInfo.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/___splashScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/___splashScreenshot.png -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/gfx/splashScreenshot@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/ThisService Help.help/Contents/Resources/English.lproj/gfx/splashScreenshot@2x.png -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wafflesoftware/thisservice/HEAD/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /ThisService.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | -------------------------------------------------------------------------------- /TSLineBox.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSLineBox.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-23. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | 13 | @interface TSLineBox : NSBox 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WFMachTime.h: -------------------------------------------------------------------------------- 1 | // This class is written by Jesper and is placed in the public domain. 2 | 3 | #import 4 | 5 | @interface WFMachTime : NSObject { 6 | uint64_t startedTime; 7 | } 8 | + (WFMachTime *)currentTime; 9 | @property(readonly) NSTimeInterval intervalSinceStart; 10 | @end -------------------------------------------------------------------------------- /TSModeCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSModeTabView.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2007-08-03. 6 | // Copyright 2007-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @interface TSModeCell : NSButtonCell { 13 | } 14 | 15 | @end -------------------------------------------------------------------------------- /TSZip.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSZip.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2007-04-23. 6 | // Copyright 2007-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | 13 | @interface TSZip : NSObject 14 | + (NSData *)zip:(id)raw; 15 | @end 16 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/NSApplication+AppCopies.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSApplication+AppCopies.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSApplication (SUAppCopies) 12 | - (int)copiesRunning; 13 | @end 14 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2006-10-28. 6 | // Copyright 2006-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | return NSApplicationMain(argc, (const char **) argv); 15 | } 16 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/NSFileManager+Authentication.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+Authentication.m 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/9/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | @interface NSFileManager (SUAuthenticationAdditions) 10 | - (BOOL)movePathWithAuthentication:(NSString *)src toPath:(NSString *)dst; 11 | @end 12 | -------------------------------------------------------------------------------- /NSWorkspace+SmallIcon.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWorkspace+SmallIcon.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-01. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | 13 | @interface NSWorkspace (SmallIcon) 14 | - (NSImage *)smallIconForFileAtPath:(NSString *)path; 15 | @end 16 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | { 5 | CLASS = SUStatusController; 6 | LANGUAGE = ObjC; 7 | OUTLETS = {actionButton = id; }; 8 | SUPERCLASS = NSWindowController; 9 | } 10 | ); 11 | IBVersion = 1; 12 | } -------------------------------------------------------------------------------- /TSTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSTableView.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-15. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @interface NSObject (TSTableViewDelegate) 13 | - (void)deleteSelectedRows; 14 | @end 15 | 16 | @interface TSTableView : NSTableView { 17 | 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | { 5 | ACTIONS = {relaunchLater = id; relaunchNow = id; }; 6 | CLASS = SUAutomaticUpdateAlert; 7 | LANGUAGE = ObjC; 8 | SUPERCLASS = NSWindowController; 9 | } 10 | ); 11 | IBVersion = 1; 12 | } -------------------------------------------------------------------------------- /OpaqueView.m: -------------------------------------------------------------------------------- 1 | #import "OpaqueView.h" 2 | 3 | @implementation OpaqueView 4 | 5 | - (id)initWithFrame:(NSRect)frameRect 6 | { 7 | if ((self = [super initWithFrame:frameRect]) != nil) { 8 | // Add initialization code here 9 | } 10 | return self; 11 | } 12 | 13 | - (void)drawRect:(NSRect)rect 14 | { 15 | [[[self window] backgroundColor] setFill]; 16 | [NSBezierPath fillRect:rect]; 17 | } 18 | 19 | - (BOOL)isOpaque { 20 | return NO; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/NSFileManager+Verification.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+Verification.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // For the paranoid folks! 12 | @interface NSFileManager (SUVerification) 13 | - (BOOL)validatePath:(NSString *)path withMD5Hash:(NSString *)hash; 14 | - (BOOL)validatePath:(NSString *)path withEncodedDSASignature:(NSString *)encodedSignature; 15 | @end 16 | -------------------------------------------------------------------------------- /version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 92 7 | CFBundleVersion 8 | 1.0 9 | ProductBuildVersion 10 | 7K571 11 | ProjectName 12 | NibPBTemplates 13 | SourceVersion 14 | 1200000 15 | 16 | 17 | -------------------------------------------------------------------------------- /TSDelegatingDropZoneView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSDelegatingDropZoneView.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-25. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | 13 | @interface TSDelegatingDropZoneView : NSView { 14 | BOOL drophovering; 15 | NSView *draggingDestination; 16 | } 17 | - (void)setDraggingDestination:(NSView *)draggingDestination; 18 | - (NSView *)draggingDestination; 19 | @end 20 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAutomaticUpdateAlert.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAutomaticUpdateAlert.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/18/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SUAppcastItem; 12 | @interface SUAutomaticUpdateAlert : NSWindowController { 13 | SUAppcastItem *updateItem; 14 | } 15 | 16 | - initWithAppcastItem:(SUAppcastItem *)item; 17 | 18 | - (IBAction)relaunchNow:sender; 19 | - (IBAction)relaunchLater:sender; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /TSServiceAppFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceAppFilter.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-01. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | 13 | @interface TSServiceAppFilter : NSObject { 14 | @private 15 | NSSet *_applicationIdentifiers; 16 | } 17 | @property (readonly, copy) NSSet *applicationIdentifiers; 18 | + (id)appFilterWithApplicationIdentifiers:(NSSet *)applicationIdentifiers; 19 | @end 20 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 69 10 356 240 0 0 1280 832 7 | IBFramework Version 8 | 446.1 9 | IBOpenObjects 10 | 11 | 5 12 | 13 | IBSystem Version 14 | 8L127 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 425 40 356 240 0 0 1280 832 7 | IBFramework Version 8 | 446.1 9 | IBOpenObjects 10 | 11 | 5 12 | 13 | IBSystem Version 14 | 8I127 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 188 142 356 240 0 0 1280 1002 7 | IBFramework Version 8 | 443.0 9 | IBOpenObjects 10 | 11 | 5 12 | 13 | IBSystem Version 14 | 8H14 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RSS, SUAppcastItem; 12 | @interface SUAppcast : NSObject { 13 | NSArray *items; 14 | id delegate; 15 | } 16 | 17 | - (void)fetchAppcastFromURL:(NSURL *)url; 18 | - (void)setDelegate:delegate; 19 | 20 | - (SUAppcastItem *)newestItem; 21 | - (NSArray *)items; 22 | 23 | @end 24 | 25 | @interface NSObject (SUAppcastDelegate) 26 | - appcastDidFinishLoading:(SUAppcast *)appcast; 27 | @end -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import "SUUpdater.h" 10 | #import "SUUtilities.h" 11 | #import "SUConstants.h" 12 | #import "SUAppcast.h" 13 | #import "SUAppcastItem.h" 14 | #import "SUUpdateAlert.h" 15 | #import "SUAutomaticUpdateAlert.h" 16 | #import "SUStatusController.h" 17 | #import "SUUnarchiver.h" 18 | #import "SUStatusChecker.h" 19 | 20 | #import "NSApplication+AppCopies.h" 21 | #import "NSFileManager+Authentication.h" 22 | #import "NSFileManager+Verification.h" 23 | -------------------------------------------------------------------------------- /TSStubbornImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSStubbornImageView.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-13. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class TSStubbornImageView; 13 | 14 | @protocol TSStubbornImageViewDelegate 15 | - (void)stubbornImageView:(TSStubbornImageView *)imageView changedImage:(NSImage *)image isStubbornDefault:(BOOL)isDefault; 16 | @end 17 | 18 | 19 | @interface TSStubbornImageView : NSImageView { 20 | IBOutlet id delegate; 21 | } 22 | - (BOOL)isStubbornDefault; 23 | @end 24 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface SUUnarchiver : NSObject { 13 | id delegate; 14 | } 15 | 16 | - (void)unarchivePath:(NSString *)path; 17 | - (void)setDelegate:delegate; 18 | 19 | @end 20 | 21 | @interface NSObject (SUUnarchiverDelegate) 22 | - (void)unarchiver:(SUUnarchiver *)unarchiver extractedLength:(long)length; 23 | - (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver; 24 | - (void)unarchiverDidFail:(SUUnarchiver *)unarchiver; 25 | @end 26 | -------------------------------------------------------------------------------- /NSBezierPath+AttributedStringExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBezierPath+AttributedStringExtensions.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-24. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | #import 13 | 14 | // Adapted from http://amber-framework.googlecode.com/ under the same license. 15 | 16 | @interface NSBezierPath (AttributedStringExtensions) 17 | + (NSBezierPath *)bezierPathWithString:(NSString *)text inFont:(NSFont *)font; 18 | - (void)appendBezierPathWithString:(NSString *)text inFont:(NSFont *)font; 19 | @end 20 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUProfileInfo.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 34 318 356 240 0 0 1280 1002 7 | IBEditorPositions 8 | 9 | 39 10 | 433 534 418 267 0 0 1280 1002 11 | 12 | IBFramework Version 13 | 446.1 14 | IBOpenObjects 15 | 16 | 39 17 | 5 18 | 19 | IBSystem Version 20 | 8I1119 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUProfileInfo.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | {CLASS = NSObject; LANGUAGE = ObjC; }, 5 | { 6 | ACTIONS = {checkForUpdates = id; closeProfileInfoSheet = id; }; 7 | CLASS = SUUpdater; 8 | LANGUAGE = ObjC; 9 | OUTLETS = { 10 | checkForUpdatesText = NSTextField; 11 | delegate = id; 12 | profileMoreInfoButton = NSButton; 13 | profileMoreInfoView = NSView; 14 | profileMoreInfoWindow = NSWindow; 15 | }; 16 | SUPERCLASS = NSObject; 17 | } 18 | ); 19 | IBVersion = 1; 20 | } -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUtilities.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | id SUInfoValueForKey(NSString *key); 12 | id SUUnlocalizedInfoValueForKey(NSString *key); 13 | NSString *SUHostAppName(); 14 | NSString *SUHostAppDisplayName(); 15 | NSString *SUHostAppVersion(); 16 | NSString *SUHostAppVersionString(); 17 | NSString *SUCurrentSystemVersionString(); 18 | 19 | NSComparisonResult SUStandardVersionComparison(NSString * versionA, NSString * versionB); 20 | 21 | // If running make localizable-strings for genstrings, ignore the error on this line. 22 | NSString *SULocalizedString(NSString *key, NSString *comment); 23 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | Sparkle 9 | CFBundleIdentifier 10 | com.example.sparkeplus 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Sparkle 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ServiceSkeleton/NSAppleScript+HandlerCalls.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | NSAppleScript+HandlerCalls.h 4 | ASHandlerTest 5 | by Buzz Andersen 6 | 7 | More information at: http://www.scifihifi.com/weblog/mac/Cocoa-AppleEvent-Handlers.html 8 | 9 | This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit 10 | 11 | http://creativecommons.org/licenses/by/1.0/ 12 | 13 | or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, 14 | California 94305, USA. 15 | 16 | */ 17 | 18 | #import 19 | 20 | @interface NSAppleScript (HandlerCalls) 21 | 22 | - (NSAppleEventDescriptor *)callHandler:(NSString *)handler 23 | withArguments:(NSAppleEventDescriptor *)arguments 24 | errorInfo:(out NSDictionary **)errorInfo; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /ShortcutRecorder/SRCommon.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRCommon.h (selected, extracted parts) 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors (of these parts): 10 | // Jesper 11 | 12 | #import 13 | 14 | // Image macros, for use in any bundle 15 | //#define SRImage(name) [[[NSImage alloc] initWithContentsOfFile: [[NSBundle bundleForClass: [self class]] pathForImageResource: name]] autorelease] 16 | #define SRResIndImage(name) [SRSharedImageProvider supportingImageWithName:name] 17 | #define SRImage(name) SRResIndImage(name) 18 | 19 | #pragma mark - 20 | #pragma mark Image provider 21 | 22 | @interface SRSharedImageProvider : NSObject 23 | + (NSImage *)supportingImageWithName:(NSString *)name; 24 | @end 25 | -------------------------------------------------------------------------------- /TSExtraCollectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSExtraCollectionView.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-09. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | 13 | @interface TSExtraCollectionView : NSCollectionView { 14 | NSMutableDictionary *views; 15 | id whenRemovedTarget; 16 | SEL whenRemovedAction; 17 | } 18 | - (void)registerView:(NSView *)view forIdentifier:(NSString *)identifier; 19 | - (void)registerWhenRemovedTarget:(id)target action:(SEL)action; 20 | @end 21 | 22 | 23 | @interface TSExtraCollectionItemView : NSView { 24 | NSCollectionViewItem *_item; 25 | } 26 | @property (assign) NSCollectionViewItem *item; 27 | - (IBAction)removeItem:(id)sender; 28 | @end -------------------------------------------------------------------------------- /TSServiceAppFilter.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceAppFilter.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-01. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import "TSServiceAppFilter.h" 12 | 13 | @implementation TSServiceAppFilter 14 | @synthesize applicationIdentifiers=_applicationIdentifiers; 15 | 16 | - (id)initWithApplicationIdentifiers:(NSSet *)applicationIdentifiers 17 | { 18 | self = [super init]; 19 | if (self) { 20 | _applicationIdentifiers = [applicationIdentifiers copy]; 21 | } 22 | return self; 23 | } 24 | 25 | +(id)appFilterWithApplicationIdentifiers:(NSSet *)applicationIdentifiers { 26 | return [[[self alloc] initWithApplicationIdentifiers:applicationIdentifiers] autorelease]; 27 | } 28 | 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /NDSDKCompatibility.h: -------------------------------------------------------------------------------- 1 | /* 2 | NDSDKCompatibility.h 3 | 4 | Created by Nick Zitzmann on 2007-10-22. 5 | 6 | 7 | NDAlias uses types that were introduced with the 10.5 SDK. 8 | This allows older SDKs to be used. 9 | */ 10 | 11 | #import 12 | 13 | #ifndef NSINTEGER_DEFINED 14 | #ifdef NS_BUILD_32_LIKE_64 15 | typedef long NSInteger; 16 | typedef unsigned long NSUInteger; 17 | #else 18 | typedef int NSInteger; 19 | typedef unsigned int NSUInteger; 20 | #endif 21 | #define NSIntegerMax LONG_MAX 22 | #define NSIntegerMin LONG_MIN 23 | #define NSUIntegerMax ULONG_MAX 24 | #define NSINTEGER_DEFINED 1 25 | #endif 26 | 27 | #ifndef CGFLOAT_DEFINED 28 | typedef float CGFloat; 29 | #define CGFLOAT_MIN FLT_MIN 30 | #define CGFLOAT_MAX FLT_MAX 31 | #define CGFLOAT_IS_DOUBLE 0 32 | #define CGFLOAT_DEFINED 1 33 | #endif 34 | -------------------------------------------------------------------------------- /TSWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSWindowController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-11. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | #import "TSModeMatrix.h" 13 | #import "TSViewController.h" 14 | 15 | @interface TSWindowController : NSWindowController { 16 | NSArray *viewControllers; 17 | IBOutlet TSModeMatrix *modeMatrix; 18 | IBOutlet NSView *subviewView; 19 | 20 | NSViewAnimation *currentAnimation; 21 | } 22 | 23 | - (IBAction)showPackUp:(id)sender; 24 | - (IBAction)showCreateService:(id)sender; 25 | 26 | @end 27 | 28 | @interface TSViewController () 29 | - (void)viewWillAppearInContainer:(id)c; 30 | @end -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUConstants.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | // $Id: SUConstants.h 56 2006-07-29 21:49:55Z atomicbird $ 9 | // $HeadURL: http://sparkleplus.googlecode.com/svn/trunk/SUConstants.h $ 10 | 11 | extern NSString *SUUpdaterWillRestartNotification; 12 | 13 | extern NSString *SUCheckAtStartupKey; 14 | extern NSString *SUSendProfileInfoKey; 15 | extern NSString *SUFeedURLKey; 16 | extern NSString *SUShowReleaseNotesKey; 17 | extern NSString *SUSkippedVersionKey; 18 | extern NSString *SUScheduledCheckIntervalKey; 19 | extern NSString *SULastCheckTimeKey; 20 | extern NSString *SUExpectsDSASignatureKey; 21 | extern NSString *SUPublicDSAKeyKey; 22 | extern NSString *SUAutomaticallyUpdateKey; 23 | extern NSString *SUAllowsAutomaticUpdatesKey; 24 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | {CLASS = NSObject; LANGUAGE = ObjC; }, 5 | { 6 | ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; }; 7 | CLASS = SUUpdateAlert; 8 | LANGUAGE = ObjC; 9 | OUTLETS = {description = NSTextField; releaseNotesView = WebView; }; 10 | SUPERCLASS = NSWindowController; 11 | }, 12 | { 13 | ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; }; 14 | CLASS = SUUpdateAlertController; 15 | LANGUAGE = ObjC; 16 | OUTLETS = {releaseNotesView = id; }; 17 | SUPERCLASS = NSWindowController; 18 | } 19 | ); 20 | IBVersion = 1; 21 | } -------------------------------------------------------------------------------- /TSViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSViewController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-11. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class TSViewController; 13 | 14 | @protocol TSViewControllerContainer 15 | - (void)resizeViewController:(TSViewController *)vc toNewContentSize:(NSSize)size animate:(BOOL)animate; 16 | @end 17 | 18 | @interface TSViewController : NSViewController { 19 | @private 20 | id _currentContainer; 21 | } 22 | @property (assign, readonly) id container; 23 | - (void)viewWillAppear; 24 | - (void)viewWillDisappear; 25 | - (BOOL)shouldSwitchToViewController:(TSViewController *)otherViewController; 26 | - (BOOL)shouldOpenFileAtPath:(NSString *)filePath; 27 | @end 28 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUStatusChecker.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStatusChecker.h 3 | // Sparkle 4 | // 5 | // Created by Evan Schoenberg on 7/6/06. 6 | // 7 | 8 | #import 9 | #import "SUUpdater.h" 10 | 11 | @class SUStatusChecker; 12 | 13 | @protocol SUStatusCheckerDelegate 14 | //versionString will be nil and isNewVersion will be NO if version checking fails. 15 | - (void)statusChecker:(SUStatusChecker *)statusChecker foundVersion:(NSString *)versionString isNewVersion:(BOOL)isNewVersion; 16 | @end 17 | 18 | @interface SUStatusChecker : SUUpdater { 19 | id scDelegate; 20 | } 21 | 22 | // Create a status checker which will notifiy delegate once the appcast version is determined. 23 | // Notification occurs via the method defined in the SUStatusCheckerDelegate informal protocol. 24 | + (SUStatusChecker *)statusCheckerForDelegate:(id)delegate; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TSModeMatrix.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSModeMatrix.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2007-08-04. 6 | // Copyright 2007-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class TSModeMatrix; 13 | 14 | @protocol TSModeMatrixDelegate 15 | - (BOOL)modeMatrix:(TSModeMatrix *)matrix shouldSwitchFromTag:(NSInteger)previousTag toTag:(NSInteger)newTag; 16 | - (void)modeMatrix:(TSModeMatrix *)matrix switchFromTag:(NSInteger)previousTag toTag:(NSInteger)newTag animate:(BOOL)animate; 17 | @end 18 | 19 | @interface TSModeMatrix : NSMatrix { 20 | double baseHeight; 21 | double bottomHeight; 22 | NSInteger lastTag; 23 | BOOL contentHasInitialized; 24 | 25 | BOOL animationIsBlocked; 26 | } 27 | - (IBAction)selectMe:(id)sender; 28 | - (void)goToTag:(int)tag; 29 | - (void)reconfigureWithAnimation:(BOOL)anim; 30 | - (id)delegate; 31 | - (void)setContentInitialized; 32 | @end 33 | 34 | -------------------------------------------------------------------------------- /TSViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSViewController.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-11. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSViewController.h" 11 | #import "TSWindowController.h" 12 | 13 | @implementation TSViewController 14 | - (id)container { 15 | return _currentContainer; 16 | } 17 | 18 | - (BOOL)shouldSwitchToViewController:(TSViewController *)otherViewController { 19 | return YES; 20 | } 21 | 22 | - (BOOL)shouldOpenFileAtPath:(NSString *)filePath { 23 | return NO; 24 | } 25 | 26 | - (void)viewWillAppearInContainer:(id)c { 27 | // NSLog(@"%@ will appear in container %@", self, c); 28 | _currentContainer = c; 29 | [self viewWillAppear]; 30 | } 31 | 32 | - (void)viewWillAppear { 33 | 34 | } 35 | 36 | - (void)viewWillDisappear { 37 | // NSLog(@"%@ will disappear from container %@", self, _currentContainer); 38 | _currentContainer = nil; 39 | } 40 | @end 41 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUUpdateAlert.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdateAlert.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum 12 | { 13 | SUInstallUpdateChoice, 14 | SURemindMeLaterChoice, 15 | SUSkipThisVersionChoice 16 | } SUUpdateAlertChoice; 17 | 18 | @class WebView, SUAppcastItem; 19 | @interface SUUpdateAlert : NSWindowController { 20 | SUAppcastItem *updateItem; 21 | id delegate; 22 | 23 | IBOutlet WebView *releaseNotesView; 24 | IBOutlet NSTextField *description; 25 | NSProgressIndicator *releaseNotesSpinner; 26 | BOOL webViewFinishedLoading; 27 | } 28 | 29 | - initWithAppcastItem:(SUAppcastItem *)item; 30 | - (void)setDelegate:delegate; 31 | 32 | - (IBAction)installUpdate:sender; 33 | - (IBAction)skipThisVersion:sender; 34 | - (IBAction)remindMeLater:sender; 35 | 36 | @end 37 | 38 | @interface NSObject (SUUpdateAlertDelegate) 39 | - (void)updateAlert:(SUUpdateAlert *)updateAlert finishedWithChoice:(SUUpdateAlertChoice)updateChoice; 40 | @end 41 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en_US 7 | CFBundleIdentifier 8 | net.wafflesoftware.ThisService.help 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ThisService Help 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1 17 | CFBundleSignature 18 | hbwr 19 | CFBundleVersion 20 | 120729020308 21 | HPDBookAccessPath 22 | index.html 23 | HPDBookIconPath 24 | shrd/icon.png 25 | HPDBookIndexPath 26 | index.helpindex 27 | HPDBookTitle 28 | ThisService Help 29 | HPDBookType 30 | 3 31 | 32 | 33 | -------------------------------------------------------------------------------- /TSCheckedListDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSCheckedListDataSource.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-14. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class TSCheckedListDataSource; 13 | 14 | @protocol TSCheckedListDataSourceDelegate 15 | - (void)dataSource:(TSCheckedListDataSource *)dataSource checkedChoicesChanged:(NSArray *)selectedChoices; 16 | @end 17 | 18 | 19 | @interface TSCheckedListDataSource : NSObject { 20 | NSArray *rowData; 21 | NSMutableIndexSet *selectedIndexes; 22 | NSString *labelKey; 23 | id delegate; 24 | } 25 | - (id)initWithRowData:(NSArray *)rowData selectedChoices:(NSIndexSet *)selectedIndexes labelKey:(NSString *)labelKey delegate:(id)delegate; 26 | - (NSArray *)selectedChoices; 27 | - (NSArray *)selectedChoiceValues; 28 | - (BOOL)anyChoicesSelected; 29 | 30 | + (NSIndexSet *)indexSetOfSelectedIndexesForRowData:(NSArray *)rowData selectedValues:(NSSet *)values; 31 | @end 32 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/css/genlist.html: -------------------------------------------------------------------------------- 1 | AppleTopicListOther

AppleTopicListOther

Click a topic below.

AppleTopicListItemTitle

-------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUStatusController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStatusController.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/14/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface SUStatusController : NSWindowController { 13 | double progressValue, maxProgressValue; 14 | NSString *title, *statusText, *buttonTitle; 15 | IBOutlet NSButton *actionButton; 16 | } 17 | 18 | // Pass 0 for the max progress value to get an indeterminate progress bar. 19 | // Pass nil for the status text to not show it. 20 | - (void)beginActionWithTitle:(NSString *)title maxProgressValue:(double)maxProgressValue statusText:(NSString *)statusText; 21 | 22 | // If isDefault is YES, the button's key equivalent will be \r. 23 | - (void)setButtonTitle:(NSString *)buttonTitle target:target action:(SEL)action isDefault:(BOOL)isDefault; 24 | - (void)setButtonEnabled:(BOOL)enabled; 25 | 26 | - (double)progressValue; 27 | - (void)setProgressValue:(double)value; 28 | - (double)maxProgressValue; 29 | - (void)setMaxProgressValue:(double)value; 30 | 31 | - (void)setStatusText:(NSString *)statusText; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /NSWorkspace+SmallIcon.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSWorkspace+SmallIcon.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-01. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import "NSWorkspace+SmallIcon.h" 12 | 13 | @implementation NSWorkspace (SmallIcon) 14 | - (NSImage *)smallIconForFileAtPath:(NSString *)path { 15 | NSImage *icon = [[self iconForFile:path] copy]; 16 | NSSize s16x16 = NSMakeSize(16, 16); 17 | [icon setSize:s16x16]; 18 | 19 | // This category previously used to toss every non-16x16 icon since NSImage notoriously 20 | // would pick a larger image and scale it down instead of using a crisp exact icon. 21 | // With Retina displays, I can't keep doing that. It's not a problem to find the high-res/@2x 22 | // version of the 16x16 icon instead, but you might move the window to a low-res screen, 23 | // and the image can't magically contain the right icon at that time. 24 | 25 | // Maybe in the future, I will return an image with an NSCustomImageRep drawing the right image. 26 | 27 | return [icon autorelease]; 28 | } 29 | @end 30 | -------------------------------------------------------------------------------- /TSServiceInputRules.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceInputRules.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-17. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | 13 | @interface TSServiceInputRules : NSObject { 14 | NSSet *writingSystems; 15 | NSSet *contentTypes; 16 | NSNumber *wordLimit; 17 | NSSet *applicationIdentifiers; 18 | NSSet *languages; 19 | } 20 | 21 | - (id)initWithWritingSystems:(NSSet *)writingSystems 22 | contentTypes:(NSSet *)contentTypes 23 | wordLimit:(NSNumber *)wordLimit 24 | applicationIdentifiers:(NSSet *)applicationIdentifiers 25 | languages:(NSSet *)languages; 26 | 27 | - (NSSet *)writingSystems; 28 | - (NSSet *)contentTypes; 29 | - (NSNumber *)wordLimit; 30 | - (NSSet *)applicationIdentifiers; 31 | - (NSSet *)languages; 32 | 33 | - (NSDictionary *)infoPlistRequiredContextDictionary; 34 | + (TSServiceInputRules *)singleInputRulesFromInfoPlistRequiredContext:(NSDictionary *)requiredContextEntryDictionary; 35 | + (NSArray *)allInputRulesFromInfoPlistRequiredContext:(id)requiredContextEntry; 36 | 37 | - (BOOL)isEmpty; 38 | @end 39 | -------------------------------------------------------------------------------- /TSStubbornImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSStubbornImageView.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-13. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSStubbornImageView.h" 11 | 12 | 13 | @implementation TSStubbornImageView 14 | 15 | - (NSImage *)stubbornDefault { 16 | static NSImage *stubbornDefault = nil; 17 | if (stubbornDefault == nil) { 18 | stubbornDefault = [[NSImage imageNamed:@"emptyApp16x16"] retain]; 19 | } 20 | return stubbornDefault; 21 | } 22 | 23 | - (BOOL)imageShouldBeResisted:(NSImage *)newImage { 24 | return (newImage == nil); 25 | } 26 | 27 | - (void)setImage:(NSImage *)newImage { 28 | if ([self imageShouldBeResisted:newImage]) { 29 | [super setImage:[self stubbornDefault]]; 30 | [delegate stubbornImageView:self changedImage:[self image] isStubbornDefault:YES]; 31 | } else { 32 | [super setImage:newImage]; 33 | [delegate stubbornImageView:self changedImage:[self image] isStubbornDefault:NO]; 34 | } 35 | } 36 | 37 | - (BOOL)isStubbornDefault { 38 | return ([[self image] isEqual:[self stubbornDefault]] || [self imageShouldBeResisted:[self image]]); 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDRjCCAjkGByqGSM44BAEwggIsAoIBAQDw1klqa7aQ55AyF/Kw/n5GgW5LFwzf 3 | m+gqbGc8ZxlJoe4hr8cefoy/s3oyG8uYWujYtJwdATzFuuXrKr4PBsK/9FrvV2Bf 4 | +767ZNrCPIy6vYyg8xgkI1zT1AVHZDbcglN+JqM4cS7Wk/rCHdbIPkn0f93CN20w 5 | 0qmRcTpwapJg1Jdfelu/qt5+OFLFy3Od5chY7pyID9+HIfd889UDuyZ4DCCTz61C 6 | 2Ef/ctqzRoRIOB8em+JF0nBrp5+4Bcf83tTJ1awt4ORVt4IG3LLtpSem/EpgDr2a 7 | X5yY3lEd771eHWVbcR5+xMbAACHykaiCiqRvgI/5rzhpATshnsjJor2xAiEA/3Dj 8 | ZvOrE2KUdhT6uQkk/SmF+rPlm/mv02EV3I/l9g0CggEASu/pC6lWMHJrIqkGCn2b 9 | eahfeM0VWy1EMHDiIdguSThOcvqB0tg7SR4pgeH1yaNbUxNpL1uqTt1AubMl+62c 10 | hr4VAZ7pOV/RY1rnbZWL0ewltIgnudVsahGdVHe89maYdJCeTl9VL3URLI/lEAyL 11 | aq2NxL/BzpoXSkDGOS/zPxXixUj9JuREQPeDI53KLyXn2LKTecewutWo9caHrHBV 12 | E9OLucu33qNW5YmWQGUQLEfSLXlt0sUOLRyizIFGpIIWbNF9q1vcEuGy8sG7xHG9 13 | miObc8mHGZplFOkK/8nGNKpilbRhFcwE5aTAO9ptwMKkeifiLH3N8bvT2YeTBAkb 14 | KgOCAQUAAoIBAChjfGB7l+Oqqr93+njMGYCBxUX7SB6neflR2i9KixKtbxyMBnoj 15 | lhqHhFY/uCfYHBghRByYZPae3lq9IT373yBAV3DAsf//Yj3yD+wurQIq5i+41HTV 16 | DFW0WMAi6bObQcv9f0IMGL8MuJIvRxpKfPUzlf5106mdaV/t4OhIX9QB7u0D9Ecc 17 | mIvD6viVO9V9hxYlr0z5ae/KCgnBmlMbHw12dwvxO3cQBnilj82oILVjzBckFgq1 18 | oE3+QQghPOu/z09Of3H+XhUa92BBvC4GCdtPqblsEufuNoRGsXEyv/E0i8gNcfmz 19 | 53uLLYNQSRLUysdA2FMUmxc51JFSCBrE2Ks= 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /ServiceSkeleton/ServiceSkeletonMagic.h: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceSkeletonMagic.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2006-10-28. 6 | // Copyright 2006-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | #import "TSServiceTesting.h" 12 | 13 | #define SLog(...) do { if (logging) { NSLog(__VA_ARGS__); } } while (0) 14 | 15 | @interface ServiceSkeletonMagic : NSObject { 16 | NSString *_connectionName; 17 | id _producer; 18 | 19 | NSConnection *_connection; 20 | 21 | NSArray *scriptCandidates; 22 | 23 | BOOL isRunning; 24 | 25 | BOOL waitingForChoice; 26 | NSURL *selectedScript; 27 | 28 | NSMutableDictionary *outputsForFileHandles; 29 | } 30 | @property (readonly, retain) NSString *connectionName; 31 | @property (retain) NSConnection *connection; 32 | @property (readonly, retain) id producer; 33 | - (void)registerProducer:(id)p; 34 | 35 | + (void)setLogging:(BOOL)nl; 36 | 37 | + (BOOL)shouldKeepRunning; 38 | - (void)bumpBailingTimer; 39 | 40 | - (BOOL)vendSkeleton; 41 | 42 | - (NSData *)callThroughToScript:(NSString *)filename withData:(NSData *)data expectingOutput:(BOOL)expOut error:(NSError **)error; 43 | - (NSURL *)askUserToPickScriptOne:(NSURL *)one orTwo:(NSURL *)two; 44 | 45 | - (NSURL *)urlToScript; 46 | @end 47 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/css/genlist_style.css: -------------------------------------------------------------------------------- 1 | /* This Apple Help template put together by Andy Matuschak http://www.andymatuschak.org andy@andymatuschak.org Version 1.0 Adapted from the Safari help book--thanks, Apple! Adapted more directly from Pixen's help book. Licensed under MIT. */ /* APD CSS Genlist Style 2.0c*/ /* */ body { margin: 2px 12px 12px } h1 { font-size: 11pt; font-family: "Lucida Grande", Arial, sans-serif; margin-bottom: -4px } p { font-size: 9pt; line-height: 12pt; font-family: "Lucida Grande", Arial, sans-serif; margin-bottom: -4px } a { color: #00f; font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; text-decoration: none } a:hover { color: #00f; text-decoration: underline } #banner { background-color: #f2f2f2; background-repeat: no-repeat; padding: -2px 6px 0; position: fixed; top: 0; left: 0; width: 100%; height: 1.2em; float: left; border-bottom: 1px solid #bfbfbf } #machelp { position: absolute; top: 2px; left: 10px } #index { background-color: #f2f2f2; padding-right: 25px; position: absolute; top: 2px; right: 12px; width: auto; float: right } #list { margin-top: 36px; padding-right: 6px; width: 100% } .bread { color: #00f; font-size: 8pt; margin: -9px 0 -6px } .leftborder { color: #00f; font-size: 8pt; margin: -9px 0 -6px; padding-top: 2px; padding-bottom: 3px; padding-left: 8px; border-left: 1px solid #bfbfbf} -------------------------------------------------------------------------------- /ServiceSkeleton-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | net.wafflesoftware.ThisService.ServiceSkeleton 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | NSBGOnly 20 | 1 21 | NSPrincipalClass 22 | NSApplication 23 | ServiceSkeletonPortName 24 | Debug 25 | NSServices 26 | 27 | 28 | NSMenuItem 29 | 30 | default 31 | Test Magic Service 32 | 33 | NSMessage 34 | doServiceWork 35 | NSPortName 36 | ServiceSkeletonMagic 37 | NSSendTypes 38 | 39 | NSStringPboardType 40 | 41 | NSReturnTypes 42 | 43 | NSStringPboardType 44 | 45 | NSUserData 46 | foo.scpt 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /TSPackUpViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSPackUpViewController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2007-04-22. 6 | // Copyright 2007-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class WFFilePicker, TSModeMatrix; 13 | 14 | #import "TSViewController.h" 15 | 16 | @interface TSPackUpViewController : TSViewController 17 | { 18 | 19 | IBOutlet NSView *hasServicesView; 20 | IBOutlet NSView *noServicesView; 21 | IBOutlet NSTextField *onlySearchesInLabel; 22 | 23 | IBOutlet WFFilePicker *instructionsChoice; 24 | IBOutlet NSButton *packUpButton; 25 | IBOutlet NSPopUpButton *serviceChoice; 26 | IBOutlet TSModeMatrix *modeMatrix; 27 | 28 | IBOutlet NSTextField *loadingLabel; 29 | IBOutlet NSProgressIndicator *loadingIndicator; 30 | BOOL isRenaming; 31 | NSString *_rename; 32 | 33 | int instructionMode; 34 | BOOL _isPreflightingInstructionModeChange; 35 | 36 | BOOL hasConstructedMenuBefore; 37 | 38 | NSInvocationOperation *constructServicesMenuOperation; 39 | NSOperationQueue *operationQueue; 40 | } 41 | - (IBAction)changeService:(id)sender; 42 | - (IBAction)doPackUp:(id)sender; 43 | - (IBAction)showInstructionTemplate:(id)sender; 44 | 45 | - (IBAction)help:(id)sender; 46 | 47 | - (IBAction)showPackUp:(id)sender; 48 | 49 | - (void)packUp:(NSURL *)path; 50 | 51 | - (void)setRenaming:(BOOL)ren; 52 | - (BOOL)renaming; 53 | 54 | - (void)setRename:(NSString *)newRename; 55 | - (NSString *)rename; 56 | @end 57 | -------------------------------------------------------------------------------- /TSServiceAppFilterWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceAppFilterWindowController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-01. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class TSServiceAppFilterWindowController; 13 | @class TSServiceAppFilter; 14 | 15 | @protocol TSServiceAppFilterWindowControllerDelegate 16 | - (void)serviceAppFilterWindowController:(TSServiceAppFilterWindowController *)windowController savedChanges:(TSServiceAppFilter *)newRules; 17 | - (void)serviceAppFilterWindowControllerCancelled:(TSServiceAppFilterWindowController *)windowController; 18 | @end 19 | 20 | @interface TSServiceAppFilterWindowController : NSWindowController { 21 | NSMutableArray *apps; 22 | NSSet *appIDsInUse; 23 | NSTableView *tableView; 24 | TSServiceAppFilter *initialAppFilter; 25 | id editor; 26 | NSPopUpButton *applicationDropDown; 27 | NSButton *okButton; 28 | } 29 | @property (assign) IBOutlet NSPopUpButton *applicationDropDown; 30 | @property (assign) IBOutlet NSButton *okButton; 31 | 32 | - (void)setEditor:(id)newEditor; 33 | - (void)setInitialAppFilter:(TSServiceAppFilter *)initialAppFilter; 34 | 35 | @property (assign) IBOutlet NSTableView *tableView; 36 | - (IBAction)done:(id)sender; 37 | - (IBAction)cancel:(id)sender; 38 | - (IBAction)deleteSelectedRowsByButton:(id)sender; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface SUAppcastItem : NSObject { 13 | NSString *title; 14 | NSDate *date; 15 | NSString *description; 16 | 17 | NSURL *releaseNotesURL; 18 | 19 | NSString *DSASignature; 20 | NSString *MD5Sum; 21 | 22 | NSString *minimumSystemVersion; 23 | 24 | NSURL *fileURL; 25 | NSString *fileVersion; 26 | NSString *versionString; 27 | } 28 | 29 | // Initializes with data from a dictionary provided by the RSS class. 30 | - initWithDictionary:(NSDictionary *)dict; 31 | 32 | - (NSString *)title; 33 | - (void)setTitle:(NSString *)aTitle; 34 | 35 | - (NSDate *)date; 36 | - (void)setDate:(NSDate *)aDate; 37 | 38 | - (NSString *)description; 39 | - (void)setDescription:(NSString *)aDescription; 40 | 41 | - (NSURL *)releaseNotesURL; 42 | - (void)setReleaseNotesURL:(NSURL *)aReleaseNotesURL; 43 | 44 | - (NSString *)DSASignature; 45 | - (void)setDSASignature:(NSString *)aDSASignature; 46 | 47 | - (NSString *)MD5Sum; 48 | - (void)setMD5Sum:(NSString *)aMd5Sum; 49 | 50 | - (NSURL *)fileURL; 51 | - (void)setFileURL:(NSURL *)aFileURL; 52 | 53 | - (NSString *)fileVersion; 54 | - (void)setFileVersion:(NSString *)aFileVersion; 55 | 56 | - (NSString *)versionString; 57 | - (void)setVersionString:(NSString *)versionString; 58 | 59 | - (NSString *)minimumSystemVersion; 60 | - (void)setMinimumSystemVersion:(NSString *)systemVersionString; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /WFMachTime.m: -------------------------------------------------------------------------------- 1 | #import "WFMachTime.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | @interface WFMachTime () 9 | @property uint64_t startedTime; 10 | @end 11 | 12 | @implementation WFMachTime 13 | @synthesize startedTime; 14 | 15 | + (uint64_t)currentPrimitiveTime { 16 | return mach_absolute_time(); 17 | } 18 | 19 | + (WFMachTime *)currentTime { 20 | WFMachTime *time = [[self alloc] init]; 21 | time.startedTime = [self currentPrimitiveTime]; 22 | return [time autorelease]; 23 | } 24 | 25 | NSTimeInterval WFMachTimeIntervalBetweenStartTimeEndTime(uint64_t startTime, uint64_t endTime) { 26 | uint64_t elapsed; 27 | uint64_t elapsedNano; 28 | static mach_timebase_info_data_t sTimebaseInfo; 29 | 30 | elapsed = endTime - startTime; 31 | 32 | if ( sTimebaseInfo.denom == 0 ) { 33 | (void) mach_timebase_info(&sTimebaseInfo); 34 | } 35 | 36 | elapsedNano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom; 37 | 38 | NSTimeInterval duration = (NSTimeInterval)(elapsedNano / 1000000000.0); 39 | 40 | return duration; 41 | } 42 | 43 | - (NSTimeInterval)intervalSinceTime:(WFMachTime *)time { 44 | uint64_t startTime = time.startedTime; 45 | uint64_t endTime = self.startedTime; 46 | 47 | return WFMachTimeIntervalBetweenStartTimeEndTime(startTime, endTime); 48 | } 49 | 50 | - (NSTimeInterval)intervalSinceStart { 51 | uint64_t startTime = self.startedTime; 52 | uint64_t endTime = [[self class] currentPrimitiveTime]; 53 | 54 | return WFMachTimeIntervalBetweenStartTimeEndTime(startTime, endTime); 55 | } 56 | @end -------------------------------------------------------------------------------- /NDResourceFork+OtherSorces.m: -------------------------------------------------------------------------------- 1 | /* 2 | * NDResourceFork+OtherSorces.m category 3 | * NDResourceFork 4 | * 5 | * Created by Nathan Day on Thu Dec 05 2002. 6 | * Copyright (c) 2002 Nathan Day. All rights reserved. 7 | */ 8 | 9 | #import "NDResourceFork+OtherSorces.h" 10 | #import "NSURL+NDCarbonUtilities.h" 11 | 12 | /* 13 | * category implementation NDResourceFork (OtherSorces) 14 | */ 15 | @implementation NDResourceFork (OtherSorces) 16 | 17 | /* 18 | * +iconFamilyDataForURL: 19 | */ 20 | + (NSData *)iconFamilyDataForURL:(NSURL *)aURL 21 | { 22 | NSData * theIconFamilyData = nil; 23 | FSRef theFSRef; 24 | IconRef theIconRef; 25 | SInt16 theOutLabel; 26 | IconFamilyHandle theIconFamilyHandle; 27 | 28 | if( [aURL getFSRef:&theFSRef] ) 29 | { 30 | if( noErr == GetIconRefFromFileInfo( &theFSRef, 0, NULL, kFSCatInfoFinderInfo, NULL, kIconServicesNormalUsageFlag, &theIconRef, &theOutLabel ) ) 31 | { 32 | if( noErr == IconRefToIconFamily( theIconRef, kSelectorAllAvailableData, &theIconFamilyHandle ) ) 33 | { 34 | HLock( (Handle)theIconFamilyHandle ); 35 | theIconFamilyData = [NSData dataWithBytes:*theIconFamilyHandle length:GetHandleSize( (Handle)theIconFamilyHandle )]; 36 | HUnlock( (Handle)theIconFamilyHandle ); 37 | 38 | DisposeHandle( (Handle)theIconFamilyHandle ); 39 | } 40 | 41 | ReleaseIconRef( theIconRef ); 42 | } 43 | } 44 | 45 | return theIconFamilyData; 46 | } 47 | 48 | /* 49 | * +iconFamilyDataForFile: 50 | */ 51 | + (NSData *)iconFamilyDataForFile:(NSString *)aPath 52 | { 53 | return [self iconFamilyDataForURL:[NSURL fileURLWithPath:aPath]]; 54 | } 55 | 56 | @end 57 | 58 | 59 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Except where otherwise noted, including references to other source material within the code, 2 | ThisService is licensed under the ("modified", "three-clause", "new") BSD license as below: 3 | 4 | Copyright (c) 2006-2012, waffle software 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | * Neither the name of waffle software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /NSString+CarbonFSRefCreation.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2001-2010 Troy N. Stephens 3 | 4 | Use and distribution of this source code is governed by the MIT License, whose terms are as follows. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | #import 14 | #import 15 | 16 | @interface NSString (CarbonFSRefCreation) 17 | 18 | // Fills in the given FSRef struct so it specifies the file whose path is in this string. 19 | // If the file doesn't exist, and "createFile" is YES, this method will attempt to create 20 | // an empty file with the specified path. (The caller should insure that the directory 21 | // the file is to be placed in already exists.) 22 | 23 | - (BOOL) getFSRef:(FSRef*)fsRef createFileIfNecessary:(BOOL)createFile; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TSTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSTableView.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-15. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSTableView.h" 11 | 12 | @implementation TSTableView 13 | 14 | - (void)keyDown:(NSEvent *)theEvent { 15 | 16 | static NSNumber *hasPerformClickOnCell = nil; 17 | if (!hasPerformClickOnCell) { 18 | hasPerformClickOnCell = [[NSNumber numberWithBool:[self respondsToSelector:@selector(performClickOnCellAtColumn:row:)]] retain]; 19 | } 20 | if (![hasPerformClickOnCell boolValue]) { 21 | [super keyDown:theEvent]; 22 | return; 23 | } 24 | 25 | NSUInteger keyboardModifiers = (NSShiftKeyMask | NSAlternateKeyMask | NSCommandKeyMask | NSControlKeyMask); 26 | if (([theEvent modifierFlags] & keyboardModifiers) == 0) { 27 | const int backspace = 51; 28 | const int delete = 117; 29 | if ([theEvent keyCode] == backspace || [theEvent keyCode] == delete) { 30 | if ([self.delegate respondsToSelector:@selector(deleteSelectedRows)]) { 31 | [self.delegate performSelector:@selector(deleteSelectedRows)]; 32 | return; 33 | } 34 | } 35 | if ([[theEvent characters] isEqualToString:@" "]) { 36 | NSInteger selectedRow = [self selectedRow]; 37 | if (selectedRow != NSNotFound) { 38 | NSCell *cell = [self preparedCellAtColumn:0 row:selectedRow]; 39 | if ([cell isKindOfClass:[NSButtonCell class]]) { 40 | NSButtonCell *buttonCell = (NSButtonCell *)cell; 41 | if ([buttonCell isEnabled]) { 42 | [self performClickOnCellAtColumn:0 row:selectedRow]; 43 | return; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | [super keyDown:theEvent]; 51 | } 52 | @end 53 | -------------------------------------------------------------------------------- /NSBezierPath+AttributedStringExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSBezierPath+AttributedStringExtensions.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-24. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import "NSBezierPath+AttributedStringExtensions.h" 12 | 13 | // Adapted from http://amber-framework.googlecode.com/ under the same license. 14 | 15 | @implementation NSBezierPath (AttributedStringExtensions) 16 | 17 | + (NSBezierPath *)bezierPathWithString:(NSString *)text inFont:(NSFont *)font { 18 | NSBezierPath *textPath = [self bezierPath]; 19 | [textPath appendBezierPathWithString:text inFont:font]; 20 | return textPath; 21 | } 22 | 23 | - (void)appendBezierPathWithString:(NSString *)text inFont:(NSFont *)font { 24 | if ([self isEmpty]) [self moveToPoint:NSZeroPoint]; 25 | 26 | NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text]; 27 | CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attributedString); 28 | [attributedString release]; 29 | 30 | CFArrayRef glyphRuns = CTLineGetGlyphRuns(line); 31 | CFIndex count = CFArrayGetCount(glyphRuns); 32 | 33 | for (CFIndex index = 0; index < count; index++) { 34 | CTRunRef currentRun = CFArrayGetValueAtIndex(glyphRuns, index); 35 | 36 | CFIndex glyphCount = CTRunGetGlyphCount(currentRun); 37 | 38 | CGGlyph glyphs[glyphCount]; 39 | CTRunGetGlyphs(currentRun, CTRunGetStringRange(currentRun), glyphs); 40 | 41 | NSGlyph bezierPathGlyphs[glyphCount]; 42 | for (CFIndex glyphIndex = 0; glyphIndex < glyphCount; glyphIndex++) 43 | bezierPathGlyphs[glyphIndex] = glyphs[glyphIndex]; 44 | 45 | [self appendBezierPathWithGlyphs:bezierPathGlyphs count:glyphCount inFont:font]; 46 | } 47 | 48 | CFRelease(line); 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/css/accessPage.css: -------------------------------------------------------------------------------- 1 | /* This Apple Help template put together by Andy Matuschak http://www.andymatuschak.org andy@andymatuschak.org Version 1.0 Adapted from the Safari help book--thanks, Apple! Adapted more directly from Pixen's help book. Licensed under MIT. */ /* Tiger access v1.0b*/ /* */ body { color: #000; background-color: #fff; margin: 0; font-family: "Lucida Grande", Arial, sans-serif; } a { color: #00f; text-decoration: none } h1 { color: #000; font-size: 18pt; font-weight: 500; letter-spacing: -1pt; padding-top: 8px } h2 { color: #000; font-size: 11pt; font-weight: 300; margin: 0; margin-bottom: 15px; } h4 { color: #000; font-size: 8pt; font-weight: 300; margin-top: 21px } p { font-size: 9pt; font-family: Lucida Grande, Arial, sans-serif; margin-top: -10px; margin-left: 0 } ul { margin: 0; padding: 0; padding-left: 16px; } li { list-style-image: url(../gfx/orngbullet.gif); font-size: 9pt; line-height: 13pt; margin: 0; padding: 0; } a:hover { text-decoration: underline } #contentleft { margin-top: 38px; width: 235px; float: left } #contentcenter { margin-top: 2px; padding: 0; width: 18px; float: left } #contentright { margin-top: 18px; padding-left: 30px; width: 210px; height: 300px; float: left; border-left: 1px solid #808080 } #frame { text-align: left; margin-top: 12px; margin-right: auto; margin-left: auto; width: 500px } .space17 { padding-top: 17px } .smlapp { height: 275px } .utility { margin-top: 6px; margin-bottom: 24px } .icon { margin-bottom: -6px } #splashscreenshot { content: -webkit-image-set(url(../gfx/splashScreenshot.png) 1x, url('../gfx/splashScreenshot@2x.png') 2x); } #appicon { content: -webkit-image-set(url(../gfx/icon.png) 1x, url('../gfx/icon@2x.png') 2x); } -------------------------------------------------------------------------------- /TSServiceTester.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceTester.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-05. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | #import "TSServiceTesting.h" 13 | 14 | @class TSServiceTester; 15 | @class TSService; 16 | 17 | @protocol TSServiceTesterDelegate 18 | - (void)testerLaunchedService:(TSServiceTester *)tester; 19 | - (void)testerPairedWithService:(TSServiceTester *)tester; 20 | - (void)tester:(TSServiceTester *)tester failedWithError:(NSString *)error; 21 | - (void)testerBeganRunningService:(TSServiceTester *)tester; 22 | 23 | - (void)testerWillInvokeService:(TSServiceTester *)tester withPasteboard:(NSPasteboard *)pasteboard; 24 | - (void)testerFinishedRunningService:(TSServiceTester *)tester withPasteboard:(NSPasteboard *)pasteboard; 25 | @end 26 | 27 | @interface TSServiceTester : NSObject { 28 | NSString *_launchPath; 29 | NSURL *_serviceURL; 30 | 31 | TSService *_service; 32 | 33 | id _skeleton; 34 | NSPasteboard *_pasteboard; 35 | NSString *_registeredSkeletonName; 36 | NSConnection *_connection; 37 | NSTask *_serviceTask; 38 | 39 | dispatch_source_t _taskExitSource; 40 | 41 | id _delegate; 42 | } 43 | - (id)initWithServiceLaunchPath:(NSString *)launchPath service:(TSService *)service testServiceURL:(NSURL *)serviceURL; 44 | 45 | @property (retain) id skeleton; 46 | @property (retain) NSPasteboard *pasteboard; 47 | @property (retain) NSString *registeredSkeletonName; 48 | @property (retain) NSConnection *connection; 49 | @property (retain) NSTask *serviceTask; 50 | 51 | @property (readonly, retain) TSService *service; 52 | 53 | - (BOOL)startTesting; 54 | 55 | - (void)setDelegate:(id)delegate; 56 | 57 | - (BOOL)startConnection; 58 | 59 | - (void)cancel; 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /TSServiceTesting.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceTesting.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-05. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | 13 | @protocol TSServiceTestingSkeleton // skeleton called by ThisService 14 | - (oneway void)invokeServiceWithPasteboard:(NSString *)pasteboardName; 15 | - (oneway void)testingDone; 16 | @end 17 | 18 | @protocol TSServiceTestingProducer // TS called by the skeleton 19 | // the name of the connection of the skeleton vending a id object 20 | - (oneway void)registerNewSkeletonNamed:(NSString *)skeletonName; 21 | - (oneway void)testRunForSkeletonStarted:(NSString *)skeletonName; 22 | - (oneway void)testRunForSkeleton:(NSString *)skeletonName ended:(NSString *)error; // error being nil indicates success 23 | @end 24 | 25 | 26 | /* 27 | 1. The ThisService application (TS) creates the service. 28 | 2. TS creates an object like id and vends it. 29 | 3. TS runs the service skeleton in the newly created service, passing in the name of its connection as a flag. 30 | 4. The service invents a unique name and names its NSConnection. 31 | 5. The service creates an object like id and vends it. 32 | 6. The service connects to the TS object and registers the new skeleton using the unique name. 33 | 7. When testing is requested: 34 | a. TS sets up a unique pasteboard (inherently cross-process) using system functionality. 35 | b. If necessary, TS populates the pasteboard with the input data. 36 | c. TS invokes the service passing the name of the pasteboard. 37 | d. Glue code in the service skeleton runs the service as usual with the pasteboard, noting to TS that it has started running. 38 | e. On error, the service reports the error; on success, the service reports the success. This is the same call. 39 | 8. When the test sheet is dismissed for any reason, testingDone is called and both ends are torn down. 40 | */ 41 | -------------------------------------------------------------------------------- /TSModeMatrix.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSModeMatrix.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2007-08-04. 6 | // Copyright 2007-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSModeMatrix.h" 11 | 12 | 13 | @implementation TSModeMatrix 14 | 15 | - (id)initWithCoder:(NSCoder *)aDecoder { 16 | self = [super initWithCoder:aDecoder]; 17 | if (self != nil) { 18 | lastTag = NSNotFound; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)finishInitializing { 24 | [self selectCellWithTag:0]; 25 | [self reconfigureWithAnimation:NO]; 26 | } 27 | 28 | - (void)setContentInitialized { 29 | contentHasInitialized = YES; 30 | [self finishInitializing]; 31 | } 32 | 33 | - (void)awakeFromNib { 34 | if (contentHasInitialized) return; 35 | [self finishInitializing]; 36 | } 37 | 38 | - (void)goToTag:(int)tag { 39 | [self selectCellWithTag:tag]; 40 | [self selectMe:[self cellWithTag:tag]]; 41 | } 42 | 43 | - (void)selectMe:(id)sender { 44 | id dlx = [self delegate]; 45 | //NSLog(@"do we have a delegate? %@; sender: %@", dlx, sender); 46 | if ([dlx respondsToSelector:@selector(modeMatrix:shouldSwitchFromTag:toTag:)]) { 47 | //NSLog(@"yes, and it responds to the selector"); 48 | if (![dlx modeMatrix:self shouldSwitchFromTag:lastTag toTag:[self selectedTag]]) { 49 | //NSLog(@"it responded no. last tag: %d", lastTag); 50 | if ([self selectedTag] != lastTag) { 51 | [self selectCellWithTag:lastTag]; 52 | [self selectMe:[self cellWithTag:lastTag]]; 53 | } 54 | return; 55 | } 56 | } 57 | // NSLog(@"go ahead"); 58 | [self reconfigureWithAnimation:YES]; 59 | } 60 | 61 | - (id)delegate { 62 | return (id)[super delegate]; 63 | } 64 | - (void)reconfigureWithAnimation:(BOOL)anim { 65 | NSInteger previousTag = lastTag; 66 | lastTag = [self selectedTag]; 67 | // NSLog(@"lastTag set to %llu; previousTag is %llu", (unsigned long long)lastTag, (unsigned long long)previousTag); 68 | NSInteger newTag = lastTag; 69 | 70 | [[self delegate] modeMatrix:self switchFromTag:previousTag toTag:newTag animate:anim]; 71 | } 72 | @end 73 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/css/indexPage.css: -------------------------------------------------------------------------------- 1 | /* This Apple Help template put together by Andy Matuschak http://www.andymatuschak.org andy@andymatuschak.org Version 1.0 Adapted from the Safari help book--thanks, Apple! Adapted more directly from Pixen's help book. Licensed under MIT. */ /* Tiger index.css v1.0e*/ /* */ body { margin: 2px 12px 12px } h1 { font-size: 11pt; font-family: Lucida Grande, Arial, sans-serif; margin-bottom: 0 } p, li { font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; text-decoration: none } a { color: #00f; font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; text-decoration: none } a:hover { color: #00f; text-decoration: underline } #letters { background-color: #fff; padding-top: 1px; padding-bottom: 0; padding-left: 12px; position: fixed; z-index: 1; top: 1.2em; right: 0; left: 0; width: 1000px; height: 1.2em; float: left; border-top: 1px solid #bfbfbf; border-bottom: 1px solid #bfbfbf } #terms { position: absolute; top: 3em; width: 470px } #banner { background-color: #f2f2f2; background-repeat: no-repeat; padding: -2px 6px 0; position: fixed; z-index: 1; top: 0; left: 0; width: 100%; height: 1.2em; float: left; border-bottom: 1px solid #bfbfbf } #machelp { position: absolute; top: 2px; left: 10px } #index { padding-right: 25px; position: absolute; top: 2px; left: 85% } #mainbox { margin-top: 36px; padding-right: 6px } .seealso { color: #5c5c5c; text-decoration: none } .select { color: #00f; font-size: 10pt; background-color: #ff9f00; margin-right: -1px; margin-left: -1px; padding: 2px 2px 3px } .letter { color: #00f; font-size: 10pt; margin-right: 1px; margin-left: 1px } .leftborder { color: #00f; font-size: 8pt; margin: -9px 0 -6px; padding-top: 2px; padding-bottom: 3px; padding-left: 8px; border-left: 1px solid #bfbfbf} tr { margin-top: 12px; margin-bottom: 12px } td { padding: 3px; border-bottom: 1px solid #eee} table { margin-bottom: 12px; border-style: dotted; border-color: #bfbfbf} .bread { color: #00f; font-size: 8pt; margin: -9px 0 -6px } -------------------------------------------------------------------------------- /ServiceSkeleton/NSAppleScript+HandlerCalls.m: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | NSAppleScript+HandlerCalls.m 4 | ASHandlerTest 5 | by Buzz Andersen 6 | 7 | More information at: http://www.scifihifi.com/weblog/mac/Cocoa-AppleEvent-Handlers.html 8 | 9 | This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit 10 | 11 | http://creativecommons.org/licenses/by/1.0/ 12 | 13 | or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, 14 | California 94305, USA. 15 | 16 | */ 17 | 18 | #import "NSAppleScript+HandlerCalls.h" 19 | 20 | @implementation NSAppleScript (HandlerCalls) 21 | 22 | - (NSAppleEventDescriptor *)callHandler:(NSString *)handler 23 | withArguments:(NSAppleEventDescriptor *)arguments 24 | errorInfo:(out NSDictionary **)errorInfo { 25 | NSAppleEventDescriptor* event; 26 | NSAppleEventDescriptor* targetAddress; 27 | NSAppleEventDescriptor* subroutineDescriptor; 28 | NSAppleEventDescriptor* result; 29 | 30 | /* This will be a self-targeted AppleEvent, so we need to identify ourselves using our process id */ 31 | int pid = [[NSProcessInfo processInfo] processIdentifier]; 32 | targetAddress = [[NSAppleEventDescriptor alloc] initWithDescriptorType: typeKernelProcessID bytes: &pid length: sizeof(pid)]; 33 | 34 | /* Set up our root AppleEvent descriptor: a subroutine call (psbr) */ 35 | event = [[NSAppleEventDescriptor alloc] initWithEventClass: 'ascr' eventID: 'psbr' targetDescriptor: targetAddress returnID: kAutoGenerateReturnID transactionID: kAnyTransactionID]; 36 | 37 | /* Set up an AppleEvent descriptor containing the subroutine (handler) name */ 38 | subroutineDescriptor = [NSAppleEventDescriptor descriptorWithString: handler]; 39 | [event setParamDescriptor: subroutineDescriptor forKeyword: 'snam']; 40 | 41 | /* Add the provided arguments to the handler call */ 42 | [event setParamDescriptor: arguments forKeyword: keyDirectObject]; 43 | 44 | /* Execute the handler */ 45 | result = [self executeAppleEvent: event error: errorInfo]; 46 | 47 | [targetAddress release]; 48 | [event release]; 49 | 50 | return result; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/NSString+extras.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD License 4 | 5 | Copyright (c) 2002, Brent Simmons 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, 9 | are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | * Neither the name of ranchero.com or Brent Simmons nor the names of its 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 24 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | 32 | */ 33 | 34 | 35 | /* 36 | NSString+extras.h 37 | NetNewsWire 38 | 39 | Created by Brent Simmons on Fri Jun 14 2002. 40 | Copyright (c) 2002 Brent Simmons. All rights reserved. 41 | */ 42 | 43 | 44 | #import 45 | #import 46 | 47 | 48 | @interface NSString (extras) 49 | 50 | - (NSString *)stringWithSubstitute:(NSString *)subs forCharactersFromSet:(NSCharacterSet *)set; 51 | 52 | - (NSString *) trimWhiteSpace; 53 | 54 | - (NSString *) stripHTML; 55 | 56 | - (NSString *) ellipsizeAfterNWords: (int) n; 57 | 58 | + (BOOL) stringIsEmpty: (NSString *) s; 59 | 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /TSServiceInputRulesWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceInputRulesWindowController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-17. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | #import "TSCheckedListDataSource.h" 13 | 14 | @class TSServiceInputRules; 15 | 16 | @class TSServiceInputRulesWindowController; 17 | 18 | @protocol TSServiceInputRulesWindowControllerDelegate 19 | - (void)serviceInputRulesWindowController:(TSServiceInputRulesWindowController *)windowController savedChanges:(TSServiceInputRules *)newRules; 20 | - (void)serviceInputRulesWindowControllerCancelled:(TSServiceInputRulesWindowController *)windowController; 21 | @end 22 | 23 | 24 | @interface TSServiceInputRulesWindowController : NSWindowController { 25 | TSServiceInputRules *initialInputRules; 26 | id editor; 27 | 28 | IBOutlet NSPanel *inputRulesPanel; 29 | 30 | TSCheckedListDataSource *writingSystemCheckedListDataSource; 31 | IBOutlet NSTableView *writingSystemTableView; 32 | BOOL constrainsByWritingSystem; 33 | 34 | TSCheckedListDataSource *contentTypeCheckedListDataSource; 35 | IBOutlet NSTableView *contentTypeTableView; 36 | BOOL constrainsByContentType; 37 | 38 | TSCheckedListDataSource *languageCheckedListDataSource; 39 | IBOutlet NSTableView *languageTableView; 40 | BOOL constrainsByLanguage; 41 | 42 | BOOL constrainsByWordLimit; 43 | NSInteger wordLimit; 44 | 45 | 46 | } 47 | 48 | - (void)setEditor:(id)newEditor; 49 | - (void)setInitialInputRules:(TSServiceInputRules *)initialInputRules; 50 | 51 | - (void)setConstrainsByWritingSystem:(BOOL)c; 52 | - (BOOL)constrainsByWritingSystem; 53 | 54 | - (void)setConstrainsByContentType:(BOOL)c; 55 | - (BOOL)constrainsByContentType; 56 | 57 | - (void)setConstrainsByWordLimit:(BOOL)c; 58 | - (BOOL)constrainsByWordLimit; 59 | 60 | - (void)setConstrainsByLanguage:(BOOL)c; 61 | - (BOOL)constrainsByLanguage; 62 | 63 | - (void)setWordLimit:(NSInteger)wordLimit; 64 | - (NSInteger)wordLimit; 65 | 66 | 67 | - (IBAction)okayInputRulesSheet:(id)sender; 68 | - (IBAction)cancelInputRulesSheet:(id)sender; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /TSExtraCollectionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSExtraCollectionView.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-09. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import "TSExtraCollectionView.h" 12 | #import 13 | 14 | @implementation TSExtraCollectionView 15 | 16 | -(void)awakeFromNib { 17 | views = [[NSMutableDictionary alloc] init]; 18 | } 19 | 20 | - (void)registerView:(NSView *)view forIdentifier:(NSString *)identifier { 21 | [views setObject:view forKey:identifier]; 22 | } 23 | 24 | - (void)registerWhenRemovedTarget:(id)target action:(SEL)action { 25 | whenRemovedTarget = [target retain]; 26 | whenRemovedAction = action; 27 | } 28 | 29 | - (void)callWhenRemoved { 30 | [whenRemovedTarget performSelector:whenRemovedAction withObject:self]; 31 | } 32 | 33 | - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object { 34 | NSCollectionViewItem *newItem = [super newItemForRepresentedObject:object]; 35 | 36 | // NSLog(@"new item %@", newItem); 37 | 38 | NSView *v = [newItem view]; 39 | TSExtraCollectionItemView *itemView = (TSExtraCollectionItemView *)v; 40 | [itemView setItem:newItem]; 41 | 42 | NSButton *button = [itemView viewWithTag:888]; 43 | [button setTarget:itemView]; 44 | [button setAction:@selector(removeItem:)]; 45 | 46 | // NSLog(@"itemView: %@", itemView); 47 | 48 | NSView *view = [views objectForKey:object]; 49 | [itemView addSubview:view]; 50 | 51 | return newItem; 52 | } 53 | 54 | @end 55 | 56 | 57 | @implementation TSExtraCollectionItemView 58 | @synthesize item = _item; 59 | - (IBAction)removeItem:(id)sender { 60 | NSMutableArray *c = [[[_item.collectionView content] mutableCopy] autorelease]; 61 | [c removeObject:_item.representedObject]; 62 | 63 | 64 | id plainCollectionView = _item.collectionView; 65 | TSExtraCollectionView *collectionView = nil; 66 | if ([plainCollectionView isKindOfClass:[TSExtraCollectionView class]]) { 67 | collectionView = plainCollectionView; 68 | } 69 | 70 | [_item.collectionView setContent:c]; 71 | 72 | if (collectionView) { 73 | [collectionView callWhenRemoved]; 74 | } 75 | 76 | } 77 | @end -------------------------------------------------------------------------------- /WFFilePicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // WFFilePicker.h 3 | // 4 | // Created by Jesper on 2006-04-13. 5 | // Copyright 2006-2012 waffle software. All rights reserved. 6 | // BSD licensed - see license.txt for more information. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class WFFilePickerIconView, WFFilePickerLabelView; 13 | 14 | @interface WFFilePicker : NSView { 15 | NSButton *chooseButton; 16 | NSButton *emptyButton; 17 | WFFilePickerIconView *iconView; 18 | WFFilePickerLabelView *nameView; 19 | 20 | NSURL *representedURL; 21 | FSRef representedFSRef; 22 | 23 | NSImage *currentFileIcon; 24 | 25 | BOOL isDropping; 26 | 27 | BOOL enabled; 28 | 29 | BOOL showsEmptyButton; 30 | 31 | // BOOL allowsMultipleSelection; 32 | BOOL canChooseDirectories; 33 | BOOL canChooseFiles; 34 | BOOL resolvesAliases; 35 | NSArray *allowedFileTypes; 36 | 37 | id filePathObserver; 38 | NSString *filePathObserverKeyPath; 39 | NSValueTransformer *filePathVT; 40 | 41 | id enabledObserver; 42 | NSString *enabledObserverKeyPath; 43 | NSValueTransformer *enabledVT; 44 | 45 | IBOutlet id delegate; 46 | 47 | } 48 | - (void)setRepresentedURL:(NSURL *)u; 49 | - (NSURL *)representedURL; 50 | 51 | - (void)setFilePath:(NSString *)s; 52 | - (NSString *)filePath; 53 | 54 | - (void)setRepresentedFSRef:(FSRef)r; 55 | - (FSRef)representedFSRef; 56 | 57 | - (BOOL)isEmpty; 58 | - (void)setEmpty; 59 | 60 | - (BOOL)showsEmptyButton; 61 | - (void)setShowsEmptyButton:(BOOL)set; 62 | 63 | - (BOOL)isEnabled; 64 | - (void)setEnabled:(BOOL)en; 65 | - (void)setEnabledWithoutKVO:(BOOL)en; 66 | 67 | - (IBAction)beginChooseSheet:(id)sender; 68 | 69 | - (id)delegate; 70 | - (void)setDelegate:(id)del; 71 | 72 | - (BOOL)resolvesAliases; 73 | - (void)setResolvesAliases:(BOOL)flag; 74 | - (BOOL)canChooseDirectories; 75 | - (void)setCanChooseDirectories:(BOOL)flag; 76 | - (BOOL)canChooseFiles; 77 | - (void)setCanChooseFiles:(BOOL)flag; 78 | - (NSArray *)allowedFileTypes; 79 | - (void)setAllowedFileTypes:(NSArray *)types; 80 | @end 81 | 82 | @interface NSObject (WFFilePickerDelegateMethods) 83 | - (NSOpenPanel *)filePicker:(WFFilePicker *)aFilePicker willShowOpenPanel:(NSOpenPanel *)openPanel; 84 | - (void)filePicker:(WFFilePicker *)aFilePicker openPanelDismissedWithReturnCode:(int)returnCode; 85 | - (BOOL)filePicker:(WFFilePicker *)aFilePicker validateURL:(NSURL *)url error:(NSError **)anError; 86 | @end 87 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuartzGLEnable 6 | 7 | CFBundleShortVersionString 8 | 3.0.1 9 | CFBundleDevelopmentRegion 10 | English 11 | CFBundleDocumentTypes 12 | 13 | 14 | CFBundleTypeExtensions 15 | 16 | pl 17 | rb 18 | py 19 | pyc 20 | pm 21 | js 22 | sh 23 | command 24 | csh 25 | rbw 26 | php 27 | php3 28 | php4 29 | ph3 30 | ph4 31 | applescript 32 | scpt 33 | 34 | CFBundleTypeName 35 | ThisService script source 36 | CFBundleTypeOSTypes 37 | 38 | osas 39 | 40 | CFBundleTypeRole 41 | Viewer 42 | LSHandlerRank 43 | None 44 | LSTypeIsPackage 45 | 46 | 47 | 48 | CFBundleExecutable 49 | ${EXECUTABLE_NAME} 50 | CFBundleHelpBookFolder 51 | ThisService Help.help 52 | CFBundleHelpBookName 53 | net.wafflesoftware.ThisService.help 54 | CFBundleIconFile 55 | hidpiicon 56 | CFBundleIdentifier 57 | net.wafflesoftware.ThisService 58 | CFBundleInfoDictionaryVersion 59 | 6.0 60 | CFBundleName 61 | ${PRODUCT_NAME} 62 | CFBundlePackageType 63 | APPL 64 | CFBundleSignature 65 | ???? 66 | CFBundleVersion 67 | 3.0.1 68 | NSMainNibFile 69 | MainMenu 70 | NSPrincipalClass 71 | NSApplication 72 | SUFeedURL 73 | http://wafflesoftware.net/thisservice/sparkle/sparkle.xml 74 | SUPublicDSAKeyFile 75 | dsa_pub.pem 76 | 77 | 78 | -------------------------------------------------------------------------------- /NDResourceFork+OtherSorces.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header NDResourceFork+OtherSorces 3 | @abstract Declares the category NDResourceFork (OtherSorces) 4 | @discussion NDResourceFork+OtherSorces is a category of NDResourceFork which adds methods that can retireve resource fork data by non resource fork means. 5 | */ 6 | 7 | #import 8 | #import "NDResourceFork.h" 9 | 10 | /*! 11 | @header NDResourceFork(OtherSorces) 12 | @abstract Defines the interface for a category of the class NDResourceFork. 13 | @discussion Defines method for NDResourceFork for retrieving resource type data from non resource fork sources, at lest not directly. The category OtherSorces can be omitted from your project if the additonal functionalty is not desired. 14 | */ 15 | 16 | /*! 17 | @category NDResourceFork(OtherSorces) 18 | @abstract A category of the class NDResourceFork. 19 | @discussion The category OtherSorces adds method to NDResourceFork for retrieving resource type data from non resource fork sources, at lest not directly. This category can be omitted from your project if the additonal functionalty is not desired. 20 | */ 21 | @interface NDResourceFork (OtherSorces) 22 | 23 | /*! 24 | @method iconFamilyDataForURL: 25 | @abstract Gets a files or directories Icon Family Data. 26 | @discussion iconFamilyDataForURL: returns the Icon Family Data for any file or directory. The file does not have to have an actual resource fork with the Icon Family Data in it, neither does a directory have to have an Icon/r file with the Icon Family Data. 27 | @param URL The file url for which the Icon Family Data is required. 28 | @result A NSData contain the Icon Family Data, returns nil if iconFamilyDataForURL: failed. 29 | */ 30 | + (NSData *)iconFamilyDataForURL:(NSURL *)URL; 31 | /*! 32 | @method iconFamilyDataForFile: 33 | @abstract Gets a files or directories Icon Family Data. 34 | @discussion iconFamilyDataForURL: returns the Icon Family Data for any file or directory. The file does not have to have an actual resource fork with the Icon Family Data in it, neither does a directory have to have an Icon/r file with the Icon Family Data. 35 | @param path The path for which the Icon Family Data is required. 36 | @result A NSData contain the Icon Family Data, returns nil if iconFamilyDataForURL: failed. 37 | */ 38 | + (NSData *)iconFamilyDataForFile:(NSString *)path; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /TSDelegatingDropZoneView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSDelegatingDropZoneView.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-25. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSDelegatingDropZoneView.h" 11 | 12 | 13 | @implementation TSDelegatingDropZoneView 14 | 15 | 16 | - (void)setDraggingDestination:(NSView *)aDraggingDestination { 17 | [self unregisterDraggedTypes]; 18 | draggingDestination = aDraggingDestination; 19 | [self registerForDraggedTypes:[draggingDestination registeredDraggedTypes]]; 20 | } 21 | 22 | - (NSView *)draggingDestination { 23 | return draggingDestination; 24 | } 25 | 26 | - (void)setDropHovering:(BOOL)dh { 27 | if (dh != drophovering) { 28 | drophovering = dh; 29 | [self setNeedsDisplay:YES]; 30 | } 31 | } 32 | 33 | - (NSDragOperation)draggingEntered:(id )sender { 34 | NSDragOperation operation = [draggingDestination draggingEntered:sender]; 35 | [self setDropHovering:(operation != NSDragOperationNone)]; 36 | return operation; 37 | } 38 | 39 | - (NSDragOperation)draggingUpdated:(id )sender { 40 | NSDragOperation operation = [draggingDestination draggingUpdated:sender]; 41 | [self setDropHovering:(operation != NSDragOperationNone)]; 42 | return operation; 43 | } 44 | 45 | - (void)draggingEnded:(id )sender { 46 | if ([draggingDestination respondsToSelector:@selector(draggingEnded:)]) { 47 | [draggingDestination draggingEnded:sender]; 48 | } 49 | [self setDropHovering:NO]; 50 | } 51 | 52 | - (void)draggingExited:(id )sender { 53 | [draggingDestination draggingExited:sender]; 54 | [self setDropHovering:NO]; 55 | } 56 | 57 | - (BOOL)performDragOperation:(id )sender { 58 | BOOL result = [draggingDestination performDragOperation:sender]; 59 | [self setDropHovering:result]; 60 | return result; 61 | } 62 | 63 | - (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender { 64 | BOOL result = [draggingDestination prepareForDragOperation:sender]; 65 | [self setDropHovering:result]; 66 | return result; 67 | } 68 | 69 | - (BOOL)wantsPeriodicDraggingUpdates { 70 | return YES; 71 | } 72 | 73 | - (void)concludeDragOperation:(id )sender { 74 | [draggingDestination concludeDragOperation:sender]; 75 | [self setDropHovering:NO]; 76 | } 77 | 78 | - (BOOL)isOpaque { 79 | return NO; 80 | } 81 | 82 | - (void)drawRect:(NSRect)rect { 83 | if (drophovering) { 84 | if (!NSEqualSizes(rect.size,[self frame].size)) { 85 | [self setNeedsDisplay:YES]; 86 | return; 87 | } 88 | [[NSColor selectedControlColor] setStroke]; 89 | } else { 90 | [[NSColor clearColor] setStroke]; 91 | } 92 | [NSBezierPath strokeRect:rect]; 93 | [NSBezierPath strokeRect:NSInsetRect(rect,1.0,1.0)]; 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /NSString+CarbonFSRefCreation.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2001-2010 Troy N. Stephens 3 | 4 | Use and distribution of this source code is governed by the MIT License, whose terms are as follows. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | #import "NSString+CarbonFSRefCreation.h" 14 | 15 | @implementation NSString (CarbonFSRefCreation) 16 | 17 | - (BOOL) getFSRef:(FSRef*)fsRef createFileIfNecessary:(BOOL)createFile 18 | { 19 | NSFileManager* fileManager = [NSFileManager defaultManager]; 20 | CFURLRef urlRef; 21 | Boolean gotFSRef; 22 | 23 | // Check whether the file exists already. If not, create an empty file if requested. 24 | if (![fileManager fileExistsAtPath:self]) { 25 | if (createFile) { 26 | if (![@"" writeToFile:self atomically:YES]) { 27 | return NO; 28 | } 29 | } else { 30 | return NO; 31 | } 32 | } 33 | 34 | // Create a CFURL with the specified POSIX path. 35 | urlRef = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, 36 | (CFStringRef) self, 37 | kCFURLPOSIXPathStyle, 38 | FALSE /* isDirectory */ ); 39 | if (urlRef == NULL) { 40 | // printf( "** Couldn't make a CFURLRef for the file.\n" ); 41 | return NO; 42 | } 43 | 44 | // Try to create an FSRef from the URL. (If the specified file doesn't exist, this 45 | // function will return false, but if we've reached this code we've already insured 46 | // that the file exists.) 47 | gotFSRef = CFURLGetFSRef( urlRef, fsRef ); 48 | CFRelease( urlRef ); 49 | 50 | if (!gotFSRef) { 51 | // printf( "** Couldn't get an FSRef for the file.\n" ); 52 | return NO; 53 | } 54 | 55 | return YES; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 12 | 13 | 14 | 15 | 16 | ThisService Help 17 | 18 | 20 | 26 | 27 | 28 | 29 | 30 |
31 |
32 |
Screenshot of ThisService in action 33 |

ThisService icon ThisService

34 | 35 |

wafflesoftware.net

36 |
37 |
38 |
39 |
40 |

Instant services.

41 |

ThisService creates services using AppleScript or anything that runs on a command line (like Ruby, Perl, Python and shell scripts).

42 | 48 |

Index

49 |

Look up topics easily.

50 |
51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /TSService.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSService.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-20. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class IconFamily; 13 | 14 | typedef enum { 15 | TSServiceInputOnlyType, 16 | TSServiceOutputOnlyType, 17 | TSServiceFilterType, 18 | TSServiceNoInputOutputType 19 | } TSServiceType; 20 | 21 | typedef enum { 22 | TSServiceScriptCopied, 23 | TSServiceScriptReferenced 24 | } TSServiceScriptReferenceType; 25 | 26 | @class TSServiceTester; 27 | 28 | @interface TSService : NSObject { 29 | NSString *serviceName; 30 | NSString *serviceFileName; 31 | NSString *executableName; 32 | NSDictionary *infoPlistDictionary; 33 | IconFamily *serviceIcon; 34 | TSServiceType serviceType; 35 | TSServiceScriptReferenceType scriptReferenceType; 36 | NSArray *allInputRules; 37 | NSSet *applicationIDs; 38 | NSFileWrapper *serviceFileWrapper; 39 | NSString *pathToScriptInFileWrapper; 40 | NSString *pathToScriptOutsideService; 41 | NSURL *existingServiceURL; 42 | NSNumber *timeoutInSeconds; 43 | } 44 | + (TSService *)serviceWithServiceName:(NSString *)name 45 | serviceType:(TSServiceType)serviceType 46 | scriptReferenceType:(TSServiceScriptReferenceType)scriptReferenceType 47 | inputRules:(NSArray *)allInputRules 48 | timeoutInSeconds:(NSNumber *)timeoutInSeconds 49 | scriptPath:(NSString *)path 50 | serviceIcon:(IconFamily *)image 51 | applicationIDs:(NSSet *)applicationIDs; 52 | 53 | // returns nil if the service is not a ThisService service 54 | + (TSService *)serviceAtURL:(NSURL *)serviceURL; 55 | 56 | + (NSString *)cleanseName:(NSString *)name; 57 | + (NSString *)camelCize:(NSString *)name; 58 | 59 | - (BOOL)renameService:(NSString *)newServiceName; 60 | 61 | - (NSString *)serviceName; 62 | - (NSString *)serviceFileName; 63 | - (NSURL *)existingServiceURL; 64 | 65 | // returns an NSFileWrapper to a reconstructed, upgraded service with the info plist rebuilt and the latest ServiceSkeleton 66 | - (NSFileWrapper *)upgradedServiceFileWrapper; 67 | 68 | // for a referenced-script-style-service, instates the reference alias (which can only be done to a path/URL and not to a file wrapper) 69 | // for a copy-style-service, does nothing 70 | - (void)writeReferenceAliasForServiceAtURL:(NSURL *)serviceURL; 71 | 72 | // chmods the script skeleton and runs the service once with a specific parameter that tells it to register itself and quit 73 | - (void)installServiceAfterFileWrapperWrittenAtURL:(NSURL *)serviceURL; 74 | 75 | - (TSServiceTester *)testRunServiceAfterFileWrapperWrittenAtURL:(NSURL *)serviceURL; 76 | - (BOOL)freshenScriptInFileWrapperWrittenAtURL:(NSURL *)serviceURL; 77 | 78 | // key is NSURL *, value is TSService *. 79 | + (NSDictionary *)allServicesInUserBoundary; 80 | 81 | - (NSString *)pathToScriptOutsideService; 82 | 83 | @property (readonly) BOOL supportsOutput; 84 | @property (readonly) BOOL supportsInput; 85 | 86 | - (NSTimeInterval)effectiveTimeout; 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/RSS.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD License 4 | 5 | Copyright (c) 2002, Brent Simmons 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, 9 | are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | * Neither the name of ranchero.com or Brent Simmons nor the names of its 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 24 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | 32 | */ 33 | 34 | /* 35 | RSS.h 36 | A class for reading RSS feeds. 37 | 38 | Created by Brent Simmons on Wed Apr 17 2002. 39 | Copyright (c) 2002 Brent Simmons. All rights reserved. 40 | */ 41 | 42 | 43 | #import 44 | #import 45 | #import "NSString+extras.h" 46 | 47 | 48 | @interface RSS : NSObject { 49 | 50 | NSDictionary *headerItems; 51 | NSMutableArray *newsItems; 52 | NSString *version; 53 | 54 | BOOL flRdf; 55 | BOOL normalize; 56 | } 57 | 58 | 59 | /*Public*/ 60 | 61 | - (RSS *) initWithTitle: (NSString *) title andDescription: (NSString *) description; 62 | 63 | - (RSS *) initWithData: (NSData *) rssData normalize: (BOOL) fl; 64 | 65 | - (RSS *) initWithURL: (NSURL *) url normalize: (BOOL) fl; 66 | - (RSS *) initWithURL: (NSURL *) url normalize: (BOOL) fl userAgent:(NSString *)userAgent; 67 | 68 | - (NSDictionary *) headerItems; 69 | 70 | - (NSMutableArray *) newsItems; 71 | 72 | - (NSString *) version; 73 | 74 | // AMM's extensions for Sparkle 75 | - (NSDictionary *)newestItem; 76 | 77 | 78 | /*Private*/ 79 | 80 | - (void) createheaderdictionary: (CFXMLTreeRef) tree; 81 | 82 | - (void) createitemsarray: (CFXMLTreeRef) tree; 83 | 84 | - (void) setversionstring: (CFXMLTreeRef) tree; 85 | 86 | - (void) flattenimagechildren: (CFXMLTreeRef) tree into: (NSMutableDictionary *) dictionary; 87 | 88 | - (void) flattensourceattributes: (CFXMLNodeRef) node into: (NSMutableDictionary *) dictionary; 89 | 90 | - (CFXMLTreeRef) getchanneltree: (CFXMLTreeRef) tree; 91 | 92 | - (CFXMLTreeRef) getnamedtree: (CFXMLTreeRef) currentTree name: (NSString *) name; 93 | 94 | - (void) normalizeRSSItem: (NSMutableDictionary *) rssItem; 95 | 96 | - (NSString *) getelementvalue: (CFXMLTreeRef) tree; 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /TSServiceTestWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceTestWindowController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-05. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import 12 | 13 | @class TSServiceTestWindowController; 14 | 15 | #import "TSServiceTester.h" 16 | 17 | @class WFMachTime; 18 | 19 | @protocol TSServiceTestWindowControllerDelegate 20 | - (void)testingDone:(TSServiceTestWindowController *)testWindowController; 21 | - (void)testing:(TSServiceTestWindowController *)testWindowController failedFatally:(NSError *)error; 22 | - (void)testingCancelled:(TSServiceTestWindowController *)testWindowController; 23 | @end 24 | 25 | 26 | @interface TSServiceTestWindowController : NSWindowController { 27 | TSServiceTester *_tester; 28 | id _delegate; 29 | NSTextField *_statusLabel; 30 | NSProgressIndicator *_statusIndicator; 31 | NSTextField *_outputDirtyLabel; 32 | NSTextField *_testServiceHeadlineLabel; 33 | NSTextView *_inputTextView; 34 | NSTextView *_outputTextView; 35 | NSScrollView *_inputTextScrollView; 36 | NSScrollView *_outputTextScrollView; 37 | NSButton *_createServiceButton; 38 | NSButton *_doTestService; 39 | NSTextView *_logTextView; 40 | NSTextField *_durationLabel; 41 | NSBox *_noInputBox; 42 | NSBox *_noOutputBox; 43 | NSTextField *_inputLabel; 44 | NSTextField *_inputInstructionsLabel; 45 | NSTextField *_outputLabel; 46 | NSNumber *_previousRunTime; 47 | WFMachTime *_ongoingTimer; 48 | 49 | BOOL supportsInput; 50 | BOOL supportsOutput; 51 | 52 | BOOL _pairingCompleted; 53 | 54 | BOOL doomed; 55 | NSButton *_testServiceButton; 56 | } 57 | -(TSServiceTestWindowController *)initWithTester:(TSServiceTester *)tester; 58 | 59 | @property (assign) id delegate; 60 | 61 | @property (assign) IBOutlet NSTextField *statusLabel; 62 | @property (assign) IBOutlet NSProgressIndicator *statusIndicator; 63 | @property (assign) IBOutlet NSTextField *outputDirtyLabel; 64 | @property (assign) IBOutlet NSTextField *testServiceHeadlineLabel; 65 | @property (assign) IBOutlet NSTextView *inputTextView; 66 | @property (assign) IBOutlet NSTextView *outputTextView; 67 | @property (assign) IBOutlet NSScrollView *inputTextScrollView; 68 | @property (assign) IBOutlet NSScrollView *outputTextScrollView; 69 | @property (assign) IBOutlet NSButton *createServiceButton; 70 | 71 | - (IBAction)doTestService:(id)sender; 72 | - (IBAction)help:(id)sender; 73 | 74 | @property (assign) IBOutlet NSTextView *logTextView; 75 | @property (assign) IBOutlet NSTextField *durationLabel; 76 | 77 | @property (assign) IBOutlet NSBox *noInputBox; 78 | @property (assign) IBOutlet NSBox *noOutputBox; 79 | @property (assign) IBOutlet NSTextField *inputLabel; 80 | @property (assign) IBOutlet NSTextField *inputInstructionsLabel; 81 | @property (assign) IBOutlet NSTextField *outputLabel; 82 | 83 | @property (retain) NSNumber *previousRunTime; 84 | @property (retain) WFMachTime *ongoingTimer; 85 | 86 | - (IBAction)cancel:(id)sender; 87 | - (IBAction)createService:(id)sender; 88 | @property (assign) IBOutlet NSButton *testServiceButton; 89 | 90 | @property BOOL doomed; // failed during initialization 91 | @end -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/index.html: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | Index 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 |
31 | Index
32 | 33 |
34 | 35 | 36 | 39 | 40 | 43 | 44 | 47 | 48 | 51 | 52 | 55 | 56 | 59 | 60 | 63 | 64 | 67 | 68 | 71 | 72 | 75 | 76 | 79 | 80 |
37 |

Reliable conditions for standard service scripts

38 |
41 |

Considerations when sharing a service

42 |
45 |

Writing service scripts

46 |
49 |

Testing a service using the test sheet

50 |
53 |

What is a service?

54 |
57 |

Sharing a service

58 |
61 |

Writing a standard service script

62 |
65 |

Writing an AppleScript service script

66 |
69 |

Preparing to assemble a service

70 |
73 |

Reliable conditions for AppleScript service scripts

74 |
77 |

How to create a service

78 |
81 |
82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/sharingconsiderations.html: -------------------------------------------------------------------------------- 1 | 3 | 11 | 15 | 16 | 17 | 18 | Considerations when sharing a service 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 |
32 |
ThisService Icon
33 |
34 |

Considerations when sharing a service

35 |
36 | 37 |

When you share a service written in ThisService, bear in mind that most languages in which you can write your service script are interpreted, meaning the full source code is available for anyone to see. Because of this you may want to place a comment in your service script stating copyright and the license under which people can reuse your code, if any.

38 |

To help reach people interested in services, you may want to consider submitting it to the official ThisService service archive. For more information, visit the ThisService web site.

39 | 40 |

See also

41 |

Sharing a service
42 | Sharing services Topics

46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /TSCreateServiceViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TSCreateServiceViewController.h 3 | // ThisService 4 | // 5 | // Created by Jesper on 2006-10-28. 6 | // Copyright 2006-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | 12 | @class WFFilePicker, SRRecorderControl, TSModeMatrix; 13 | #import "TSViewController.h" 14 | #import "TSCheckedListDataSource.h" 15 | #import "TSServiceInputRulesWindowController.h" 16 | #import "TSServiceAppFilterWindowController.h" 17 | #import "TSServiceTestWindowController.h" 18 | 19 | @class TSServiceInputRules, TSStubbornImageView, TSServiceAppFilter; 20 | 21 | #import "TSService.h" 22 | 23 | #import "TSStubbornImageView.h" 24 | 25 | #import "TSExtraCollectionView.h" 26 | 27 | @interface TSCreateServiceViewController : TSViewController { 28 | 29 | IBOutlet WFFilePicker *filePicker; 30 | IBOutlet TSStubbornImageView *iconView; 31 | IBOutlet NSTextField *iconLabel; 32 | IBOutlet NSView *iconDropZone; 33 | 34 | IBOutlet NSTextField *appFilterStatusLabel; 35 | 36 | // TSServiceType serviceType; 37 | BOOL takesInput; 38 | BOOL producesOutput; 39 | NSString *serviceName; 40 | TSServiceScriptReferenceType referenceType; 41 | 42 | NSString *pathToUpcomingService; 43 | TSService *upcomingService; 44 | 45 | NSSize baseSize; 46 | CGFloat extraIncrement; 47 | 48 | NSString *pathToLatestService; 49 | NSDictionary *serviceBeingCreated; 50 | 51 | BOOL showsAdvancedOptions; 52 | float advancedOptionsHeight; 53 | BOOL animationBlocks; 54 | 55 | TSServiceInputRulesWindowController *inputRulesWindowController; 56 | TSServiceInputRules *inputRules; 57 | 58 | TSServiceAppFilterWindowController *appFilterWindowController; 59 | TSServiceAppFilter *appFilter; 60 | 61 | TSServiceTestWindowController *testWindowController; 62 | 63 | NSInteger timeoutInSeconds; 64 | 65 | IBOutlet NSView *appFilterCollectionItemView; 66 | IBOutlet NSView *inputRulesCollectionItemView; 67 | IBOutlet NSView *serviceIconCollectionItemView; 68 | IBOutlet NSView *referenceServiceCollectionItemView; 69 | 70 | IBOutlet NSView *timeoutCollectionItemView; 71 | 72 | IBOutlet TSExtraCollectionView *extrasCollectionView; 73 | IBOutlet NSPopUpButton *extrasDropDown; 74 | IBOutlet NSScrollView *extrasScrollView; 75 | } 76 | - (IBAction)addAppFilterExtra:(id)sender; 77 | - (IBAction)addInputRulesExtra:(id)sender; 78 | - (IBAction)addServiceIconExtra:(id)sender; 79 | - (IBAction)addReferenceServiceExtra:(id)sender; 80 | - (IBAction)addTimeoutExtra:(id)sender; 81 | 82 | @property (retain) NSString *pathToUpcomingService; 83 | @property (retain) TSService *upcomingService; 84 | 85 | @property NSInteger timeoutInSeconds; 86 | 87 | @property BOOL takesInput; 88 | @property BOOL producesOutput; 89 | 90 | - (IBAction)chooseImage:(id)sender; 91 | 92 | + (NSString *)stringByCleansingString:(NSString *)string fromCharactersNotInSet:(NSCharacterSet *)set; 93 | + (NSString *)cleanseName:(NSString *)name; 94 | + (NSString *)sanitizeName:(NSString *)name; 95 | + (NSString *)camelCize:(NSString *)name; 96 | 97 | - (IBAction)produceService:(id)sender; 98 | 99 | - (IBAction)help:(id)sender; 100 | 101 | - (IBAction)specifyInputRules:(id)sender; 102 | - (IBAction)specifyAppFilter:(id)sender; 103 | 104 | @end -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/writingscripts.html: -------------------------------------------------------------------------------- 1 | 3 | 11 | 12 | 13 | 14 | Writing service scripts 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 |
28 |
ThisService Icon
29 |
30 |

Writing service scripts

31 |
32 | 33 |

A service script is what makes a service you create with ThisService do what it does. Service scripts can be written in AppleScript or in other languages, and ThisService Help details the conventions ThisService-generated services will use to communicate with your service script.

34 |

If you are planning to share your service with others later on, take care to ensure that you don't rely on external libraries (like Ruby modules not shipping with the standard Mac OS X Ruby installation) and that, if applicable, you can handle the full range of Unicode characters that UTF-8 affords.

35 |

ThisService comes with a few service scripts starting points for AppleScript, Ruby, Perl and Python, containing skeletal scripts to which you can add your own code. For standard service scripts, the starting points scripts supply the lines of codes to read from STDIN and to make sure input and output are known to be in UTF-8.

36 | 37 |

See also

38 |

Writing a standard service script
39 | Writing an AppleScript service script
40 | Reliable conditions for standard service scripts
41 | Reliable conditions for AppleScript service scripts
42 | Writing scripts Topics

46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/explainingservices.html: -------------------------------------------------------------------------------- 1 | 3 | 11 | 12 | 13 | 14 | What is a service? 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 |
28 |
ThisService Icon
29 |
30 |

What is a service?

31 |
32 | 33 |

A service is a concept in Mac OS X of a small and efficient bit of code that can work as part of any application. All services are contained in the Services submenu located in the application menu (named for the currently running application) to the left of the menu bar.

34 |

Some services take the current selection and does something with it, some produce output into the current window and some (commonly known as "filters") process the current selection and outputs it in a different form. For example, a Calculator service of the filter type may let you select a calculation (like 6 * 7) and output in place the result (like 42).

35 |

Most services are provided by applications, like Safari's service to search for the selected text on Google, or Mail's service to create a new mail message using the selected text or images. However, there are also standalone service bundles whose only purpose is to provide services. The service bundles are hard for most programmers to code as they are written using Apple's Cocoa coding framework, which requires you learn the relatively low-level Objective-C programming language.

36 |

ThisService lets you create service bundles whose service is written not in Objective-C, but in almost any other language you'd like to use (including AppleScript and many other popular languages, like Ruby, Python, Perl and PHP).

37 | 38 |

See also

39 |

Service basics Topics

43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdater.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 1/4/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | // $Id: SUUpdater.h 87 2007-07-05 19:16:34Z evands $ 9 | // $HeadURL: http://sparkleplus.googlecode.com/svn/trunk/SUUpdater.h $ 10 | 11 | #import 12 | 13 | // Before you use Sparkle in your app, you must set SUFeedURL in Info.plist to the 14 | // address of the appcast on your webserver. If you don't already have an 15 | // appcast, please see the Sparkle documentation to learn about how to set one up. 16 | 17 | // .zip, .dmg, .tar, .tbz, .tgz archives are supported at this time. 18 | 19 | // By default, Sparkle offers to show the user the release notes of the build they'll be 20 | // getting, which it assumes are in the description (or body) field of the relevant RSS item. 21 | // Set SUShowReleaseNotes to in Info.plist to hide the button. 22 | 23 | @class SUAppcastItem, SUUpdateAlert, SUStatusController; 24 | @interface SUUpdater : NSObject { 25 | SUAppcastItem *updateItem; 26 | 27 | SUStatusController *statusController; 28 | SUUpdateAlert *updateAlert; 29 | 30 | NSURLDownload *downloader; 31 | NSString *downloadPath; 32 | 33 | NSTimer *checkTimer; 34 | NSTimeInterval checkInterval; 35 | 36 | BOOL verbose; 37 | BOOL updateInProgress; 38 | 39 | id delegate; 40 | 41 | IBOutlet NSWindow *profileMoreInfoWindow; 42 | IBOutlet NSView *profileMoreInfoView; 43 | IBOutlet NSButton *profileMoreInfoButton; 44 | IBOutlet NSTextField *checkForUpdatesText; 45 | BOOL moreInfoVisible; 46 | } 47 | 48 | // This IBAction is meant for a main menu item. Hook up any menu item to this action, 49 | // and Sparkle will check for updates and report back its findings verbosely. 50 | - (IBAction)checkForUpdates:sender; 51 | 52 | // This method is similar to the above, but it's intended for updates initiated by 53 | // the computer instead of by the user. It does not alert the user when he is up to date, 54 | // and it remains silent about network errors in fetching the feed. This is what you 55 | // want to call to update programmatically; only use checkForUpdates: with buttons and menu items. 56 | - (void)checkForUpdatesInBackground; 57 | 58 | // This method allows you to schedule a check to run every time interval. You can 59 | // pass 0 to this method to cancel a previously scheduled timer. You probably don't want 60 | // to call this directly: if you set a SUScheduledCheckInterval key in Info.plist or 61 | // the user defaults, Sparkle will set this up for you automatically on startup. You might 62 | // just want to call this every time the user changes the setting in the preferences. 63 | - (void)scheduleCheckWithInterval:(NSTimeInterval)interval; 64 | 65 | // Get information that will be included with update-check requests. This method can be used 66 | // whether or not profile information is enabled. Use this method to show the user what kind 67 | // of information will be included. This method will invoke -updaterCustomizeProfileInfo: on 68 | // the delegate, if it's implemented. 69 | - (NSMutableArray *)systemProfileInformationArray; 70 | 71 | - (IBAction)closeProfileInfoSheet:(id)sender; 72 | 73 | @end 74 | @interface NSObject (SUUpdaterDelegate) 75 | // Specify whether the updater should include system-profile information with update checks. 76 | - (BOOL)updaterShouldSendProfileInfo; 77 | // This method gives the delegate the opportunity to customize the information that will 78 | // be included with update checks. Add or remove items from the dictionary as desired. 79 | - (NSMutableArray *)updaterCustomizeProfileInfo:(NSMutableArray *)profileInfo; 80 | // This method lets the delegate customize how versions are compared 81 | - (NSComparisonResult)compareVersion:(NSString *)appcastVersion toVersion:(NSString *)appVersion; 82 | @end 83 | -------------------------------------------------------------------------------- /English.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1187 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw12240\paperh15840\viewkind0 5 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 6 | 7 | \f0\b\fs12 \cf0 \ 8 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 9 | 10 | \b0\fs24 \cf0 Turn scripts into system services.\ 11 | {\field{\*\fldinst{HYPERLINK "http://wafflesoftware.net/thisservice/"}}{\fldrslt http://wafflesoftware.net/thisservice/}}\ 12 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 13 | 14 | \fs18 \cf0 \ 15 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 16 | 17 | \b\fs28 \cf0 Special thanks to:\ 18 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 19 | 20 | \fs14 \cf0 \ 21 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 22 | 23 | \fs24 \cf0 John Gruber 24 | \b0 \ 25 | Original concept.\ 26 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 27 | {\field{\*\fldinst{HYPERLINK "http://daringfireball.net/"}}{\fldrslt 28 | \fs20 \cf0 daringfireball.net}}\ 29 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 30 | 31 | \fs14 \cf0 \ 32 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 33 | 34 | \b\fs24 \cf0 Peter Hosey 35 | \b0 \ 36 | Invaluable debugging help and cheerleading.\ 37 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 38 | {\field{\*\fldinst{HYPERLINK "http://boredzo.org/"}}{\fldrslt 39 | \fs20 \cf0 boredzo.org}} 40 | \fs20 \ 41 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 42 | 43 | \fs14 \cf0 \ 44 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 45 | 46 | \b\fs24 \cf0 Brent Simmons 47 | \b0 \ 48 | Apple Event advice.\ 49 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 50 | {\field{\*\fldinst{HYPERLINK "http://inessential.com/"}}{\fldrslt 51 | \fs20 \cf0 inessential.com}} 52 | \b\fs22 \ 53 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 54 | 55 | \fs14 \cf0 \ 56 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 57 | 58 | \fs24 \cf0 All beta testers 59 | \b0\fs20 \ 60 | \ 61 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 62 | 63 | \b\fs28 \cf0 Code: 64 | \b0 \ 65 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 66 | 67 | \b\fs14 \cf0 \ 68 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 69 | {\field{\*\fldinst{HYPERLINK "http://homepage.mac.com/nathan_day/"}}{\fldrslt 70 | \fs24 \cf0 NDAlias}} 71 | \b0 \ 72 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 73 | 74 | \b\fs8 \cf0 \ 75 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 76 | {\field{\*\fldinst{HYPERLINK "http://iconfamily.sourceforge.net/"}}{\fldrslt 77 | \fs24 \cf0 IconFamily}} 78 | \b0\fs14 \ 79 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 80 | 81 | \b\fs8 \cf0 \ 82 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc 83 | {\field{\*\fldinst{HYPERLINK "http://weblog.scifihifi.com/2004/04/15/calling-applescript-handlers-from-cocoa"}}{\fldrslt 84 | \fs24 \cf0 NSAppleScript+HandlerCalls}} 85 | \b0\fs14 \ 86 | } -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/testservice.html: -------------------------------------------------------------------------------- 1 | 9 | 13 | 14 | 15 | 16 | Testing a service using the test sheet 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
30 |
ThisService Icon
31 |
32 |

Testing a service using the test sheet

33 |
34 | 35 |

When creating a service, you can test the service using the test sheet. At this stage, the service is not yet created for use in other applications.

36 |
37 |

To test a service:

38 |
    39 |
  1. Follow the appropriate steps to create a service until the test sheet comes up.
  2. 40 |
  3. The test sheet has everything you need to test your service before it is created. 41 |
      42 |
    • There is an Input field to enter the input to supply to your service, if it accepts input.
    • 43 |
    • There is an Output field that shows the output produced by your service, if it produces output.
    • 44 |
    • Click the Test Service button to run the service. Until the service script has finished executing, a progress indicator is shown in the top right corner.
    • 45 |
    • Every time the service is run, the service script is reloaded from its original location. This means that you can keep the test sheet open and make changes to the service script as you test different scenarios and fix bugs.
    • 46 |
    47 |
  4. 48 |
  5. When you're finished testing, or if you don't want to test, click Finish Testing and Create Service to have ThisService create the service and install it.
    49 |
    50 | Alternatively, to abort testing without creating the service and go back to defining the service, click Cancel.
  6. 51 |
52 |
53 | 54 |

See also

55 |

How to create a service
56 | Service basics Topics

60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /NDAlias+AliasFile.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header NDAlias+AliasFile 3 | @abstract Defines a category of NDAlias 4 | @discussion The category NDAlias+AliasFile add methods for reading and saving alias files. 5 | */ 6 | 7 | #import 8 | #import "NDAlias.h" 9 | 10 | /*! 11 | @category NDAlias(AliasFile) 12 | @abstract A category of the class NDAlias 13 | @discussion This category add aditional functionality to NDAlias for reading and writting NDAlias instances to Finder alias files. Though this could be used for archiving purposed, the methods of the adopted protocol NSCoding are proble better suited. The method of NDAlias (AliasFile) are mainly for creating alias files that are visible in Finder to the user. 14 |

As well as the class NDAlias and the classes and categories it uses, NDAlias (AliasFile) also requires the class NDResourceFork and it's category NDResourceFork (OtherSorces). If the additional functioanlity of NDAlias (AliasFile) is not required then the files for NDAlias (AliasFile), NDResourceFork and NDResourceFork (OtherSorces) can be excluded from your project.

15 | */ 16 | @interface NDAlias (AliasFile) 17 | 18 | /*! 19 | @method aliasWithContentsOfFile: 20 | @abstract Creates and initalises a NDAlias. 21 | @discussion The method aliasWithContentsOfFile: allocates and initalises an NDAlias with the alias record data within the Finder alias file pointed to by the NSString path path. 22 | @param path the path to an alias file. 23 | @result A NDAlias instance, returns nil if NDAlias creation fails. 24 | */ 25 | + (id)aliasWithContentsOfFile:(NSString *)path; 26 | /*! 27 | @method aliasWithContentsOfURL: 28 | @abstract Initalises a NDAlias. 29 | @discussion The method aliasWithContentsOfURL: allocates and initalises an NDAlias with the alias record data within the Finder NSURL alias file pointed to pay the file url URL 30 | @param URL the file url to the alias file. 31 | @result A NDAlias instance, returns nil if NDAlias creation fails. 32 | */ 33 | + (id)aliasWithContentsOfURL:(NSURL *)URL; 34 | 35 | /*! 36 | @method initWithContentsOfFile: 37 | @abstract Initalises a NDAlias. 38 | @discussion The method initWithContentsOfFile: initalises the reciever with the alias record data within the Finder alias file pointed to by the NSString path path 39 | @param path the path to the alias file. 40 | @result An initalises NDAlias, returns nil if initalises fails. 41 | */ 42 | - (id)initWithContentsOfFile:(NSString *)path; 43 | /*! 44 | @method initWithContentsOfURL: 45 | @abstract Initalises a NDAlias. 46 | @discussion The method initWithContentsOfURL: initalises the reciever with the alias record data within the Finder NSURL alias file pointed to pay the file url URL. 47 | @param URL the file url to the alias file. 48 | @result An initalises NDAlias, returns nil if initalises fails. 49 | */ 50 | - (id)initWithContentsOfURL:(NSURL *)URL; 51 | 52 | /*! 53 | @method writeToFile: 54 | @abstract Writes an NDAlias to a Finder alias file. 55 | @discussion The method writeToFile: writes the alias record data contained within the reciever to a Finder alias file at the path path. writeToFile: can be used to create alias files that the user can see in Finder and use. 56 | @param path the path for the alias file. Not the path the alias record represents. 57 | @result <#result#> 58 | */ 59 | - (BOOL)writeToFile:(NSString *)path; 60 | /*! 61 | @method writeToURL: 62 | @abstract Writes an NDAlias to a Finder alias file. 63 | @discussion The method writeToURL: writes the alias record data contained within the reciever to a Finder alias file at the file url URL. writeToFile: can be used to create alias files that the user can see in Finder and use. 64 | @param URL the file url for the alias file. Not the file url the alias record represents. 65 | @result <#result#> 66 | */ 67 | - (BOOL)writeToURL:(NSURL *)URL; 68 | 69 | @end -------------------------------------------------------------------------------- /ServiceSkeleton/ServiceSkeleton_main.m: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceSkeleton_main.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2006-10-28. 6 | // Copyright 2006-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import 11 | #import "ServiceSkeletonMagic.h" 12 | 13 | int main (int argc, char *argv[]) { 14 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 15 | ServiceSkeletonMagic *serviceProvider = [[ServiceSkeletonMagic alloc] init]; 16 | 17 | BOOL printScriptURLAndQuit = NO; 18 | BOOL justRegister = NO; 19 | NSString *testingServiceConnectionName = nil; 20 | BOOL isTestingService = NO; 21 | 22 | NSArray *arguments = [[NSProcessInfo processInfo] arguments]; 23 | NSString *testingServicePrefix = @"-THISSERVICE_TESTING_SERVICE__"; 24 | for (NSString *argument in arguments) { 25 | if ([argument isEqualToString:@"-THISSERVICE_PRINT_SCRIPT_URL_AND_QUIT"]) { 26 | printScriptURLAndQuit = YES; 27 | } 28 | if ([argument isEqualToString:@"-THISSERVICE_REGISTER_SERVICE"]) { 29 | justRegister = YES; 30 | } 31 | if ([argument hasPrefix:testingServicePrefix]) { 32 | testingServiceConnectionName = [argument substringFromIndex:testingServicePrefix.length]; 33 | if (testingServiceConnectionName.length == 0) { 34 | testingServiceConnectionName = nil; 35 | } else { 36 | isTestingService = YES; 37 | } 38 | } 39 | } 40 | 41 | 42 | // This supports the discovery of the script's location, used in reference-style services. 43 | if (printScriptURLAndQuit) { 44 | // NSLog(@"-THISSERVICE_PRINT_SCRIPT_URL_AND_QUIT"); 45 | NSURL *scriptURL = [serviceProvider urlToScript]; 46 | printf("%s\n", [[scriptURL absoluteString] UTF8String]); 47 | goto shutdowndirectlyjustexiting; // http://xkcd.com/292/ 48 | } 49 | 50 | NSString *portName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"ServiceSkeletonPortName"]; 51 | 52 | NSString *friendlyName = [NSString stringWithFormat:@"%@Service", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"ServiceSkeletonSuitableExecutableName"]]; 53 | //NSLog(@"program name: %s", argv[0]); 54 | [[NSProcessInfo processInfo] setProcessName:friendlyName]; 55 | 56 | NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; 57 | BOOL logging = [ud boolForKey:@"DebugLogging"]; 58 | [ServiceSkeletonMagic setLogging:logging]; 59 | 60 | if (!isTestingService) { 61 | SLog(@"Starting service: %@ (%@)", [[NSProcessInfo processInfo] processName], portName); 62 | 63 | NSRegisterServicesProvider(serviceProvider, portName); 64 | NSUpdateDynamicServices(); 65 | 66 | SLog(@"Registered %@ for services!", friendlyName); 67 | } else { 68 | SLog(@"Testing service %@", friendlyName); 69 | } 70 | 71 | if (justRegister) { 72 | SLog(@"Exiting since we're just registering the service."); 73 | goto shutdowndirectly; // OMG SPAGHETTI CODE!1 74 | } 75 | 76 | NSRunLoop *currentLoop = [NSRunLoop currentRunLoop]; // ensure created 77 | 78 | 79 | if (isTestingService) { 80 | [serviceProvider performSelectorOnMainThread:@selector(setUpServiceTesting:) withObject:testingServiceConnectionName waitUntilDone:NO]; 81 | } else { 82 | [serviceProvider bumpBailingTimer]; 83 | } 84 | 85 | @try { 86 | while ([ServiceSkeletonMagic shouldKeepRunning] && [currentLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:3]]) { 87 | // NSLog(@"#RL# run loop tick; shouldKeepRunning is %d", [ServiceSkeletonMagic shouldKeepRunning]); 88 | ; 89 | } 90 | } @catch (NSException *localException) { 91 | SLog(@"%@", localException); 92 | } 93 | 94 | shutdowndirectly: 95 | SLog(@"Exiting service %@...", friendlyName); 96 | shutdowndirectlyjustexiting: 97 | [serviceProvider release]; 98 | [pool release]; 99 | 100 | exit(0); // ensure the process exit status is 0 101 | return 0; // ...and make main fit the ANSI spec. 102 | } 103 | -------------------------------------------------------------------------------- /ShortcutRecorder/SRCommon.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRCommon.m (selected, extracted parts) 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors (of these parts): 10 | // Jesper 11 | 12 | #import "SRCommon.h" 13 | 14 | static NSMutableDictionary *SRSharedImageCache = nil; 15 | 16 | @interface SRSharedImageProvider (Private) 17 | + (void)_drawSRRemoveShortcut:(id)anNSCustomImageRep; 18 | + (NSValue *)_sizeSRRemoveShortcut; 19 | + (void)_drawSRRemoveShortcutRollover:(id)anNSCustomImageRep; 20 | + (NSValue *)_sizeSRRemoveShortcutRollover; 21 | + (void)_drawSRRemoveShortcutPressed:(id)anNSCustomImageRep; 22 | + (NSValue *)_sizeSRRemoveShortcutPressed; 23 | 24 | + (void)_drawARemoveShortcutBoxUsingRep:(id)anNSCustomImageRep opacity:(double)opacity; 25 | @end 26 | 27 | @implementation SRSharedImageProvider 28 | + (NSImage *)supportingImageWithName:(NSString *)name { 29 | // NSLog(@"supportingImageWithName: %@", name); 30 | if (nil == SRSharedImageCache) { 31 | SRSharedImageCache = [[NSMutableDictionary dictionary] retain]; 32 | // NSLog(@"inited cache"); 33 | } 34 | NSImage *cachedImage = nil; 35 | if (nil != (cachedImage = [SRSharedImageCache objectForKey:name])) { 36 | // NSLog(@"returned cached image: %@", cachedImage); 37 | return cachedImage; 38 | } 39 | 40 | // NSLog(@"constructing image"); 41 | NSSize size; 42 | NSValue *sizeValue = [self performSelector:NSSelectorFromString([NSString stringWithFormat:@"_size%@", name])]; 43 | size = [sizeValue sizeValue]; 44 | // NSLog(@"size: %@", NSStringFromSize(size)); 45 | 46 | NSCustomImageRep *customImageRep = [[NSCustomImageRep alloc] initWithDrawSelector:NSSelectorFromString([NSString stringWithFormat:@"_draw%@:", name]) delegate:self]; 47 | [customImageRep setSize:size]; 48 | [customImageRep setAlpha:YES]; 49 | // NSLog(@"created customImageRep: %@", customImageRep); 50 | NSImage *returnImage = [[NSImage alloc] initWithSize:size]; 51 | [returnImage addRepresentation:[customImageRep autorelease]]; 52 | [returnImage setScalesWhenResized:YES]; 53 | [SRSharedImageCache setObject:returnImage forKey:name]; 54 | 55 | // NSLog(@"returned image: %@", returnImage); 56 | return [returnImage autorelease]; 57 | } 58 | @end 59 | 60 | @implementation SRSharedImageProvider (Private) 61 | 62 | #define MakeRelativePoint(x,y) NSMakePoint(x*hScale, y*vScale) 63 | 64 | + (NSValue *)_sizeSRRemoveShortcut { 65 | return [NSValue valueWithSize:NSMakeSize(14.0,14.0)]; 66 | } 67 | + (NSValue *)_sizeSRRemoveShortcutRollover { return [self _sizeSRRemoveShortcut]; } 68 | + (NSValue *)_sizeSRRemoveShortcutPressed { return [self _sizeSRRemoveShortcut]; } 69 | + (void)_drawARemoveShortcutBoxUsingRep:(id)anNSCustomImageRep opacity:(double)opacity { 70 | 71 | // NSLog(@"drawARemoveShortcutBoxUsingRep: %@ opacity: %f", anNSCustomImageRep, opacity); 72 | 73 | NSCustomImageRep *rep = anNSCustomImageRep; 74 | NSSize size = [rep size]; 75 | [[NSColor colorWithCalibratedWhite:0.0 alpha:1-opacity] setFill]; 76 | double hScale = (size.width/14.0); 77 | double vScale = (size.height/14.0); 78 | 79 | [[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(0.0,0.0,size.width,size.height)] fill]; 80 | 81 | [[NSColor whiteColor] setStroke]; 82 | 83 | NSBezierPath *cross = [[NSBezierPath alloc] init]; 84 | [cross setLineWidth:hScale*1.2]; 85 | 86 | [cross moveToPoint:MakeRelativePoint(4,4)]; 87 | [cross lineToPoint:MakeRelativePoint(10,10)]; 88 | [cross moveToPoint:MakeRelativePoint(10,4)]; 89 | [cross lineToPoint:MakeRelativePoint(4,10)]; 90 | 91 | [cross stroke]; 92 | 93 | [cross release]; 94 | } 95 | + (void)_drawSRRemoveShortcut:(id)anNSCustomImageRep { 96 | 97 | // NSLog(@"drawSRRemoveShortcut using: %@", anNSCustomImageRep); 98 | 99 | [self _drawARemoveShortcutBoxUsingRep:anNSCustomImageRep opacity:0.75]; 100 | } 101 | + (void)_drawSRRemoveShortcutRollover:(id)anNSCustomImageRep { 102 | 103 | // NSLog(@"drawSRRemoveShortcutRollover using: %@", anNSCustomImageRep); 104 | 105 | [self _drawARemoveShortcutBoxUsingRep:anNSCustomImageRep opacity:0.65]; 106 | } 107 | + (void)_drawSRRemoveShortcutPressed:(id)anNSCustomImageRep { 108 | 109 | // NSLog(@"drawSRRemoveShortcutPressed using: %@", anNSCustomImageRep); 110 | 111 | [self _drawARemoveShortcutBoxUsingRep:anNSCustomImageRep opacity:0.55]; 112 | } 113 | @end 114 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/css/topicPage.css: -------------------------------------------------------------------------------- 1 | /* This Apple Help template put together by Andy Matuschak http://www.andymatuschak.org andy@andymatuschak.org Version 1.0 Adapted from the Safari help book--thanks, Apple! Adapted more directly from Pixen's help book. Licensed under MIT. */ /* Tiger Mac Help task_style.css v2.0f*/ /* */ body { margin: 2px 12px 12px } h1 { font-size: 11pt; font-family: "Lucida Grande", Arial, sans-serif; margin-bottom: 0 } h2 { font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; margin-top: 0; margin-bottom: -10px } h3 { font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; font-weight: bold; margin-top: -4px; margin-bottom: -4px } p { font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; text-decoration: none } ol { font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; list-style-position: outside; margin-top: 12px; margin-bottom: 12px; margin-left: -18px; padding-left: 40px } ol li { margin-top: 6px; margin-bottom: 6px } ol p { margin-top: 6px; margin-bottom: 6px } ul { font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; list-style-type: square; list-style-position: outside; margin-top: 12px; margin-bottom: 12px; margin-left: -24px; padding-left: 40px } ul li { margin-top: 6px; margin-bottom: 6px } ul p { margin-top: 6px; margin-bottom: 6px } a { color: #00f; font-size: 9pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; text-decoration: none } a:hover { color: #00f; font-family: "Lucida Grande", Arial, sans-serif; text-decoration: underline } hr { text-decoration: none; border: solid 1px #bfbfbf } td { padding: 6px } #banner { background-color: #f2f2f2; background-repeat: no-repeat; padding: -2px 6px 0; position: fixed; top: 0; left: 0; width: 100%; height: 1.2em; float: left; border: solid 1px #bfbfbf } #caticon { margin-top: 3px; margin-bottom: -3px; margin-right: 5px; float: left; } #pagetitle { margin-top: 12px; margin-bottom: 0px; margin-left: 40px; width: 88%; border: solid 1px #fff } #mainbox { margin-top: 36px; padding-right: 6px } #taskbox { background-color: #e6edff; list-style-type: decimal; list-style-position: outside; margin: 12px 0; padding: 2px 12px; border: solid 1px #bfbfbf } #taskbox h2 { margin-top: 8; margin-bottom: -4px } #machelp { position: absolute; top: 2px; left: 10px } #index { background-color: #f2f2f2; padding-right: 25px; top: 2px; right: 12px; width: auto; float: right } #next { position: absolute; top: 49px; left: 88% } #asindent { margin-left: 22px; font-size: 9pt; font-family: Verdana, Courier, sans-serif; } .bread { color: #00f; font-size: 8pt; margin: -9px 0 -6px } .leftborder { color: #00f; font-size: 8pt; margin: -9px 0 -6px; padding-top: 2px; padding-bottom: 3px; padding-left: 8px; border-left: 1px solid #bfbfbf } .mult { margin-top: -8px } .blue { background-color: #e6edff; margin-top: -3px; margin-bottom: -3px; padding-top: -3px; padding-bottom: -3px } .rightfloater { float: right; margin-left: 15px; } .rules { border-bottom: 1px dotted #ccc } .dots { border: dotted 1px #ccc } .seealso { margin-top: 4px; margin-bottom: 4px } code { font-size: 9pt; font-family: Monaco, Courier, sans-serif; background-color: #e6e6e6; border: 1px solid #cccccc; padding-left: 3px; padding-right: 3px; padding-top: 1px; padding-bottom: 1px; } samp { font-family: "Lucida Grande"; background-color: rgba(242, 242, 242, 0.55); -webkit-box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.25); border: 1px solid rgba(0, 0, 0, 0.2); padding-left: 3px; padding-right: 3px; padding-top: 1px; padding-bottom: 1px; } var { font-style: normal; font-family: "Lucida Grande"; background-color: rgba(242, 242, 242, 0.25); -webkit-box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.15); border: 1px solid rgba(0, 0, 0, 0.1); padding-left: 3px; padding-right: 3px; padding-top: 1px; padding-bottom: 1px; } #appicon { content: -webkit-image-set(url(../gfx/icon.png) 1x, url('../gfx/icon@2x.png') 2x); } -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/serviceprerequisites.html: -------------------------------------------------------------------------------- 1 | 9 | 13 | 14 | 15 | 16 | Preparing to assemble a service 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
30 |
ThisService Icon
31 |
32 |

Preparing to assemble a service

33 |
34 | 35 |

Creating a service in ThisService is simple. This topic explains what you'll have to do to prepare a service, including writing the service script, if necessary. For more information on how to actually create the service, see How to create a service.

36 |

This process differs depending on if you plan to write your own service script or use an existing script.

37 |
38 |

To prepare to assemble a service using an existing script:

39 |
    40 |
  1. Consider how the script works and what service type would be a good match. A service can a) accept input, b) produce output, c) accept input and produce output (this is commonly called a filter) and d) run without input or output.
  2. 41 |
  3. You're now ready to assemble your service.
  4. 42 |
43 |
44 |
45 |

To prepare to assemble a service using your own service script:

46 |
    47 |
  1. Consider how your service should work. Whether it should produce output, whether it should accept input; if it both produces output and accepts input, if it should return both the input text and the new text or just the new text, and so on.
  2. 48 |
  3. Decide which language to use to write your service script. When you've settled on one, read Writing service scripts.
  4. 49 |
  5. Write your service script.
  6. 50 |
  7. You're now ready to assemble and test your service.
  8. 51 |
52 |
53 | 54 |

See also

55 |

What is a service?
56 | How to create a service
57 | Service basics Topics

61 |
62 | 63 | 64 | -------------------------------------------------------------------------------- /TSCheckedListDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSCheckedListDataSource.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-14. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSCheckedListDataSource.h" 11 | 12 | 13 | @implementation TSCheckedListDataSource 14 | 15 | + (NSIndexSet *)indexSetOfSelectedIndexesForRowData:(NSArray *)rowData selectedValues:(NSSet *)values { 16 | NSMutableIndexSet *selectedIndexSet = [NSMutableIndexSet indexSet]; 17 | 18 | if ([values count] == 0) return selectedIndexSet; 19 | 20 | NSUInteger i = 0; 21 | for (NSDictionary *row in rowData) { 22 | if ([values containsObject:[row objectForKey:@"value"]]) { 23 | [selectedIndexSet addIndex:i]; 24 | } 25 | i++; 26 | } 27 | 28 | return selectedIndexSet; 29 | } 30 | 31 | - (id)initWithRowData:(NSArray *)rowData_ selectedChoices:(NSIndexSet *)selectedIndexes_ labelKey:(NSString *)labelKey_ delegate:(id)aDelegate { 32 | self = [super init]; 33 | if (self != nil) { 34 | rowData = [rowData_ retain]; 35 | NSUInteger indexGreaterThanMaxValidIndex = (selectedIndexes_ == nil ? NSNotFound : [selectedIndexes_ indexGreaterThanIndex:(NSUInteger)[rowData_ count]-1]); 36 | if (indexGreaterThanMaxValidIndex != NSNotFound) { 37 | [NSException raise:@"Can't construct checked list data source; selected choices extend beyond choices" format:@""]; 38 | } 39 | selectedIndexes = selectedIndexes_ == nil ? [[NSMutableIndexSet alloc] init] : [selectedIndexes_ mutableCopy]; 40 | delegate = aDelegate; 41 | labelKey = [labelKey_ retain]; 42 | } 43 | return self; 44 | } 45 | 46 | - (BOOL)anyChoicesSelected { 47 | return [selectedIndexes count] > 0; 48 | } 49 | 50 | - (NSArray *)selectedChoiceValues { 51 | return [[self selectedChoices] valueForKey:@"value"]; 52 | } 53 | 54 | - (NSArray *)selectedChoices { 55 | return [rowData objectsAtIndexes:selectedIndexes]; 56 | } 57 | 58 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 59 | return [rowData count]; 60 | } 61 | 62 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 63 | NSUInteger idxOfColumn = [[tableView tableColumns] indexOfObject:tableColumn]; 64 | if (idxOfColumn == 0) { 65 | return ([NSNumber numberWithInt:[selectedIndexes containsIndex:row] ? NSOnState : NSOffState]); 66 | } else { 67 | NSDictionary *columns = (NSDictionary *)[rowData objectAtIndex:row]; 68 | NSString *columnValue = (NSString *)[columns objectForKey:[tableColumn identifier]]; 69 | 70 | return columnValue == nil ? @"" : columnValue; 71 | } 72 | } 73 | 74 | - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 75 | NSUInteger idxOfColumn = [[tableView tableColumns] indexOfObject:tableColumn]; 76 | if (idxOfColumn != 0) return; 77 | NSCellStateValue state = (NSCellStateValue)[(NSNumber *)object intValue]; 78 | if (state == NSOnState) { 79 | [selectedIndexes addIndex:(NSUInteger)row]; 80 | } else if (state == NSOffState) { 81 | [selectedIndexes removeIndex:(NSUInteger)row]; 82 | } 83 | 84 | [delegate dataSource:self checkedChoicesChanged:[self selectedChoices]]; 85 | 86 | } 87 | 88 | - (void)tableView:(NSTableView *)tableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 89 | if (tableColumn == nil) return; 90 | NSUInteger idxOfColumn = [[tableView tableColumns] indexOfObject:tableColumn]; 91 | if (idxOfColumn == 0) { 92 | NSString *label = (NSString *)[(NSDictionary *)[rowData objectAtIndex:row] objectForKey:labelKey]; 93 | NSButtonCell *checkBox = (NSButtonCell *)aCell; 94 | [checkBox setTitle:label]; 95 | [checkBox setButtonType:NSSwitchButton]; 96 | [checkBox setState:([selectedIndexes containsIndex:row] ? NSOnState : NSOffState)]; 97 | } else { 98 | NSDictionary *columns = (NSDictionary *)[rowData objectAtIndex:row]; 99 | NSString *columnValue = (NSString *)[columns objectForKey:[tableColumn identifier]]; 100 | columnValue = (columnValue == nil ? @"" : columnValue); 101 | 102 | NSTextFieldCell *textCell = (NSTextFieldCell *)aCell; 103 | [textCell setStringValue:columnValue]; 104 | [textCell setTextColor:[NSColor disabledControlTextColor]]; 105 | [textCell setBordered:NO]; 106 | [textCell setEditable:NO]; 107 | } 108 | } 109 | 110 | - (void)dealloc { 111 | [rowData release]; 112 | [selectedIndexes release]; 113 | [labelKey release]; 114 | [super dealloc]; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /NDAlias+AliasFile.m: -------------------------------------------------------------------------------- 1 | /* 2 | * NDAlias+AliasFile.m category 3 | * NDAliasProject 4 | * 5 | * Created by Nathan Day on Tue Dec 03 2002. 6 | * Copyright (c) 2002 Nathan Day. All rights reserved. 7 | */ 8 | 9 | #import "NDAlias+AliasFile.h" 10 | #import "NDResourceFork.h" 11 | #import "NSURL+NDCarbonUtilities.h" 12 | #import "NDResourceFork+OtherSorces.h" 13 | 14 | //const ResType aliasResourceType = 'alis'; 15 | const OSType finderCreatorCode = 'MACS'; 16 | const short aliasRecordId = 0; 17 | // customIconID = -16496; 18 | 19 | @implementation NDAlias (AliasFile) 20 | 21 | OSType aliasOSTypeFor( NSURL * aURL ); 22 | 23 | + (id)aliasWithContentsOfFile:(NSString *)aPath 24 | { 25 | return [[[self alloc] initWithContentsOfFile:aPath] autorelease]; 26 | } 27 | 28 | + (id)aliasWithContentsOfURL:(NSURL *)aURL 29 | { 30 | return [[[self alloc] initWithContentsOfURL:aURL] autorelease]; 31 | } 32 | 33 | - (id)initWithContentsOfFile:(NSString *)aPath 34 | { 35 | NDResourceFork * theResourcFork; 36 | theResourcFork = [[NDResourceFork alloc] initForReadingAtPath:aPath]; 37 | 38 | self = [self initWithData:[theResourcFork dataForType:formAlias Id:aliasRecordId]]; 39 | 40 | [theResourcFork release]; 41 | 42 | return self; 43 | } 44 | 45 | - (id)initWithContentsOfURL:(NSURL *)aURL 46 | { 47 | NDResourceFork * theResourcFork; 48 | theResourcFork = [[NDResourceFork alloc] initForReadingAtURL:aURL]; 49 | 50 | self = [self initWithData:[theResourcFork dataForType:formAlias Id:aliasRecordId]]; 51 | 52 | [theResourcFork release]; 53 | 54 | return self; 55 | } 56 | 57 | - (BOOL)writeToFile:(NSString *)aPath 58 | { 59 | return [self writeToURL:[NSURL fileURLWithPath:aPath]]; 60 | } 61 | 62 | - (BOOL)writeToURL:(NSURL *)aURL 63 | { 64 | BOOL theSuccess; 65 | NDResourceFork * theResourcFork; 66 | 67 | theResourcFork = [[NDResourceFork alloc] initForWritingAtURL:aURL]; 68 | theSuccess = [theResourcFork addData:[self data] type:formAlias Id:aliasRecordId name:@"created by NDAlias"]; 69 | 70 | if( theSuccess ) 71 | { 72 | UInt16 theFlags; 73 | OSType theAliasType, 74 | theAliasCreator, 75 | theTargetType, 76 | theTargetCreator; 77 | NSURL * theTargetURL; 78 | 79 | theTargetURL = [self url]; 80 | 81 | [[self url] finderInfoFlags:&theFlags type:&theTargetType creator:&theTargetCreator]; 82 | 83 | theAliasType = aliasOSTypeFor( theTargetURL ); // get the alias type 84 | 85 | if( theAliasType == 0 ) // 0 alias type means doc which just takes the targets type 86 | { 87 | theAliasCreator = theTargetCreator; 88 | theAliasType = theTargetType; 89 | } 90 | else // special alias types take the finder creator code 91 | { 92 | theAliasCreator = finderCreatorCode; 93 | } 94 | 95 | // item with custom icon as well as apps need to have a custoime icon for the alias 96 | if( (theAliasType == 0 ) || (theFlags & kHasCustomIcon) || (theAliasType == kAppPackageAliasType) || (theAliasType == kApplicationAliasType) ) 97 | { 98 | NSData * theIconFamilyData; 99 | 100 | theIconFamilyData = [NDResourceFork iconFamilyDataForURL:theTargetURL]; 101 | 102 | if( [theResourcFork addData:theIconFamilyData type:kIconFamilyType Id:kCustomIconResource name:@""] ) 103 | [aURL setFinderInfoFlags:kIsAlias | kHasCustomIcon mask:kIsAlias | kHasCustomIcon type:theAliasType creator:theAliasCreator]; 104 | } 105 | else 106 | { 107 | [aURL setFinderInfoFlags:kIsAlias mask:kIsAlias | kHasCustomIcon type:theAliasType creator:theAliasCreator]; 108 | } 109 | } 110 | 111 | [theResourcFork release]; 112 | return theSuccess; 113 | } 114 | 115 | OSType aliasOSTypeFor( NSURL * aURL ) 116 | { 117 | LSItemInfoRecord theItemInfo; 118 | OSType theType = kContainerFolderAliasType; 119 | 120 | /* 121 | * alias files to documents take on the targets type and creator 122 | * alias files to others take on special types and finder creator 123 | */ 124 | if( LSCopyItemInfoForURL( (CFURLRef)aURL, kLSRequestBasicFlagsOnly, &theItemInfo) == noErr) 125 | { 126 | if( (theItemInfo.flags & kLSItemInfoIsApplication) && (theItemInfo.flags & kLSItemInfoIsPackage) ) // package app 127 | { 128 | theType = kAppPackageAliasType; 129 | } 130 | else if( theItemInfo.flags & kLSItemInfoIsApplication ) // straight app 131 | { 132 | theType = kApplicationAliasType; 133 | } 134 | else if( theItemInfo.flags & kLSItemInfoIsPlainFile ) // document 135 | { 136 | theType = 0; // straight documents don't have a special alias type 137 | } 138 | else if( theItemInfo.flags & kLSItemInfoIsPackage ) // package 139 | { 140 | theType = kPackageAliasType; 141 | } 142 | else if( theItemInfo.flags & kLSItemInfoIsVolume ) // disk 143 | { 144 | theType = kContainerHardDiskAliasType; 145 | } 146 | } 147 | 148 | return theType; 149 | } 150 | 151 | @end 152 | 153 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/sharingservices.html: -------------------------------------------------------------------------------- 1 | 9 | 13 | 14 | 15 | 16 | Sharing a service 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
30 |
ThisService Icon
31 |
32 |

Sharing a service

33 |
34 | 35 |

Due to the minimal nature of services, they are perfect for solving small problems well. You may have written a useful service that you'd like to share with someone else or even with anyone else by making it available on the web.

36 |

ThisService contains a feature called Pack Up that will generate a zip archive file for you containing your service. Pack Up will try to resolve as many issues as possible that would prevent people from using your service on their computers - for example, it will place a copy of your script inside the packed up service if the service currently just references the script instead of carrying its own copy of it. The Services feature in general is not very well known and it is not obvious how to install a service, so you can also supply a file with instructions.

37 |

The packed up service's Resource folder will contain any file you've put in the Resources folder of the original service.

38 |

ThisService is unable to verify that your service will run on other computers due to dependencies on a particular version of a language, a particular module or library or other reasons. For example, if you write a script using the Node.js JavaScript environment that's not bundled with OS X, the service will only run on other Macs that have Node.js installed and similarly configured. If your service script depends on any third-party library, please embed them within your service.

39 |

Please also read Considerations when sharing a service.

40 |
41 |

To pack up a service:

42 |
    43 |
  1. Bring up the ThisService window and activate the Pack Up Service tab by clicking it or by choosing File → Pack Up Service.
  2. 44 |
  3. Choose the service you'd like to pack up from the Service to pack up: popup.
  4. 45 |
  5. If you'd like to rename your service, check the Rename: check box and edit the name in the text field.
  6. 46 |
  7. If you'd like to supply an instructions file, pick an instructions file by clicking Choose… next to Optional instructions
  8. 47 |
  9. Click Pack Up and choose a location for the zip archive file to have ThisService create a packed up version of the service.
  10. 48 |
49 |
50 | 51 |

See also

52 |

Considerations when sharing a service
53 | Sharing services Topics

57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /TSZip.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSZip.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2007-04-23. 6 | // Copyright 2007-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSZip.h" 11 | 12 | @implementation TSZip 13 | /* 14 | 15 | When you want to save your document as a Zip file. 16 | using 17 | cocoadev.com 18 | http://www.cocoadev.com/index.pl?UsingZipFilesExamples 19 | 20 | */ 21 | 22 | static BOOL logging = NO; 23 | #define TSZLog(...) do { if (logging) { NSLog(__VA_ARGS__); } } while (0) 24 | 25 | + (void)cleanseFileWrapperOfIcons:(NSFileWrapper *)fw { 26 | if (nil != [fw icon]) [fw setIcon:nil]; 27 | if (nil != [fw fileWrappers] || [[fw fileWrappers] count] == 0) return; 28 | NSDictionary *wrappers = [fw fileWrappers]; 29 | NSEnumerator *fwEnumerator = [wrappers keyEnumerator]; 30 | NSString *fwN; 31 | while (fwN = [fwEnumerator nextObject]) { 32 | NSFileWrapper *innerFW = [[fw fileWrappers] objectForKey:fwN]; 33 | [self cleanseFileWrapperOfIcons:innerFW]; 34 | } 35 | } 36 | 37 | + (NSData *)zip:(id)raw //raw must be NSData or NSFileWrapper 38 | { 39 | TSZLog(@"ThisService zipping..."); 40 | CFUUIDRef uuidcf = CFUUIDCreate(NULL); 41 | NSString *uuid = (NSString *)CFUUIDCreateString(NULL, uuidcf); 42 | CFRelease(uuidcf); 43 | NSString *scratchFolder = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"thisservice-zip-%@", uuid]]; 44 | [uuid release]; 45 | 46 | TSZLog(@"scratch folder: %@", scratchFolder); 47 | 48 | NSFileManager *fm = [NSFileManager defaultManager]; 49 | 50 | NSError *err; 51 | if (![fm createDirectoryAtPath:scratchFolder withIntermediateDirectories:NO attributes:nil error:&err]) { 52 | TSZLog(@"could not create scratch folder at %@ because of %@", scratchFolder, err); 53 | return nil; 54 | } 55 | 56 | TSZLog(@"created scratch folder"); 57 | 58 | NSString *sourceFilename = @"data"; 59 | NSString *targetFilename = @"zipped data"; 60 | 61 | NSString *sourcePath = [scratchFolder stringByAppendingPathComponent:sourceFilename]; 62 | NSString *targetPath = [scratchFolder stringByAppendingPathComponent:targetFilename]; 63 | 64 | TSZLog(@"source path: %@, target path: %@", sourcePath, targetPath); 65 | 66 | BOOL flag = NO; 67 | if([raw isKindOfClass:[NSData class]]) { 68 | TSZLog(@"is data"); 69 | flag = [raw writeToFile:sourcePath atomically:YES]; 70 | } 71 | else if([raw isKindOfClass:[NSFileWrapper class]]) { 72 | TSZLog(@"is filewrapper"); 73 | NSFileWrapper *fw = raw; 74 | //NSLog(@"fileWrappers: %@", [fw fileWrappers]); 75 | NSArray *files = [[fw fileWrappers] allKeys]; 76 | TSZLog(@"files: %@", files); 77 | [self cleanseFileWrapperOfIcons:fw]; 78 | //NSLog(@"cleansed: %@", fw); 79 | flag = [raw writeToFile:sourcePath atomically:YES updateFilenames:YES]; 80 | TSZLog(@"wrote to file"); 81 | NSEnumerator *fileEnumerator = [files objectEnumerator]; 82 | NSString *file; 83 | while (file = [fileEnumerator nextObject]) { 84 | NSString *pathToGeneratedSuperfluosIcon = [[sourcePath stringByAppendingPathComponent:file] stringByAppendingPathExtension:@"tiff"]; 85 | if ([fm fileExistsAtPath:pathToGeneratedSuperfluosIcon]) { 86 | TSZLog(@"horrible NSFileWrapper-generated icon exists for %@, let's remove it", file); 87 | [fm removeItemAtPath:pathToGeneratedSuperfluosIcon error:NULL]; 88 | } 89 | } 90 | } 91 | 92 | if(flag == NO) { 93 | TSZLog(@"could not write file when zipping"); 94 | return nil; 95 | } 96 | 97 | /* Assumes sourcePath and targetPath are both 98 | valid, standardized paths. */ 99 | 100 | //---------------- 101 | // Create the zip task 102 | 103 | TSZLog(@"starting zip task"); 104 | 105 | NSTask * backupTask = [[NSTask alloc] init]; 106 | [backupTask setLaunchPath:@"/usr/bin/ditto"]; 107 | [backupTask setArguments: 108 | [NSArray arrayWithObjects:@"-c", @"-k", @"-X", @"--sequesterRsrc", 109 | sourcePath, targetPath, nil]]; 110 | 111 | TSZLog(@"launching"); 112 | 113 | // Launch it and wait for execution 114 | [backupTask launch]; 115 | TSZLog(@"launched"); 116 | [backupTask waitUntilExit]; 117 | 118 | int terminationStatus = [backupTask terminationStatus]; 119 | 120 | [backupTask release]; 121 | 122 | TSZLog(@"exited, termstatus: %d", terminationStatus); 123 | 124 | // Handle the task's termination status 125 | if (terminationStatus != 0) { 126 | TSZLog(@"Sorry, didn't work."); 127 | return nil; 128 | } 129 | 130 | NSData *convertedData = [[NSData alloc] initWithContentsOfFile:targetPath]; 131 | 132 | TSZLog(@"created converted data"); 133 | 134 | //delete scratch 135 | 136 | TSZLog(@"deleting scratch folders"); 137 | 138 | 139 | NSError *removeScratchFolderError = nil; 140 | TSZLog(@"scratch folder: %@", scratchFolder); 141 | [[NSFileManager defaultManager] removeItemAtPath:scratchFolder error:&removeScratchFolderError]; 142 | TSZLog(@"remove scratch folder: %@ error %@", scratchFolder, removeScratchFolderError); 143 | 144 | return [convertedData autorelease]; 145 | } 146 | @end 147 | -------------------------------------------------------------------------------- /TSServiceInputRules.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceInputRules.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2011-07-17. 6 | // Copyright 2011-2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | 10 | #import "TSServiceInputRules.h" 11 | 12 | 13 | @implementation TSServiceInputRules 14 | 15 | - (id)initWithWritingSystems:(NSSet *)writingSystems_ 16 | contentTypes:(NSSet *)contentTypes_ 17 | wordLimit:(NSNumber *)wordLimit_ 18 | applicationIdentifiers:(NSSet *)applicationIdentifiers_ 19 | languages:(NSSet *)languages_ { 20 | self = [super init]; 21 | if (self != nil) { 22 | writingSystems = [writingSystems_ copy]; 23 | contentTypes = [contentTypes_ copy]; 24 | wordLimit = [wordLimit_ retain]; 25 | applicationIdentifiers = [applicationIdentifiers_ copy]; 26 | languages = [languages_ retain]; 27 | } 28 | return self; 29 | } 30 | 31 | - (NSSet *)writingSystems { 32 | return writingSystems; 33 | } 34 | 35 | - (NSSet *)contentTypes { 36 | return contentTypes; 37 | } 38 | 39 | - (NSNumber *)wordLimit { 40 | return wordLimit; 41 | } 42 | 43 | - (NSSet *)applicationIdentifiers { 44 | return applicationIdentifiers; 45 | } 46 | 47 | - (NSSet *)languages { 48 | return languages; 49 | } 50 | 51 | + (NSSet *)setFromSingleStringOrArrayOfStrings:(id)obj { 52 | if (obj == nil) return nil; 53 | if ([obj isKindOfClass:[NSString class]]) return [NSSet setWithObject:obj]; 54 | if ([obj isKindOfClass:[NSArray class]]) { 55 | NSArray *arr = (NSArray *)obj; 56 | NSMutableSet *set = [NSMutableSet set]; 57 | for (id arrObj in arr) { 58 | if ([arrObj isKindOfClass:[NSString class]]) { 59 | [set addObject:arrObj]; 60 | } 61 | } 62 | return set; 63 | } 64 | return nil; 65 | } 66 | 67 | + (TSServiceInputRules *)singleInputRulesFromInfoPlistRequiredContext:(NSDictionary *)requiredContextEntryDictionary { 68 | NSSet *writingSystems = [self setFromSingleStringOrArrayOfStrings:[requiredContextEntryDictionary objectForKey:@"NSTextScript"]]; 69 | NSSet *languages = [self setFromSingleStringOrArrayOfStrings:[requiredContextEntryDictionary objectForKey:@"NSTextLanguage"]]; 70 | NSSet *contentTypes = [self setFromSingleStringOrArrayOfStrings:[requiredContextEntryDictionary objectForKey:@"NSTextContent"]]; 71 | NSSet *applicationIdentifiers = [self setFromSingleStringOrArrayOfStrings:[requiredContextEntryDictionary objectForKey:@"NSApplicationIdentifier"]]; 72 | id wordLimitObj = [requiredContextEntryDictionary objectForKey:@"NSWordLimit"]; 73 | NSNumber *wordLimit = (wordLimitObj == nil ? nil : ([wordLimitObj isKindOfClass:[NSNumber class]] ? (NSNumber *)wordLimitObj : nil)); 74 | 75 | return [[[TSServiceInputRules alloc] initWithWritingSystems:writingSystems 76 | contentTypes:contentTypes 77 | wordLimit:wordLimit 78 | applicationIdentifiers:applicationIdentifiers 79 | languages:languages] autorelease]; 80 | } 81 | 82 | + (NSArray *)allInputRulesFromInfoPlistRequiredContext:(id)requiredContextEntry { 83 | if ([requiredContextEntry isKindOfClass:[NSDictionary class]]) { 84 | TSServiceInputRules *rule = [self singleInputRulesFromInfoPlistRequiredContext:(NSDictionary *)requiredContextEntry]; 85 | if (rule == nil) return nil; 86 | return [NSArray arrayWithObject:rule]; 87 | } else if ([requiredContextEntry isKindOfClass:[NSArray class]]) { 88 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:[(NSArray *)requiredContextEntry count]]; 89 | for (NSDictionary *dict in array) { 90 | TSServiceInputRules *rule = [self singleInputRulesFromInfoPlistRequiredContext:dict]; 91 | if (rule == nil) continue; 92 | [array addObject:rule]; 93 | } 94 | return array; 95 | } else return nil; 96 | } 97 | 98 | - (id)singleStringOrArrayOfStringsFromSet:(NSSet *)set { 99 | if ([set count] == 0) return nil; 100 | if ([set count] == 1) return [set anyObject]; 101 | return [set allObjects]; 102 | } 103 | 104 | - (void)inDictionary:(NSMutableDictionary *)dict setObjectIfNotNil:(id)obj forKey:(NSString *)string { 105 | if (obj) 106 | [dict setObject:obj forKey:string]; 107 | } 108 | 109 | - (NSDictionary *)infoPlistRequiredContextDictionary { 110 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 111 | [self inDictionary:dictionary setObjectIfNotNil:[self singleStringOrArrayOfStringsFromSet:writingSystems] forKey:@"NSTextScript"]; 112 | [self inDictionary:dictionary setObjectIfNotNil:[self singleStringOrArrayOfStringsFromSet:languages] forKey:@"NSTextLanguage"]; 113 | [self inDictionary:dictionary setObjectIfNotNil:[self singleStringOrArrayOfStringsFromSet:contentTypes] forKey:@"NSTextContent"]; 114 | [self inDictionary:dictionary setObjectIfNotNil:[self singleStringOrArrayOfStringsFromSet:applicationIdentifiers] forKey:@"NSApplicationIdentifier"]; 115 | [self inDictionary:dictionary setObjectIfNotNil:wordLimit forKey:@"NSWordLimit"]; 116 | return dictionary; 117 | } 118 | 119 | - (BOOL)isEmpty { 120 | return (writingSystems == nil && contentTypes == nil && wordLimit == nil && applicationIdentifiers == nil && languages == nil); 121 | } 122 | 123 | - (void)dealloc { 124 | [writingSystems release]; 125 | [contentTypes release]; 126 | [wordLimit release]; 127 | [applicationIdentifiers release]; 128 | [languages release]; 129 | 130 | [super dealloc]; 131 | } 132 | 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/writingscripts-applescript.html: -------------------------------------------------------------------------------- 1 | 9 | 13 | 14 | 15 | 16 | Writing an AppleScript service script 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
30 |
ThisService Icon
31 |
32 |

Writing an AppleScript service script

33 |
34 | 35 |

AppleScript is a scripting language that's built into Mac OS X and offers some unique possibilities to control other applications that support it. ThisService supports writing service scripts in AppleScript. Apple offers help on their web site dedicated to teaching AppleScript - this help topic will assume that you are already familiar with AppleScript.

36 |
37 |

Guidelines for AppleScript service scripts:

38 |
    39 |
  • Your AppleScript has access to all the features any normal AppleScript would. You can use the full range of its functions and any installed scripting dictionary.
  • 40 |
  • If you have another OSA language installed, like JavaScript OSA, you can use it, too. However, this topic refers to any OSA script as an AppleScript, and uses AppleScript idioms. Also be advised that any service running an OSA script using a language other than AppleScript will require the OSA language to be installed to run.
  • 41 |
  • To function as a service script, your script must define a handler (a function) called process. In services that receive input, this handler takes one argument: the input as a Unicode text string. In services that do not take input, it doesn't take any arguments. Likewise, in services that produce output, you return the output from this handler. (In services that don't produce output, the return value is ignored.)
  • 42 |
  • Since the service script entry point is through the process handler, the service script will not start by running any code outside of the handler as a usual AppleScript would. You can use this to detect in which mode your script runs, and change its behavior accordingly.
  • 43 |
  • In order for the service script to run as an AppleScript rather than as a conventional script, you will need to use the file extension .scpt or .applescript (both case-insensitive) or make sure it has an HFS type code of osas (case-sensitive).
  • 44 |
  • Both compiled and source code AppleScripts are supported.
  • 45 |
  • If you are thinking of sharing your service with other people, please make sure any application referred to by name in the script has kept its original name in the script. For example, if you renamed your copy of iTunes to "iTunes 10", it will only run on other Macs where iTunes has been renamed "iTunes 10".
  • 46 |
47 |
48 | 49 |

See also

50 |

Writing a standard service script
51 | Reliable conditions for AppleScript service scripts
52 | Writing scripts Topics

56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /TSServiceTester.m: -------------------------------------------------------------------------------- 1 | // 2 | // TSServiceTester.m 3 | // ThisService 4 | // 5 | // Created by Jesper on 2012-07-05. 6 | // Copyright 2012 waffle software. All rights reserved. 7 | // BSD licensed - see license.txt for more information. 8 | // 9 | // 10 | 11 | #import "TSServiceTester.h" 12 | 13 | #import "TSService.h" 14 | 15 | @implementation TSServiceTester 16 | 17 | @synthesize skeleton=_skeleton, registeredSkeletonName=_registeredSkeletonName, 18 | pasteboard=_pasteboard, connection=_connection, 19 | serviceTask=_serviceTask; 20 | 21 | - (id)initWithServiceLaunchPath:(NSString *)launchPath service:(TSService *)service testServiceURL:(NSURL *)serviceURL { 22 | self = [super init]; 23 | if (self) { 24 | _launchPath = [launchPath retain]; 25 | _service = [service retain]; 26 | _serviceURL = [serviceURL retain]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)setDelegate:(id)delegate { 32 | _delegate = delegate; 33 | } 34 | 35 | - (void)cancel { 36 | if (self.connection) { 37 | @try { 38 | if (self.skeleton) { 39 | [self.skeleton testingDone]; 40 | } 41 | [self.connection invalidate]; 42 | } @finally { 43 | self.connection = nil; 44 | } 45 | } 46 | 47 | if (self.serviceTask) { 48 | if ([self.serviceTask isRunning]) { 49 | [self performSelector:@selector(killTask:) withObject:self.serviceTask afterDelay:50]; 50 | } 51 | } 52 | } 53 | 54 | - (void)killTask:(NSTask *)task { 55 | [task terminate]; 56 | } 57 | 58 | - (TSService *)service { 59 | return _service; 60 | } 61 | 62 | - (void)removeServiceBundle { 63 | [[NSFileManager defaultManager] removeItemAtURL:_serviceURL error:NULL]; 64 | } 65 | 66 | - (BOOL)startConnection { 67 | NSString *connectionName = [NSString stringWithFormat:@"thisservice-app-%@", [[NSProcessInfo processInfo] globallyUniqueString]]; 68 | 69 | NSConnection *theConnection = [NSConnection serviceConnectionWithName:connectionName rootObject:self]; 70 | if (!theConnection) return NO; 71 | 72 | NSLog(@"registered producer as %@", connectionName); 73 | 74 | self.connection = theConnection; 75 | 76 | NSArray *arguments = [NSArray arrayWithObject:[@"-THISSERVICE_TESTING_SERVICE__" stringByAppendingString:connectionName]]; 77 | 78 | self.serviceTask = [NSTask launchedTaskWithLaunchPath:_launchPath arguments:arguments]; 79 | pid_t pid = self.serviceTask.processIdentifier; 80 | 81 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 82 | _taskExitSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, 83 | pid, DISPATCH_PROC_EXIT, queue); 84 | if (_taskExitSource) { 85 | __block TSServiceTester *bself = self; 86 | dispatch_source_set_event_handler(_taskExitSource, ^{ 87 | NSLog(@"process %d exited; remove service bundle %@", pid, bself->_serviceURL); 88 | [bself removeServiceBundle]; 89 | dispatch_source_cancel(bself->_taskExitSource); 90 | dispatch_release(bself->_taskExitSource); 91 | bself->_taskExitSource = nil; 92 | }); 93 | dispatch_resume(_taskExitSource); 94 | } 95 | 96 | [_delegate testerLaunchedService:self]; 97 | 98 | return YES; 99 | } 100 | 101 | - (void)dealloc { 102 | if (_taskExitSource) { 103 | dispatch_source_cancel(_taskExitSource); 104 | dispatch_release(_taskExitSource); 105 | } 106 | [_launchPath release]; 107 | [_service release]; 108 | [_serviceURL release]; 109 | 110 | [_serviceTask release]; 111 | [_connection release]; 112 | [_registeredSkeletonName release]; 113 | [_pasteboard release]; 114 | [_skeleton release]; 115 | 116 | [super dealloc]; 117 | } 118 | 119 | - (oneway void)registerNewSkeletonNamed:(NSString *)skeletonName { 120 | self.registeredSkeletonName = skeletonName; 121 | 122 | NSConnection *connectionToSkeleton = [NSConnection connectionWithRegisteredName:skeletonName host:nil]; 123 | id skeletonProxy = [connectionToSkeleton rootProxy]; 124 | [skeletonProxy setProtocolForProxy:@protocol(TSServiceTestingSkeleton)]; 125 | self.skeleton = skeletonProxy; 126 | 127 | [_delegate testerPairedWithService:self]; 128 | } 129 | 130 | - (BOOL)startTesting { 131 | BOOL couldFreshen = [_service freshenScriptInFileWrapperWrittenAtURL:_serviceURL]; 132 | if (!couldFreshen) return NO; 133 | 134 | if (!self.pasteboard) { 135 | self.pasteboard = [NSPasteboard pasteboardWithUniqueName]; 136 | } else { 137 | [self.pasteboard clearContents]; 138 | } 139 | 140 | [_delegate testerWillInvokeService:self withPasteboard:self.pasteboard]; 141 | 142 | NSString *name = self.pasteboard.name; 143 | 144 | [self.skeleton invokeServiceWithPasteboard:name]; 145 | 146 | return YES; 147 | } 148 | 149 | - (oneway void)testRunForSkeletonStarted:(NSString *)skeletonName { 150 | [_delegate testerBeganRunningService:self]; 151 | } 152 | 153 | - (oneway void)testRunForSkeleton:(NSString *)skeletonName ended:(NSString *)error { 154 | if (error) { 155 | [_delegate tester:self failedWithError:error]; 156 | } else { 157 | [_delegate testerFinishedRunningService:self withPasteboard:self.pasteboard]; 158 | } 159 | } 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /NSURL+NDCarbonUtilities.m: -------------------------------------------------------------------------------- 1 | /* 2 | * NSURL+NDCarbonUtilities.m category 3 | * AppleScriptObjectProject 4 | * 5 | * Created by nathan on Wed Dec 05 2001. 6 | * Copyright 2001-2007 Nathan Day. All rights reserved. 7 | */ 8 | 9 | #import "NSURL+NDCarbonUtilities.h" 10 | 11 | /* 12 | * category implementation NSURL (NDCarbonUtilities) 13 | */ 14 | @implementation NSURL (NDCarbonUtilities) 15 | 16 | /* 17 | + URLWithFSRef: 18 | */ 19 | + (NSURL *)URLWithFSRef:(const FSRef *)aFsRef 20 | { 21 | CFURLRef theURL = CFURLCreateFromFSRef( kCFAllocatorDefault, aFsRef ); 22 | 23 | /* To support GC and non-GC, we need this contortion. */ 24 | return [NSMakeCollectable(theURL) autorelease]; 25 | } 26 | 27 | /* 28 | + URLWithFileSystemPathHFSStyle: 29 | */ 30 | + (NSURL *)URLWithFileSystemPathHFSStyle:(NSString *)aHFSString 31 | { 32 | CFURLRef theURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, (CFStringRef)aHFSString, kCFURLHFSPathStyle, [aHFSString hasSuffix:@":"] ); 33 | 34 | /* To support GC and non-GC, we need this contortion. */ 35 | return [NSMakeCollectable(theURL) autorelease]; 36 | } 37 | 38 | /* 39 | - getFSRef: 40 | */ 41 | - (BOOL)getFSRef:(FSRef *)aFsRef 42 | { 43 | return CFURLGetFSRef( (CFURLRef)self, aFsRef ) != 0; 44 | } 45 | 46 | /* 47 | - getFSRef: 48 | */ 49 | - (BOOL)getFSSpec:(FSSpec *)aFSSpec 50 | { 51 | #if defined(__LP64__) && __LP64__ 52 | (void)aFSSpec; 53 | return NO; 54 | #else 55 | FSRef aFSRef; 56 | 57 | return [self getFSRef:&aFSRef] && (FSGetCatalogInfo( &aFSRef, kFSCatInfoNone, NULL, NULL, aFSSpec, NULL ) == noErr); 58 | #endif 59 | } 60 | 61 | /* 62 | - URLByDeletingLastPathComponent 63 | */ 64 | - (NSURL *)URLByDeletingLastPathComponent 65 | { 66 | CFURLRef theURL = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault, (CFURLRef)self); 67 | 68 | /* To support GC and non-GC, we need this contortion. */ 69 | return [NSMakeCollectable(theURL) autorelease]; 70 | } 71 | 72 | /* 73 | - fileSystemPathHFSStyle 74 | */ 75 | - (NSString *)fileSystemPathHFSStyle 76 | { 77 | CFStringRef theString = CFURLCopyFileSystemPath((CFURLRef)self, kCFURLHFSPathStyle); 78 | 79 | /* To support GC and non-GC, we need this contortion. */ 80 | return [NSMakeCollectable(theString) autorelease]; 81 | } 82 | 83 | /* 84 | - resolveAliasFile 85 | */ 86 | - (NSURL *)resolveAliasFile 87 | { 88 | FSRef theRef; 89 | Boolean theIsTargetFolder, 90 | theWasAliased; 91 | NSURL * theResolvedAlias = nil;; 92 | 93 | [self getFSRef:&theRef]; 94 | 95 | if( (FSResolveAliasFile ( &theRef, YES, &theIsTargetFolder, &theWasAliased ) == noErr) ) 96 | { 97 | theResolvedAlias = (theWasAliased) ? [NSURL URLWithFSRef:&theRef] : self; 98 | } 99 | 100 | return theResolvedAlias; 101 | } 102 | 103 | /* 104 | - finderInfoFlags:type:creator: 105 | */ 106 | - (BOOL)finderInfoFlags:(UInt16*)aFlags type:(OSType*)aType creator:(OSType*)aCreator 107 | { 108 | FSRef theFSRef; 109 | FSCatalogInfo theInfo; 110 | 111 | if( [self getFSRef:&theFSRef] && FSGetCatalogInfo( &theFSRef, kFSCatInfoFinderInfo, &theInfo, NULL, NULL, NULL) == noErr ) 112 | { 113 | FileInfo* theFileInfo = (FileInfo*)(&theInfo.finderInfo); 114 | if( aFlags ) *aFlags = theFileInfo->finderFlags; 115 | if( aType ) *aType = theFileInfo->fileType; 116 | if( aCreator ) *aCreator = theFileInfo->fileCreator; 117 | 118 | return YES; 119 | } 120 | else 121 | return NO; 122 | } 123 | 124 | /* 125 | - finderLocation 126 | */ 127 | - (NSPoint)finderLocation 128 | { 129 | FSRef theFSRef; 130 | FSCatalogInfo theInfo; 131 | NSPoint thePoint = NSMakePoint( 0, 0 ); 132 | 133 | if( [self getFSRef:&theFSRef] && FSGetCatalogInfo( &theFSRef, kFSCatInfoFinderInfo, &theInfo, NULL, NULL, NULL) == noErr ) 134 | { 135 | FileInfo* theFileInfo = (FileInfo*)(&theInfo.finderInfo); 136 | thePoint = NSMakePoint(theFileInfo->location.h, theFileInfo->location.v ); 137 | } 138 | 139 | return thePoint; 140 | } 141 | 142 | /* 143 | - setFinderInfoFlags:mask:type:creator: 144 | */ 145 | - (BOOL)setFinderInfoFlags:(UInt16)aFlags mask:(UInt16)aMask type:(OSType)aType creator:(OSType)aCreator 146 | { 147 | BOOL theResult = NO; 148 | FSRef theFSRef; 149 | FSCatalogInfo theInfo; 150 | 151 | if( [self getFSRef:&theFSRef] && FSGetCatalogInfo( &theFSRef, kFSCatInfoFinderInfo, &theInfo, NULL, NULL, NULL) == noErr ) 152 | { 153 | FileInfo* theFileInfo = (FileInfo*)(&theInfo.finderInfo); 154 | theFileInfo->finderFlags = ((aFlags & aMask) | (theFileInfo->finderFlags & ~aMask)) & ~kHasBeenInited; 155 | theFileInfo->fileType = aType; 156 | theFileInfo->fileCreator = aCreator; 157 | 158 | theResult = FSSetCatalogInfo( &theFSRef, kFSCatInfoFinderInfo, &theInfo) == noErr; 159 | } 160 | 161 | return theResult; 162 | } 163 | 164 | /* 165 | - setFinderLocation: 166 | */ 167 | - (BOOL)setFinderLocation:(NSPoint)aLocation 168 | { 169 | BOOL theResult = NO; 170 | FSRef theFSRef; 171 | FSCatalogInfo theInfo; 172 | 173 | if( [self getFSRef:&theFSRef] && FSGetCatalogInfo( &theFSRef, kFSCatInfoFinderInfo, &theInfo, NULL, NULL, NULL) == noErr ) 174 | { 175 | FileInfo* theFileInfo = (FileInfo*)(&theInfo.finderInfo); 176 | theFileInfo->location.h = aLocation.x; 177 | theFileInfo->location.v = aLocation.y; 178 | 179 | theResult = FSSetCatalogInfo( &theFSRef, kFSCatInfoFinderInfo, &theInfo) == noErr; 180 | } 181 | 182 | return theResult; 183 | } 184 | 185 | @end 186 | 187 | @implementation NSURL (NDCarbonUtilitiesInfoFlags) 188 | 189 | - (BOOL)hasCustomIcon 190 | { 191 | UInt16 theFlags; 192 | return [self finderInfoFlags:&theFlags type:NULL creator:NULL] == YES && (theFlags & kHasCustomIcon) != 0; 193 | } 194 | 195 | @end 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/writingscripts-specialbehavior-applescript.html: -------------------------------------------------------------------------------- 1 | 9 | 13 | 14 | 15 | 16 | Reliable conditions for AppleScript service scripts 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
30 |
ThisService Icon
31 |
32 |

Reliable conditions for AppleScript service scripts

33 |
34 | 35 |

ThisService executes AppleScript service scripts under a number of special conditions that the service may choose to rely on.

36 |
37 |

Reliable conditions for AppleScript service scripts:

38 |
    39 |
  • ThisService passes service input as Unicode text and expects service output passed to it (via return) as Unicode text.
  • 40 |
  • ThisService calls the handler process with either one argument (the service input) or no arguments (if the service only produces output), and the handler must return the service results if the service is a filter or produces output. The handler is called directly by ThisService, and no surrounding code (like such code that may be called inside Script Editor when you run the script) is executed beforehand.
  • 41 |
  • 42 |

    ThisService is also able to pass surrounding context information to the script. It does this by attempting to run an alternative handler, tsprocess, if it is present. tsprocess takes one more argument (at the end of the list) than process would take, but otherwise behaves identically.

    43 |

    This extra argument is an options record, containing the context information. Due to the construction of AppleScript's records, a full descriptive name can't be used or in any way aliased without the use of a scripting dictionary (which would need to be redistributed and properly installed along with the service), so the keys used to look up the corresponding entry value are 'raw' four character constants.

    44 |

    All record entry values are strings. These record entries are defined:

    45 |
    46 |
    «class TSsv» (Service Skeleton Version)
    47 |
    This value is set to 2 for services created using this version of ThisService, and is intended to be used for versioning behavior when being created under different ThisService revisions. (Services created in ThisService 2.0.* or 1.* aren't called through tsprocess to begin with.) This variable is consistent with the value of the key ThisServiceServiceVersion in the service's Info.plist file.
    48 |
    «class TSop» (Service OS Platform)
    49 |
    This value is always set to Mac OS X.
    50 |
    «class TSov» (Service OS Version Major+Minor) and «class TSoV» (Service OS Version Full)
    51 |
    These values will be set to the current Mac OS X version in two forms; Major+Minor contains the broad release version, like 10.7, while Full contains the full version, like 10.7.4. If for any reason the version can not be determinated for one or both variables, they will contain ?. Alternative implementors of ThisService-like utilities on other platforms may set these variables to appropriate values.
    52 |
    «class TSiM» (Service Implementor)
    53 |
    This value is always set to ThisService.
    54 |
    55 |
  • 56 |
57 |
58 | 59 |

See also

60 |

Writing an AppleScript service script
61 | Writing scripts Topics

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /ThisService Help.help/Contents/Resources/English.lproj/pages/creatingservices.html: -------------------------------------------------------------------------------- 1 | 9 | 13 | 14 | 15 | 16 | How to create a service 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
30 |
ThisService Icon
31 |
32 |

How to create a service

33 |
34 | 35 |

Creating a service in ThisService is simple. This topic assumes you have read Preparing to assemble a service and tells you how to proceed.

36 |
37 |

To create a service:

38 |
    39 |
  1. Bring up the ThisService window and activate the Create Service tab by clicking it or by choosing File → New Service.
  2. 40 |
  3. Enter a name for the service in the Name text field.
  4. 41 |
  5. Choose a script by clicking the Choose… button, or by dragging the script from the Finder to the file picker field labelled Script.
  6. 42 |
  7. Depending on how you want your service to behave, check or uncheck Takes input and Produces output.
  8. 43 |
  9. At this point, you have filled out everything needed to create a usable service. You can also choose to set additional options by clicking Add option, or skip to the next step: 44 |
      45 |
    • If you would like to provide a icon for your service, add the option Service icon and provide a Mac OS X icon file (.icns) or an image. For more information on creating a Mac OS X icon, see Apple's Developer Reference Library.
    • 46 |
    • If you would like to limit in which application the service is available, add the option Application filter and follow the instructions to add applications.
    • 47 |
    • If you would like to hide your service unless input of a certain format is available, add the option Input rules. Here, you can set rules that must be fulfilled for your service to be shown. You can limit the writing system (Latin, Cyrillic, Arabic, Greek...), languages, number of words (max n words) and types of data (URLs, dates, addresses, email or file paths). Note that this logic is provided by Mac OS X, and that the entire input is still provided to your service script, not only the matching input.
    • 48 |
    • If you would like to change the service timeout from the default 30 seconds, add the option Timeout and adjust the timeout value.
    • 49 |
    • If you are refining your script and want to keep honing it in its current location, add the option Include script by reference. This makes the service refer to the exact script you provide, rather than copying it into the service itself. This means you can continue to edit your script in the same location and be sure your changes are picked up immediately without having to edit a different script or having to re-create the service from the changed script. However, this means that you can't share the service with anyone else, or run it from another user's account (unless she has necessary permissions to read the script file in whatever location you put it), until you pack up the service for sharing.
    • 50 |
    51 |
  10. 52 |
  11. Click Test Service to bring up the test sheet. Use the test sheet to test the service.
  12. 53 |
  13. When you're finished testing, or if you don't want to test, click Finish Testing and Create Service to have ThisService create the service and install it.
  14. 54 |
55 |
56 | 57 |

See also

58 |

What is a service?
59 | Testing a service using the test sheet
60 | Service basics Topics

64 |
65 | 66 | 67 | --------------------------------------------------------------------------------