Skip to content

Commit 98cc0f1

Browse files
committed
Now compiles in Mac OS 10.5 or 10.6 SDK without warnings, other improvements and bug fixes
1 parent 0139b6c commit 98cc0f1

34 files changed

+676
-150
lines changed

GCUndoManager.m

+16-1
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,27 @@ - (void) endUndoGrouping
167167

168168
if([self undoManagerState] == kGCUndoCollectingTasks)
169169
{
170+
// if this action is discardable, create userInfo indicating such
170171
GCUndoGroup* topGroup = [self peekUndo] ;
171172
NSDictionary* userInfo = nil ;
172173
if ([topGroup actionIsDiscardable]) {
174+
// If the deployment target is 10.7 or later, the NSUndoManagerGroupIsDiscardableKey global is available,
175+
// otherwise we just rely on it's string value, which is unlikely to change.
176+
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
173177
userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSUndoManagerGroupIsDiscardableKey] ;
178+
#else
179+
userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"NSUndoManagerGroupIsDiscardableKey"] ;
180+
#endif
174181
}
175-
[[NSNotificationCenter defaultCenter] postNotificationName:NSUndoManagerDidCloseUndoGroupNotification object:self userInfo:userInfo];
182+
183+
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
184+
// If the deployment target is 10.7 or later, the NSUndoManagerDidCloseUndoGroupNotification global is available,
185+
// otherwise we just rely on it's string value, which is unlikely to change.
186+
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
187+
[notificationCenter postNotificationName:NSUndoManagerDidCloseUndoGroupNotification object:self userInfo:userInfo];
188+
#else
189+
[notificationCenter postNotificationName:@"NSUndoManagerDidCloseUndoGroupNotification" object:self userInfo:userInfo];
190+
#endif
176191
}
177192
}
178193
}

MAKVONotificationCenter.m

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@
99

1010
#import <libkern/OSAtomic.h>
1111
#import <objc/message.h>
12-
12+
/*
13+
If you are developing with the 10.5 SDK, MAC_OS_X_VERSION_MAX_ALLOWED = 1050, MAC_OS_X_VERSION_10_5 = 1050 and the following #if will be true.
14+
If you are developing with the 10.6 SDK, MAC_OS_X_VERSION_MAX_ALLOWED = 1060, MAC_OS_X_VERSION_10_5 = 1050 and the following #if will be false.
15+
*/
16+
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5)
17+
// For some reason, this was not needed when I was using the 10.5 SDK
18+
#import <objc/objc-auto.h>
19+
#endif
1320

