| Line 34... |
Line 34... |
@implementation TruePreview
|
@implementation TruePreview
|
|
|
#pragma mark Class initialization
|
#pragma mark Class initialization
|
|
|
+ (void)initialize {
|
+ (void)initialize {
|
[TruePreview registerBundle];
|
if (self == [TruePreview class]) {
|
|
class_setSuperclass(self, NSClassFromString(@"MVMailBundle"));
|
|
}
|
|
|
|
[super registerBundle];
|
|
|
// do our swizzles
|
// register the preferences value transformers
|
[NSPreferences
|
[NSValueTransformer
|
truePreviewSwizzleMethod:@selector(sharedPreferences)
|
setValueTransformer:[[TruePreviewPreferenceValueTransformer alloc] init]
|
withMethod:@selector(truePreviewSharedPreferences)
|
forName:@"TruePreviewPreferenceValueTransformer"
|
isClassMethod:YES
|
|
];
|
];
|
[LibraryMessage
|
[NSValueTransformer
|
|
setValueTransformer:[[TruePreviewPreferenceValueTransformerDelay alloc] init]
|
|
forName:@"TruePreviewPreferenceValueTransformerDelay"
|
|
];
|
|
[NSValueTransformer
|
|
setValueTransformer:[[TruePreviewPreferenceValueTransformerDelayEditIndicator alloc] init]
|
|
forName:@"TruePreviewPreferenceValueTransformerDelayEditIndicator"
|
|
];
|
|
|
|
// add our "categories"
|
|
[TruePreviewLibraryMessage truePreviewAddAsCategoryToClass:NSClassFromString(@"LibraryMessage")];
|
|
[TruePreviewMessageViewer truePreviewAddAsCategoryToClass:NSClassFromString(@"MessageViewer")];
|
|
[TruePreviewPreferences truePreviewAddAsCategoryToClass:NSClassFromString(@"NSPreferences")];
|
|
|
|
// do our swizzles
|
|
[NSClassFromString(@"LibraryMessage")
|
truePreviewSwizzleMethod:@selector(markAsViewed)
|
truePreviewSwizzleMethod:@selector(markAsViewed)
|
withMethod:@selector(truePreviewMarkAsViewed)
|
withMethod:@selector(truePreviewMarkAsViewed)
|
isClassMethod:NO
|
isClassMethod:NO
|
];
|
];
|
[TableViewManager
|
[NSClassFromString(@"MessageViewer")
|
truePreviewSwizzleMethod:@selector(setCurrentDisplayedMessage:)
|
truePreviewSwizzleMethod:@selector(dealloc)
|
withMethod:@selector(truePreviewSetCurrentDisplayedMessage:)
|
withMethod:@selector(truePreviewDealloc)
|
isClassMethod:NO
|
isClassMethod:NO
|
];
|
];
|
|
[NSClassFromString(@"MessageViewer")
|
|
truePreviewSwizzleMethod:@selector(markAsRead:)
|
|
withMethod:@selector(truePreviewMarkAsRead:)
|
|
isClassMethod:NO
|
|
];
|
|
[NSClassFromString(@"MessageViewer")
|
|
truePreviewSwizzleMethod:@selector(markAsUnread:)
|
|
withMethod:@selector(truePreviewMarkAsUnread:)
|
|
isClassMethod:NO
|
|
];
|
|
[NSClassFromString(@"MessageViewer")
|
|
truePreviewSwizzleMethod:@selector(messageWasDisplayedInTextView:)
|
|
withMethod:@selector(truePreviewMessageWasDisplayedInTextView:)
|
|
isClassMethod:NO
|
|
];
|
|
[NSClassFromString(@"MessageViewer")
|
|
truePreviewSwizzleMethod:@selector(messageNoLongerDisplayedInTextView:)
|
|
withMethod:@selector(truePreviewMessageNoLongerDisplayedInTextView:)
|
|
isClassMethod:NO
|
|
];
|
|
[NSClassFromString(@"NSPreferences")
|
|
truePreviewSwizzleMethod:@selector(sharedPreferences)
|
|
withMethod:@selector(truePreviewSharedPreferences)
|
|
isClassMethod:YES
|
|
];
|
|
|
|
|
[[NSUserDefaults standardUserDefaults]
|
[[NSUserDefaults standardUserDefaults]
|
registerDefaults:[NSDictionary
|
registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
|
dictionaryWithObject:[NSNumber numberWithInt:0] forKey:@"TruePreviewDelay"
|
[NSNumber numberWithInt:TRUEPREVIEW_DELAY_IMMEDIATE], @"TruePreviewDelay",
|
|
[NSNumber numberWithInt:NSOnState], @"TruePreviewWindow",
|
|
[NSNumber numberWithInt:NSOffState], @"TruePreviewScroll",
|
|
nil
|
]
|
]
|
];
|
];
|
|
|
|
|
NSLog(
|
NSLog(
|
@"Loaded TruePreview plugin %@",
|
@"Loaded TruePreview plugin %@",
|
[[NSBundle bundleForClass: [TruePreview class]] objectForInfoDictionaryKey: (NSString * )kCFBundleVersionKey ]
|
[[NSBundle bundleForClass: [TruePreview class]] objectForInfoDictionaryKey: (NSString * )kCFBundleVersionKey ]
|
);
|
);
|
}
|
}
|
| Line 72... |
Line 120... |
+ (BOOL)hasPreferencesPanel {
|
+ (BOOL)hasPreferencesPanel {
|
return YES;
|
return YES;
|
}
|
}
|
|
|
+ (NSString*)preferencesOwnerClassName {
|
+ (NSString*)preferencesOwnerClassName {
|
return NSStringFromClass ([TruePreviewPreferencesModule class]);
|
return @"TruePreviewPreferencesModule";
|
}
|
}
|
|
|
+ (NSString*)preferencesPanelName {
|
+ (NSString*)preferencesPanelName {
|
return @"TruePreview";
|
return @"TruePreview";
|
}
|
}
|
| Line 84... |
Line 132... |
@end
|
@end
|
|
|
@implementation NSObject (TruePreviewObject)
|
@implementation NSObject (TruePreviewObject)
|
|
|
#pragma mark Class methods
|
#pragma mark Class methods
|
|
|
|
+ (void )truePreviewAddAsCategoryToClass: (Class)inClass {
|
|
unsigned int theCount = 0;
|
|
Method* theMethods = class_copyMethodList (object_getClass ([self class]), &theCount );
|
|
Class theClass = object_getClass (inClass );
|
|
unsigned int i = 0;
|
|
|
|
while (YES) {
|
|
for (i = 0; i < theCount; i++) {
|
|
if (
|
|
!class_addMethod(
|
|
theClass,
|
|
method_getName(theMethods[i]),
|
|
method_getImplementation(theMethods[i]),
|
|
method_getTypeEncoding(theMethods[i])
|
|
)
|
|
) {
|
|
NSLog(
|
|
@"truePreviewAddAsCategoryToClass: could not add %@ to %@",
|
|
NSStringFromSelector(method_getName(theMethods[i])),
|
|
inClass
|
|
);
|
|
}
|
|
}
|
|
|
|
if (theMethods != nil) {
|
|
free(theMethods);
|
|
}
|
|
|
|
if (theClass != inClass) {
|
|
theClass = inClass;
|
|
theMethods = class_copyMethodList ([self class], &theCount );
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
+ (void)truePreviewSwizzleMethod:(SEL)inOriginalSelector withMethod:(SEL)inReplacementSelector isClassMethod:(BOOL)inIsClassMethod {
|
+ (void)truePreviewSwizzleMethod:(SEL)inOriginalSelector withMethod:(SEL)inReplacementSelector isClassMethod:(BOOL)inIsClassMethod {
|
Method theOriginalMethod = (!inIsClassMethod
|
Method theOriginalMethod = (!inIsClassMethod
|
? class_getInstanceMethod ([self class], inOriginalSelector )
|
? class_getInstanceMethod ([self class], inOriginalSelector )
|
: class_getClassMethod ([self class], inOriginalSelector )
|
: class_getClassMethod ([self class], inOriginalSelector )
|
| Line 95... |
Line 181... |
Method theReplacementMethod = (!inIsClassMethod
|
Method theReplacementMethod = (!inIsClassMethod
|
? class_getInstanceMethod ([self class], inReplacementSelector )
|
? class_getInstanceMethod ([self class], inReplacementSelector )
|
: class_getClassMethod ([self class], inReplacementSelector )
|
: class_getClassMethod ([self class], inReplacementSelector )
|
);
|
);
|
|
|
#if __OBJC2__
|
|
method_exchangeImplementations(theOriginalMethod, theReplacementMethod);
|
method_exchangeImplementations(theOriginalMethod, theReplacementMethod);
|
#else
|
|
char* theOriginalTypes = theOriginalMethod->method_types;
|
|
|
|
theOriginalMethod->method_types = theReplacementMethod->method_types;
|
|
theReplacementMethod->method_types = theOriginalTypes;
|
|
|
|
IMP theOriginalImp = theOriginalMethod->method_imp;
|
|
|
|
theOriginalMethod->method_imp = theReplacementMethod->method_imp;
|
|
theReplacementMethod->method_imp = theOriginalImp;
|
|
#endif
|
|
}
|
}
|
|
|
@end
|
@end
|
|
|
|
|