root/trunk/Plug-Ins/Ruby Support/JVRubyChatPlugin.m

Revision 3263, 5.1 kB (checked in by timothy, 2 years ago)

More warning fixes that Xcode never mentioned until I build universal. Thanks Xcode. :P

Line 
1 #import "JVRubyChatPlugin.h"
2 #import "JVChatWindowController.h"
3 #import "JVChatMessage.h"
4 #import "JVChatRoomPanel.h"
5 #import "JVChatRoomMember.h"
6 #import "NSStringAdditions.h"
7
8 NSString *JVRubyErrorDomain = @"JVRubyErrorDomain";
9
10 @implementation JVRubyChatPlugin
11 + (void) initialize {
12         static BOOL tooLate = NO;
13         if( ! tooLate ) {
14                 ruby_init();
15                 ruby_init_loadpath();
16                 RBRubyCocoaInit();
17                 tooLate = YES;
18         }
19 }
20
21 - (id) initWithManager:(MVChatPluginManager *) manager {
22         if( ( self = [self init] ) ) {
23                 _manager = manager;
24                 _path = nil;
25                 _modDate = [[NSDate date] retain];
26         }
27
28         return self;
29 }
30
31 - (id) initWithScriptAtPath:(NSString *) path withManager:(MVChatPluginManager *) manager {
32         if( ( self = [self initWithManager:manager] ) ) {
33                 _path = [path copyWithZone:[self zone]];
34                 _firstLoad = YES;
35
36                 [self reloadFromDisk];
37
38                 _firstLoad = NO;
39
40                 if( ! _script ) {
41                         [self release];
42                         return nil;
43                 }
44
45                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( checkForModifications: ) name:NSApplicationWillBecomeActiveNotification object:[NSApplication sharedApplication]];
46         }
47
48         return self;
49 }
50
51 - (void) dealloc {
52         [[NSNotificationCenter defaultCenter] removeObserver:self];
53
54         [_script release];
55         [_path release];
56         [_modDate release];
57
58         _path = nil;
59         _script = nil;
60         _manager = nil;
61         _modDate = nil;
62
63         [super dealloc];
64 }
65
66 #pragma mark -
67
68 - (MVChatPluginManager *) pluginManager {
69         return _manager;
70 }
71
72 - (NSString *) scriptFilePath {
73         return _path;
74 }
75
76 - (void) reloadFromDisk {
77         if( [_script respondsToSelector:@selector( unload )] )
78                 [_script performSelector:@selector( unload )];
79
80         NSString *contents = nil;
81         if( floor( NSAppKitVersionNumber ) <= NSAppKitVersionNumber10_3 ) // test for 10.3
82                 contents = [NSString stringWithContentsOfFile:[self scriptFilePath]];
83         else contents = [NSString stringWithContentsOfFile:[self scriptFilePath] encoding:NSUTF8StringEncoding error:NULL];
84
85         [_script autorelease];
86         _script = [[RBObject alloc] initWithRubyScriptString:contents];
87
88         if( ! _script ) {
89                 int result = NSRunCriticalAlertPanel( NSLocalizedStringFromTableInBundle( @"Ruby Script Error", nil, [NSBundle bundleForClass:[self class]], "Ruby script error title" ), NSLocalizedStringFromTableInBundle( @"The Ruby script \"%@\" had an error while loading.", nil, [NSBundle bundleForClass:[self class]], "Ruby script error message" ), nil, NSLocalizedStringFromTableInBundle( @"Edit...", nil, [NSBundle bundleForClass:[self class]], "edit button title" ), nil, [[[self scriptFilePath] lastPathComponent] stringByDeletingPathExtension] );
90                 if( result == NSCancelButton ) [[NSWorkspace sharedWorkspace] openFile:[self scriptFilePath]];
91                 return;
92         }
93
94         if( ! _firstLoad && [_script respondsToSelector:@selector( loadFromPath: )] )
95                 [_script performSelector:@selector( loadFromPath: ) withObject:[self scriptFilePath]];
96 }
97
98 #pragma mark -
99
100 - (void) promptForReload {
101         if( NSRunInformationalAlertPanel( NSLocalizedStringFromTableInBundle( @"Ruby Script Changed", nil, [NSBundle bundleForClass:[self class]], "Ruby script file changed dialog title" ), NSLocalizedStringFromTableInBundle( @"The Ruby script \"%@\" has changed on disk. Any script variables will reset if reloaded.", nil, [NSBundle bundleForClass:[self class]], "Ruby script changed on disk message" ), NSLocalizedStringFromTableInBundle( @"Reload", nil, [NSBundle bundleForClass:[self class]], "reload button title" ), NSLocalizedStringFromTableInBundle( @"Keep Previous Version", nil, [NSBundle bundleForClass:[self class]], "keep previous version button title" ), nil, [[[self scriptFilePath] lastPathComponent] stringByDeletingPathExtension] ) == NSOKButton ) {
102                 [self reloadFromDisk];
103         }
104 }
105
106 - (void) checkForModifications:(NSNotification *) notification {
107         if( ! [[self scriptFilePath] length] ) return;
108
109         NSFileManager *fm = [NSFileManager defaultManager];
110         if( [fm fileExistsAtPath:[self scriptFilePath]] ) {
111                 NSDictionary *info = [fm fileAttributesAtPath:[self scriptFilePath] traverseLink:YES];
112                 NSDate *fileModDate = [info fileModificationDate];
113                 if( [fileModDate compare:_modDate] == NSOrderedDescending && [fileModDate compare:[NSDate date]] == NSOrderedAscending ) { // newer script file
114                         [_modDate autorelease];
115                         _modDate = [[NSDate date] retain];
116                         [self performSelector:@selector( promptForReload ) withObject:nil afterDelay:0.];
117                 }
118         }
119 }
120
121 #pragma mark -
122
123 - (BOOL) respondsToSelector:(SEL) selector {
124         if( [_script respondsToSelector:selector] ) return YES;
125         else return [super respondsToSelector:selector];
126 }
127
128 - (void) forwardInvocation:(NSInvocation *) invocation {
129         if( [_script respondsToSelector:[invocation selector]] )
130                 [invocation invokeWithTarget:_script];
131         else [super forwardInvocation:invocation];
132 }
133
134 - (NSMethodSignature *) methodSignatureForSelector:(SEL) selector {
135         if( [_script respondsToSelector:selector] )
136                 return [(NSObject *)_script methodSignatureForSelector:selector];
137         else return [super methodSignatureForSelector:selector];
138 }
139
140 #pragma mark -
141
142 - (void) load { // call loadFromPath instead
143         if( [_script respondsToSelector:@selector( loadFromPath: )] )
144                 [_script performSelector:@selector( loadFromPath: ) withObject:[self scriptFilePath]];
145 }
146 @end
Note: See TracBrowser for help on using the browser.