1421
@interface MAKVObservation : NSObject
1522
{

NSFancyPanel.m

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ - (void) sendEvent:(NSEvent *) theEvent
3838
// Offer key-down events to the delegats
3939
if ([theEvent type] == NSKeyDown)
4040
if ([[self delegate] respondsToSelector: @selector(handlesKeyDown:inWindow:)])
41-
if ([[self delegate] handlesKeyDown: theEvent inWindow: self])
41+
if ([(id)[self delegate] handlesKeyDown: theEvent inWindow: self])
4242
return;
4343

4444
// Offer mouse-down events (lefty or righty) to the delegate
4545
if ( ([theEvent type] == NSLeftMouseDown) || ([theEvent type] == NSRightMouseDown) )
4646
if ([[self delegate] respondsToSelector: @selector(handlesMouseDown:inWindow:)])
47-
if ([[self delegate] handlesMouseDown: theEvent inWindow: self])
47+
if ([(id)[self delegate] handlesMouseDown: theEvent inWindow: self])
4848
return;
4949

5050
// Delegate wasnÕt interested, so do the usual routing.

SSYAboutPanelController.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ extern NSString* const SSYAboutPanelHelpAnchorAcknowledgements ;
44

55
@class ScrollingTextView;
66

7-
@interface SSYAboutPanelController : NSObject {
7+
@interface SSYAboutPanelController : NSObject
8+
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5)
9+
<NSWindowDelegate>
10+
#endif
11+
{
812
// This panel exists in the nib file, but the user never sees it, because
913
// we rip out its contents and place them in “panelToDisplay”.
1014
IBOutlet NSPanel *panelInNib;

SSYAlert.h

+26-12
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,31 @@ enum {
1111
/*!
1212
@brief This is an addition to Apple's anonymous enumeration containing
1313
NSAlertDefaultReturn, NSAlertAlternateReturn, NSAlertOtherReturn and NSAlertErrorReturn.
14+
15+
@details These values are reflected in the 'Sheep Systems Suite'
16+
AppleScript terminology. Any changes you make here should be reflected
17+
in there.
1418
*/
15-
enum {
16-
SSYAlertRecoveryWasNoError = 99,
17-
SSYAlertRecoverySucceeded = 100,
18-
SSYAlertRecoveryFailed = 101,
19-
SSYAlertRecoveryNotAttempted = 102,
20-
SSYAlertRecoveryWentAsynchronous = 103,
21-
//SSYAlertRecoveryReturnedToScripter = 104
19+
enum SSYAlertRecovery_enum {
20+
SSYAlertRecoveryThereWasNoError = 99,
21+
SSYAlertRecoverySucceeded = 100,
22+
SSYAlertRecoveryFailed = 101,
23+
SSYAlertRecoveryNotAttempted = 102,
24+
SSYAlertRecoveryAttemptedAsynchronously = 103,
25+
SSYAlertRecoveryErrorIsHidden = 104,
26+
SSYAlertRecoveryUserCancelledPreviously = 105
27+
} ;
28+
typedef enum SSYAlertRecovery_enum SSYAlertRecovery ;
29+
enum SSYAlertRecoveryApplescriptCode_enum {
30+
SSYAlertRecoveryAppleScriptCodeThereWasNoError = 'Nerr',
31+
SSYAlertRecoveryAppleScriptCodeSucceeded = 'ReSx',
32+
SSYAlertRecoveryAppleScriptCodeFailed = 'ReFa',
33+
SSYAlertRecoveryAppleScriptCodeNotAttempted = 'NoAt',
34+
SSYAlertRecoveryAppleScriptCodeAttemptedAsynchronously = 'AtAs',
35+
SSYAlertRecoveryAppleScriptCodeErrorIsHidden = 'ErHd',
36+
SSYAlertRecoveryAppleScriptCodeUserCancelledPreviously = 'UsCn'
2237
} ;
38+
typedef enum SSYAlertRecoveryAppleScriptCode_enum SSYAlertRecoveryAppleScriptCode ;
2339

2440
/*!
2541
@brief Key used in the contextInfo sent to attemptRecoveryFromError:::::
@@ -113,8 +129,6 @@ extern NSString* const SSYAlertDidProcessErrorNotification ;
113129
displayed or no-op.
114130
115131
@details If error is nil, this method should return YES
116-
@param error
117-
@result
118132
*/
119133
- (BOOL)shouldHideError:(NSError*)error ;
120134

@@ -612,14 +626,14 @@ extern NSObject <SSYAlertErrorHideManager> * gSSYAlertErrorHideManager ;
612626
@result If recovery was not attempted, will be NSAlertDefaultReturn, NSAlertAlternateReturn,
613627
or NSAlertOtherReturn depending on whether user clicked the first, second, or third button.
614628
If recovery was attempted, result will be SSYAlertRecoverySucceeded, SSYAlertRecoveryFailed,
615-
or SSYAlertRecoveryWentAsynchronous.
629+
or SSYAlertRecoveryAttemptedAsynchronously.
616630
*/
617-
- (int)alertError:(NSError*)error ;
631+
- (SSYAlertRecovery)alertError:(NSError*)error ;
618632

619633
/*!
620634
@brief Invokes -alertError: on the application's shared alert.
621635
*/
622-
+ (int)alertError:(NSError*)error ;
636+
+ (SSYAlertRecovery)alertError:(NSError*)error ;
623637

624638
/*!
625639
@brief Creates an alert sheet on a given window and displays a given

SSYAlert.m

+98-23
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,39 @@ + (NSButton*)newButton {
454454

455455
#pragma mark * Private Methods
456456

457+
/*!
458+
@brief Translates from the 'recovery option' as expressed in our -doLayoutError:
459+
method to the 'recovery option index' expressed in Cocoa's error presentation method,
460+
-presentError:.
461+
462+
@details Cocoa's arrangement allows an unlimited number of error recovery options,
463+
indexed from 0. Our -doLayoutError: method only allows three options, which are
464+
indexed like the buttons in NSAlert. In particular, note that the values
465+
represented by 0 and 1 are reversed.
466+
*/
467+
+ (NSUInteger)recoveryOptionIndexForRecoveryOption:(NSInteger)recoveryOption {
468+
NSUInteger recoveryOptionIndex ;
469+
switch (recoveryOption) {
470+
case NSAlertDefaultReturn /* 1 */ :
471+
recoveryOptionIndex = 0 ;
472+
break;
473+
case NSAlertAlternateReturn /* 0 */ :
474+
recoveryOptionIndex = 1 ;
475+
break;
476+
case NSAlertOtherReturn /* -1 */ :
477+
recoveryOptionIndex = 2 ;
478+
break;
479+
default:
480+
// This should never happen since we only have 3 buttons and return
481+
// one of the above three values like NSAlert.
482+
NSLog(@"Warning 520-3840 %d", recoveryOption) ;
483+
recoveryOptionIndex = recoveryOption ;
484+
break;
485+
}
486+
487+
return recoveryOptionIndex ;
488+
}
489+
457490
+ (NSInteger)tryRecoveryAttempterForError:(NSError*)error
458491
recoveryOption:(NSUInteger)recoveryOption
459492
contextInfo:(NSMutableDictionary*)infoDictionary {
@@ -471,29 +504,70 @@ + (NSInteger)tryRecoveryAttempterForError:(NSError*)error
471504
NSInvocation* invocation = [error didRecoverInvocation] ;
472505
id delegate = [invocation target] ;
473506
SEL didRecoverSelector = [invocation selector] ;
474-
// It seems that the "Cocoa way" of recovering, using the delegate and
475-
// didRecoverSelector, only works if didRecoverSelector has no arguments.
476-
// That's why I put the whole invocation into the context info. I believe
477-
// it's alot cleaner anyhow.
507+
// I put the whole invocation into the context info, believing it to be alot cleaner.
478508
if (invocation) {
479509
// Before we invoke the didRecoverInvocation, we also put it into the
480510
// current infoDictionary in case an error occurs again and we need
481511
// to re-recover.
482512
[infoDictionary setObject:invocation
483513
forKey:SSYAlertDidRecoverInvocationKey] ;
484514
}
485-
[recoveryAttempter attemptRecoveryFromError:[[error retain] autorelease]
515+
[recoveryAttempter attemptRecoveryFromError:[[deepestRecoverableError retain] autorelease]
486516
recoveryOption:recoveryOption
487517
delegate:delegate
488518
didRecoverSelector:didRecoverSelector
489519
contextInfo:[[infoDictionary retain] autorelease]] ;
490520
// Also, the retain] autorelease] is probably not necessary since I'm invoking attemptRecoveryFromError:::::
491521
// directly, but I'm always fearful of crashes due to invalid contextInfo.
492-
result = SSYAlertRecoveryWentAsynchronous ;
522+
result = SSYAlertRecoveryAttemptedAsynchronously ;
523+
}
524+
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:)]) {
525+
/* This is an error produced by Cocoa.
526+
In particular, in Mac OS X 10.7, it might be one like this:
527+
Error Domain = NSCocoaErrorDomain
528+
Code = 67000
529+
UserInfo = {
530+
• NSLocalizedRecoverySuggestion=Click Save Anyway to keep your changes and save the
531+
changes made by the other application as a version, or click Revert to keep the changes from the other
532+
application and save your changes as a version.
533+
• NSLocalizedFailureReason=The file has been changed by another application.
534+
• NSLocalizedDescription=This document’s file has been changed by another application.
535+
• NSLocalizedRecoveryOptions = ("Save Anyway", "Revert")
536+
}
537+
*/
538+
NSInvocation* invocation = [error didRecoverInvocation] ;
539+
id delegate = [invocation target] ;
540+
SEL didRecoverSelector = [invocation selector] ;
541+
// I put the whole invocation into the context info, believing it to be alot cleaner.
542+
if (invocation) {
543+
// Before we invoke the didRecoverInvocation, we also put it into the
544+
// current infoDictionary in case an error occurs again and we need
545+
// to re-recover.
546+
[infoDictionary setObject:invocation
547+
forKey:SSYAlertDidRecoverInvocationKey] ;
548+
}
549+
NSInteger recoveryOptionIndex = [self recoveryOptionIndexForRecoveryOption:recoveryOption] ;
550+
551+
[recoveryAttempter attemptRecoveryFromError:[[deepestRecoverableError retain] autorelease]
552+
optionIndex:recoveryOptionIndex
553+
delegate:delegate
554+
didRecoverSelector:didRecoverSelector
555+
contextInfo:[[infoDictionary retain] autorelease]] ;
556+
// Also, the retain] autorelease] is probably not necessary since I'm invoking attemptRecoveryFromError:::::
557+
// directly, but I'm always fearful of crashes due to invalid contextInfo.
558+
result = SSYAlertRecoveryAttemptedAsynchronously ;
493559
}
494560
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:recoveryOption:)]) {
495-
BOOL ok = [recoveryAttempter attemptRecoveryFromError:error
496-
recoveryOption:recoveryOption] ;
561+
BOOL ok = [recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
562+
recoveryOption:recoveryOption] ;
563+
564+
result = ok ? SSYAlertRecoverySucceeded : SSYAlertRecoveryFailed ;
565+
}
566+
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:)]) {
567+
// This is an error produced by Cocoa.
568+
NSInteger recoveryOptionIndex = [self recoveryOptionIndexForRecoveryOption:recoveryOption] ;
569+
BOOL ok = [recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
570+
optionIndex:recoveryOptionIndex] ;
497571

498572
result = ok ? SSYAlertRecoverySucceeded : SSYAlertRecoveryFailed ;
499573
}
@@ -1900,19 +1974,20 @@ - (void)alertError:(NSError*)error
19001974
[self noteError:error] ;
19011975
}
19021976

1903-
- (int)alertError:(NSError*)error {
1977+
- (SSYAlertRecovery)alertError:(NSError*)error {
19041978
if (!error) {
1905-
return SSYAlertRecoveryWasNoError ;
1979+
return SSYAlertRecoveryThereWasNoError ;
19061980
}
19071981

1908-
int alertReturn_ = NSAlertErrorReturn ;
1982+
int alertReturn ;
19091983

1910-
if (
1911-
![gSSYAlertErrorHideManager shouldHideError:error]
1912-
&&
1913-
!(([[error domain] isEqualToString:NSCocoaErrorDomain]) && ([error code] == NSUserCancelledError))
1914-
) {
1915-
1984+
if ([gSSYAlertErrorHideManager shouldHideError:error]) {
1985+
alertReturn = SSYAlertRecoveryErrorIsHidden ;
1986+
}
1987+
else if ([[error domain] isEqualToString:NSCocoaErrorDomain] && ([error code] == NSUserCancelledError)) {
1988+
alertReturn = SSYAlertRecoveryAppleScriptCodeUserCancelledPreviously ;
1989+
}
1990+
else {
19161991
[self doLayoutError:error] ;
19171992
[self display] ;
19181993

@@ -1923,26 +1998,26 @@ - (int)alertError:(NSError*)error {
19231998
[NSApp runModalForWindow:[self window]] ;
19241999
// Will block here until user clicks a button
19252000

1926-
alertReturn_ = [self alertReturn] ;
2001+
alertReturn = [self alertReturn] ;
19272002
NSInteger recoveryResult = [SSYAlert tryRecoveryAttempterForError:error
1928-
recoveryOption:alertReturn_
2003+
recoveryOption:alertReturn
19292004
contextInfo:nil] ;
19302005
if (recoveryResult != SSYAlertRecoveryNotAttempted) {
1931-
alertReturn_ = recoveryResult ;
2006+
alertReturn = recoveryResult ;
19322007
}
19332008
}
19342009

19352010
[self noteError:error] ;
19362011

1937-
return alertReturn_ ;
2012+
return alertReturn ;
19382013
}
19392014

1940-
+ (int)alertError:(NSError*)error {
2015+
+ (SSYAlertRecovery)alertError:(NSError*)error {
19412016
// In BookMacster 1.1.10, I found that Core Data migration, specifically
19422017
// -[Bkmx007-008MigrationPolicy createDestinationInstancesForSourceInstance:::]
19432018
// was spending 99% of its time creating SSYAlerts for nil errors! Fix…
19442019
if (!error) {
1945-
return SSYAlertRecoveryWasNoError ;
2020+
return SSYAlertRecoveryThereWasNoError ;
19462021
}
19472022

19482023
return [[SSYAlert alert] alertError:error] ;

SSYAlertSounder.h

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
NSMutableDictionary* m_soundIds ;
1717
}
1818

19+
/*!
20+
@brief Plays a desired sound
21+
22+
@details
23+
@param name The name of a sound file, not including the .aiff extension.
24+
*/
1925
- (void)playAlertSoundNamed:(NSString*)name ;
2026

2127
+ (SSYAlertSounder*)sharedSounder ;

0 commit comments

Comments
 (0)