root/tags/2C10/JVChatConsole.m

Revision 1956, 20.9 kB (checked in by timothy, 4 years ago)

Don't show bans as simply "*" if verbose mode is off.

Line 
1 #import <ChatCore/MVChatConnection.h>
2 #import <ChatCore/MVChatPluginManager.h>
3 #import <ChatCore/NSMethodSignatureAdditions.h>
4
5 #import "JVChatConsole.h"
6 #import "JVChatController.h"
7 #import "MVTextView.h"
8 #import "NSSplitViewAdditions.h"
9
10 static NSString *JVToolbarToggleVerboseItemIdentifier = @"JVToolbarToggleVerboseItem";
11 static NSString *JVToolbarTogglePrivateMessagesItemIdentifier = @"JVToolbarTogglePrivateMessagesItem";
12 static NSString *JVToolbarClearItemIdentifier = @"JVToolbarClearItem";
13
14 @implementation JVChatConsole
15 - (id) initWithConnection:(MVChatConnection *) connection {
16         if( ( self = [self init] ) ) {
17                 _sendHistory = [[NSMutableArray array] retain];
18                 [_sendHistory insertObject:[[[NSAttributedString alloc] initWithString:@""] autorelease] atIndex:0];
19
20                 _historyIndex = 0;
21                 _paused = NO;
22                 _forceSplitViewPosition = YES;
23
24                 _connection = [connection retain];
25                 _verbose = [[NSUserDefaults standardUserDefaults] boolForKey:@"JVChatVerboseConsoleMessages"];
26                 _ignorePRIVMSG = [[NSUserDefaults standardUserDefaults] boolForKey:@"JVChatConsoleIgnoreUserChatMessages"];
27
28                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _gotRawMessage: ) name:MVChatConnectionGotRawMessageNotification object:connection];
29                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( clearConsole: ) name:MVChatConnectionWillConnectNotification object:connection];
30
31                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _refreshIcon: ) name:MVChatConnectionDidConnectNotification object:connection];
32                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( _refreshIcon: ) name:MVChatConnectionDidDisconnectNotification object:connection];
33         }
34         return self;
35 }
36
37 - (void) awakeFromNib {
38         [send setUsesSystemCompleteOnTab:[[NSUserDefaults standardUserDefaults] boolForKey:@"JVUsePantherTextCompleteOnTab"]];
39         [send setContinuousSpellCheckingEnabled:NO];
40         [send setUsesFontPanel:NO];
41         [send setUsesRuler:NO];
42         [send setImportsGraphics:NO];
43         [send reset:nil];
44
45         [display setContinuousSpellCheckingEnabled:NO];
46         [display setUsesFontPanel:NO];
47         [display setUsesRuler:NO];
48         [display setImportsGraphics:NO];
49
50 //      [(NSSplitView *)[[[send superview] superview] superview] setPositionUsingName:@"JVConsoleSplitViewPosition"];
51 }
52
53 - (void) dealloc {
54         [[NSNotificationCenter defaultCenter] removeObserver:self];
55        
56         [contents release];
57         [_sendHistory release];
58         [_connection release];
59
60         contents = nil;
61         _connection = nil;
62         _sendHistory = nil;
63         _windowController = nil;
64
65         [super dealloc];
66 }
67
68 - (NSString *) description {
69         return [NSString stringWithFormat:@"%@ - %@", [super description], [self title]];
70 }
71
72 #pragma mark -
73
74 - (IBAction) clearConsole:(id) sender {
75         [display setString:@""];
76 }
77
78 - (IBAction) toggleVerbose:(id) sender {
79         _verbose = ! _verbose;
80 }
81
82 - (IBAction) toggleMessages:(id) sender {
83         _ignorePRIVMSG = ! _ignorePRIVMSG;
84 }
85
86 - (IBAction) close:(id) sender {
87         [[JVChatController defaultManager] disposeViewController:self];
88 }
89
90 #pragma mark -
91
92 - (JVChatWindowController *) windowController {
93         return [[_windowController retain] autorelease];
94 }
95
96 - (void) setWindowController:(JVChatWindowController *) controller {
97         _windowController = controller;
98 }
99
100 #pragma mark -
101
102 - (NSView *) view {
103         if( ! _nibLoaded ) _nibLoaded = [NSBundle loadNibNamed:@"JVChatConsole" owner:self];
104         return contents;
105 }
106
107 - (NSResponder *) firstResponder {
108         return send;
109 }
110
111 - (NSToolbar *) toolbar {
112         NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"Console"];
113         [toolbar setDelegate:self];
114         [toolbar setAllowsUserCustomization:YES];
115         [toolbar setAutosavesConfiguration:YES];
116         return [toolbar autorelease];
117 }
118
119 #pragma mark -
120
121 - (BOOL) isEnabled {
122         return ! ( ! [[self connection] isConnected] && [[self connection] status] != MVChatConnectionConnectingStatus );
123 }
124
125 - (NSString *) title {
126         return [_connection server];
127 }
128
129 - (NSString *) windowTitle {
130         return [NSString stringWithFormat:NSLocalizedString( @"%@ - Console", "chat console - window title" ), [_connection server]];
131 }
132
133 - (NSString *) information {
134         if( ! [[self connection] isConnected] && [[self connection] status] != MVChatConnectionConnectingStatus )
135                 return NSLocalizedString( @"disconnected", "disconnected status info line in drawer" );
136         return nil;
137 }
138
139 - (NSString *) toolTip {
140         if( ! [[self connection] lag] ) return [self title];
141         return [NSString stringWithFormat:NSLocalizedString( @"%@\n%.3f seconds lag", "console tooltip witg lag (server delay) info in seconds" ), [self title], [[self connection] lag] / 1000.];
142 }
143
144 #pragma mark -
145
146 - (id <JVChatListItem>) parent {
147         return nil;
148 }
149
150 #pragma mark -
151
152 - (NSMenu *) menu {
153         NSMenu *menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
154         NSMenuItem *item = nil;
155
156         item = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString( @"Get Info", "get info contextual menu item title" ) action:@selector( getInfo: ) keyEquivalent:@""] autorelease];
157         [item setTarget:_windowController];
158         [menu addItem:item];
159
160         item = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString( @"Clear Display", "clear console contextual menu item title" ) action:@selector( clearConsole: ) keyEquivalent:@""] autorelease];
161         [item setTarget:self];
162         [menu addItem:item];
163
164         [menu addItem:[NSMenuItem separatorItem]];
165
166         item = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString( @"Detach From Window", "detach from window contextual menu item title" ) action:@selector( detachView: ) keyEquivalent:@""] autorelease];
167         [item setRepresentedObject:self];
168         [item setTarget:[JVChatController defaultManager]];
169         [menu addItem:item];
170
171         item = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString( @"Close", "close contextual menu item title" ) action:@selector( close: ) keyEquivalent:@""] autorelease];
172         [item setTarget:self];
173         [menu addItem:item];
174
175         return [[menu retain] autorelease];
176 }
177
178 - (NSImage *) icon {
179         return [NSImage imageNamed:@"console"];
180 }
181
182 #pragma mark -
183
184 - (NSString *) identifier {
185         return [NSString stringWithFormat:@"Console %@", [_connection server]];
186 }
187
188 - (MVChatConnection *) connection {
189         return _connection;
190 }
191
192 #pragma mark -
193
194 - (void) pause {
195         if( [[self connection] type] == MVChatConnectionIRCType )
196                 _paused = YES;
197 }
198
199 - (void) resume {
200         _paused = NO;
201 }
202
203 - (BOOL) isPaused {
204         return _paused;
205 }
206
207 - (void) addMessageToDisplay:(NSString *) message asOutboundMessage:(BOOL) outbound {
208         NSAttributedString *msg = nil;
209         NSMutableString *strMsg = [[message mutableCopy] autorelease];
210         NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
211         NSMutableParagraphStyle *para = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
212         unsigned int numeric = 0;
213
214         if( [[self connection] type] == MVChatConnectionIRCType ) {
215                 if( ! [strMsg length] || ( _ignorePRIVMSG && [strMsg rangeOfString:@"PRIVMSG"].location != NSNotFound && [strMsg rangeOfString:@"\001"].location == NSNotFound ) )
216                         return;
217
218                 if( ! _verbose ) {
219                         [strMsg replaceOccurrencesOfString:@":" withString:@"" options:NSAnchoredSearch range:NSMakeRange( 0, 1 )];
220                         [strMsg replaceOccurrencesOfString:@" :" withString:@" " options:NSLiteralSearch range:NSMakeRange( 0, [strMsg length] )];
221                 }
222
223                 [strMsg replaceOccurrencesOfString:@"\r\n" withString:@"" options:NSAnchoredSearch | NSBackwardsSearch range:NSMakeRange( 0, [strMsg length] )];
224
225                 if( ! outbound && ! _verbose ) {
226                         NSMutableArray *parts = [[[strMsg componentsSeparatedByString:@" "] mutableCopy] autorelease];
227                         NSString *tempStr = nil;
228                         unsigned i = 0, c = 0;
229
230                         if( [parts count] >= 3 && [[parts objectAtIndex:2] isEqualToString:[_connection nickname]] )
231                                 [parts removeObjectAtIndex:2];
232
233                         if( [parts count] >= 2 && ( numeric = [[parts objectAtIndex:1] intValue] ) )
234                                 [parts removeObjectAtIndex:1];
235                         else if( [parts count] >= 2 && ( [[parts objectAtIndex:1] isEqualToString:@"PRIVMSG"] && [strMsg rangeOfString:@"\001"].location != NSNotFound && [strMsg rangeOfString:@" ACTION"].location == NSNotFound ) )
236                                 [parts replaceObjectAtIndex:1 withObject:@"CTCP REQUEST"];
237                         else if( [parts count] >= 2 && ( [[parts objectAtIndex:1] isEqualToString:@"NOTICE"] && [strMsg rangeOfString:@"\001"].location != NSNotFound ) )
238                                 [parts replaceObjectAtIndex:1 withObject:@"CTCP REPLY"];
239
240                         tempStr = [parts objectAtIndex:0];
241                         if( tempStr && [tempStr rangeOfString:@"@"].location == NSNotFound && [tempStr rangeOfString:@"."].location != NSNotFound && [NSURL URLWithString:[@"irc://" stringByAppendingString:tempStr]] ) {
242                                 [parts removeObjectAtIndex:0];
243                         } else if( [tempStr hasPrefix:[NSString stringWithFormat:@"%@!", [_connection nickname]]] ) {
244                                 [parts removeObjectAtIndex:0];
245                         }
246
247                         for( i = 0, c = [parts count]; i < c; i++ ) {
248                                 tempStr = [@"irc://" stringByAppendingString:[parts objectAtIndex:i]];
249                                 if( ( tempStr = [[NSURL URLWithString:tempStr] user] ) && [tempStr rangeOfString:@"!"].location != NSNotFound && [tempStr rangeOfString:@"*"].location == NSNotFound )
250                                         [parts replaceObjectAtIndex:i withObject:[tempStr substringToIndex:[tempStr rangeOfString:@"!"].location]];
251                         }
252
253                         strMsg = (NSMutableString *) [parts componentsJoinedByString:@" "];
254                         if( numeric ) strMsg = [NSString stringWithFormat:@"%03u: %@", numeric, strMsg];
255                 } else if( outbound && ! _verbose ) {
256                         if( [strMsg rangeOfString:@"NOTICE"].location != NSNotFound && [strMsg rangeOfString:@"\001"].location != NSNotFound ) {
257                                 [strMsg replaceOccurrencesOfString:@"NOTICE" withString:@"CTCP REPLY" options:NSAnchoredSearch range:NSMakeRange( 0, 6 )];
258                         } else if( [strMsg rangeOfString:@"PRIVMSG"].location != NSNotFound && [strMsg rangeOfString:@"\001"].location != NSNotFound && [strMsg rangeOfString:@" ACTION"].location == NSNotFound ) {
259                                 [strMsg replaceOccurrencesOfString:@"PRIVMSG" withString:@"CTCP REQUEST" options:NSAnchoredSearch range:NSMakeRange( 0, 7 )];
260                         }
261                 }
262         }
263
264         [para setParagraphSpacing:3.];
265         [para setMaximumLineHeight:9.];
266         if( ! outbound ) [para setMaximumLineHeight:9.];
267         else [para setMaximumLineHeight:11.];
268
269         if( outbound ) [attrs setObject:[NSFont boldSystemFontOfSize:11.] forKey:NSFontAttributeName];
270         else [attrs setObject:[[NSFontManager sharedFontManager] fontWithFamily:@"Monaco" traits:0 weight:5 size:9.] forKey:NSFontAttributeName];
271         [attrs setObject:para forKey:NSParagraphStyleAttributeName];
272
273         msg = [[[NSAttributedString alloc] initWithString:strMsg attributes:attrs] autorelease];
274         if( [[display textStorage] length] )
275                 [display replaceCharactersInRange:NSMakeRange( [[display textStorage] length], 0 ) withString:@"\n"];
276         [[display textStorage] appendAttributedString:msg];
277         if( NSMinY( [display visibleRect] ) >= ( NSHeight( [display bounds] ) - ( NSHeight( [display visibleRect] ) * 1.1 ) ) )
278                 [display scrollRangeToVisible:NSMakeRange( [[display textStorage] length], 0 )];
279 }
280
281 #pragma mark -
282
283 - (void) send:(id) sender {
284         NSMutableAttributedString *subMsg = nil;
285         NSRange range;
286
287         if( ! [[self connection] isConnected] ) return;
288
289         [self resume];
290
291         _historyIndex = 0;
292         if( ! [[send textStorage] length] ) return;
293         if( [_sendHistory count] )
294                 [_sendHistory replaceObjectAtIndex:0 withObject:[[[NSAttributedString alloc] initWithString:@""] autorelease]];
295         [_sendHistory insertObject:[[[send textStorage] copy] autorelease] atIndex:1];
296         if( [_sendHistory count] > [[[NSUserDefaults standardUserDefaults] objectForKey:@"JVChatMaximumHistory"] unsignedIntValue] )
297                 [_sendHistory removeObjectAtIndex:[_sendHistory count] - 1];
298
299         while( [[send textStorage] length] ) {
300                 range = [[[send textStorage] string] rangeOfString:@"\n"];
301                 if( ! range.length ) range.location = [[send textStorage] length];
302                 subMsg = [[[[send textStorage] attributedSubstringFromRange:NSMakeRange( 0, range.location )] mutableCopy] autorelease];
303
304                 if( ( [subMsg length] >= 1 && range.length ) || ( [subMsg length] && ! range.length ) ) {
305                         if( [[subMsg string] hasPrefix:@"/"] ) {
306                                 NSScanner *scanner = [NSScanner scannerWithString:[subMsg string]];
307                                 NSString *command = nil;
308                                 NSAttributedString *arguments = nil;
309
310                                 [scanner scanString:@"/" intoString:nil];
311                                 [scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:&command];
312                                 if( [[subMsg string] length] >= [scanner scanLocation] + 1 )
313                                         [scanner setScanLocation:[scanner scanLocation] + 1];
314
315                                 arguments = [subMsg attributedSubstringFromRange:NSMakeRange( [scanner scanLocation], range.location - [scanner scanLocation] )];
316
317                                 NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( BOOL ), @encode( NSString * ), @encode( NSAttributedString * ), @encode( MVChatConnection * ), @encode( id ), nil];
318                                 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
319
320                                 [invocation setSelector:@selector( processUserCommand:withArguments:toConnection:inView: )];
321                                 [invocation setArgument:&command atIndex:2];
322                                 [invocation setArgument:&arguments atIndex:3];
323                                 [invocation setArgument:&_connection atIndex:4];
324                                 [invocation setArgument:&self atIndex:5];
325
326                                 NSArray *results = [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation stoppingOnFirstSuccessfulReturn:YES];
327
328                                 if( ! [[results lastObject] boolValue] )
329                                         [[self connection] sendRawMessage:[command stringByAppendingFormat:@" %@", [arguments string]]];
330                         } else {
331                                 [[self connection] sendRawMessage:[subMsg string]];
332                         }
333                 }
334                 if( range.length ) range.location++;
335                 [[send textStorage] deleteCharactersInRange:NSMakeRange( 0, range.location )];
336         }
337
338         [send reset:nil];
339         [display scrollRangeToVisible:NSMakeRange( [[display textStorage] length], 0 )];
340 }
341
342 - (BOOL) textView:(NSTextView *) textView enterKeyPressed:(NSEvent *) event {
343         [self send:nil];
344         return YES;
345 }
346
347 - (BOOL) textView:(NSTextView *) textView returnKeyPressed:(NSEvent *) event {
348         [self send:nil];
349         return YES;
350 }
351
352 - (BOOL) upArrowKeyPressed {
353         if( ! _historyIndex && [_sendHistory count] )
354                 [_sendHistory replaceObjectAtIndex:0 withObject:[[[send textStorage] copy] autorelease]];
355         _historyIndex++;
356         if( _historyIndex >= [_sendHistory count] ) {
357                 _historyIndex = [_sendHistory count] - 1;
358                 if( (signed) _historyIndex < 0 ) _historyIndex = 0;
359                 return YES;
360         }
361         [send reset:nil];
362         [[send textStorage] insertAttributedString:[_sendHistory objectAtIndex:_historyIndex] atIndex:0];
363         return YES;
364 }
365
366 - (BOOL) downArrowKeyPressed {
367         if( ! _historyIndex && [_sendHistory count] )
368                 [_sendHistory replaceObjectAtIndex:0 withObject:[[[send textStorage] copy] autorelease]];
369         if( [[send textStorage] length] ) _historyIndex--;
370         if( _historyIndex < 0 ) {
371                 [send reset:nil];
372                 _historyIndex = -1;
373                 return YES;
374         } else if( ! [_sendHistory count] ) {
375                 _historyIndex = 0;
376                 return YES;
377         }
378         [send reset:nil];
379         [[send textStorage] insertAttributedString:[_sendHistory objectAtIndex:_historyIndex] atIndex:0];
380         return YES;
381 }
382
383 - (BOOL) textView:(NSTextView *) textView functionKeyPressed:(NSEvent *) event {
384         unichar chr = 0;
385
386         if( [[event charactersIgnoringModifiers] length] ) {
387                 chr = [[event charactersIgnoringModifiers] characterAtIndex:0];
388         } else return NO;
389
390         // exclude device-dependent flags, caps-lock and fn key (necessary for pg up/pg dn/home/end on portables)
391         if( [event modifierFlags] & ~( NSFunctionKeyMask | NSNumericPadKeyMask | NSAlphaShiftKeyMask | 0xffff ) ) return NO;
392
393         if( chr == NSUpArrowFunctionKey ) {
394                 return [self upArrowKeyPressed];
395         } else if( chr == NSDownArrowFunctionKey ) {
396                 return [self downArrowKeyPressed];
397         }
398
399         return NO;
400 }
401
402 - (NSArray *) completionsFor:(NSString *) inFragment {
403         return nil;
404 }
405
406 - (BOOL) textView:(NSTextView *) textView escapeKeyPressed:(NSEvent *) event {
407         [send reset:nil];
408         return YES;     
409 }
410
411 - (void) textDidChange:(NSNotification *) notification {
412         _historyIndex = 0;
413 }
414
415 #pragma mark -
416 #pragma mark Toolbar Support
417
418 - (NSToolbarItem *) toolbar:(NSToolbar *) toolbar itemForItemIdentifier:(NSString *) identifier willBeInsertedIntoToolbar:(BOOL) willBeInserted {
419         NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
420         if( [identifier isEqual:JVToolbarToggleChatDrawerItemIdentifier] ) {
421                 toolbarItem = [_windowController toggleChatDrawerToolbarItem];
422         } else if( [identifier isEqual:JVToolbarClearItemIdentifier] ) {
423                 [toolbarItem setLabel:NSLocalizedString( @"Clear", "clear console toolbar button name" )];
424                 [toolbarItem setPaletteLabel:NSLocalizedString( @"Clear Console", "clear console toolbar customize palette name" )];
425
426                 [toolbarItem setToolTip:NSLocalizedString( @"Clear Console", "clear console tooltip" )];
427                 [toolbarItem setImage:[NSImage imageNamed:@"clear"]];
428
429                 [toolbarItem setTarget:self];
430                 [toolbarItem setAction:@selector( clearConsole: )];
431         } else if( [identifier isEqual:JVToolbarToggleVerboseItemIdentifier] ) {
432                 [toolbarItem setLabel:NSLocalizedString( @"Verbose", "verbose toolbar button name" )];
433                 [toolbarItem setPaletteLabel:NSLocalizedString( @"Toggle Verbose", "toggle verbose toolbar customize palette name" )];
434
435                 [toolbarItem setToolTip:NSLocalizedString( @"Toggle Verbose Output", "toggle verbose output tooltip" )];
436                 [toolbarItem setImage:[NSImage imageNamed:@"reveal"]];
437
438                 [toolbarItem setTarget:self];
439                 [toolbarItem setAction:@selector( toggleVerbose: )];
440         } else if( [identifier isEqual:JVToolbarTogglePrivateMessagesItemIdentifier] ) {
441                 [toolbarItem setLabel:NSLocalizedString( @"Messages", "toggle private messages toolbar button name" )];
442                 [toolbarItem setPaletteLabel:NSLocalizedString( @"Toggle Messages", "toggle private messages toolbar customize palette name" )];
443
444                 [toolbarItem setToolTip:NSLocalizedString( @"Toggle Private Messages Output", "toggle private messages output tooltip" )];
445                 [toolbarItem setImage:[NSImage imageNamed:@"room"]];
446
447                 [toolbarItem setTarget:self];
448                 [toolbarItem setAction:@selector( toggleMessages: )];
449         } else toolbarItem = nil;
450         return toolbarItem;
451 }
452
453 - (NSArray *) toolbarDefaultItemIdentifiers:(NSToolbar *) toolbar {
454         NSArray *list = [NSArray arrayWithObjects:JVToolbarToggleChatDrawerItemIdentifier, JVToolbarClearItemIdentifier, nil];
455         return [[list retain] autorelease];
456 }
457
458 - (NSArray *) toolbarAllowedItemIdentifiers:(NSToolbar *) toolbar {
459         NSArray *list = [NSArray arrayWithObjects:JVToolbarToggleChatDrawerItemIdentifier, JVToolbarToggleVerboseItemIdentifier, JVToolbarTogglePrivateMessagesItemIdentifier, JVToolbarClearItemIdentifier, NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
460         return [[list retain] autorelease];
461 }
462 #pragma mark -
463 #pragma mark SplitView Support
464
465 - (void) splitViewDidResizeSubviews:(NSNotification *) notification {
466         // Cache the height of the send box so we can keep it constant during window resizes.
467         NSRect sendFrame = [[[send superview] superview] frame];
468         _sendHeight = sendFrame.size.height;
469
470         if( _scrollerIsAtBottom ) {
471                 NSScrollView *scrollView = (NSScrollView *)[[display superview] superview];
472                 [scrollView scrollClipView:[scrollView contentView] toPoint:[[scrollView contentView] constrainScrollPoint:NSMakePoint( 0, [[scrollView documentView] bounds].size.height )]];
473                 [scrollView reflectScrolledClipView:[scrollView contentView]];
474         }
475
476         [[notification object] savePositionUsingName:@"JVConsoleSplitViewPosition"];
477         _forceSplitViewPosition = NO;
478 }
479
480 - (void) splitViewWillResizeSubviews:(NSNotification *) notification {
481         // The scrollbars are two subviews down from the JVWebView (deep in the WebKit bowls).
482         NSScrollView *scrollView = (NSScrollView *)[[display superview] superview];
483         if( [[scrollView verticalScroller] floatValue] == 1. ) _scrollerIsAtBottom = YES;
484         else _scrollerIsAtBottom = NO;
485 }
486
487 - (void) splitView:(NSSplitView *) sender resizeSubviewsWithOldSize:(NSSize) oldSize {
488         if( _forceSplitViewPosition ) {
489                 [sender adjustSubviews];
490                 return;
491         }
492
493         float dividerThickness = [sender dividerThickness];
494         NSRect newFrame = [sender frame];
495
496         // Keep the size of the send box constant during window resizes
497
498         // We need to resize the scroll view frames of the webview and the textview.
499         // The scroll views are two superviews up: NSTextView(WebView) -> NSClipView -> NSScrollView
500         NSRect sendFrame = [[[send superview] superview] frame];
501         NSRect displayFrame = [[[display superview] superview] frame];
502
503         // Set size of the web view to the maximum size possible
504         displayFrame.size.height = newFrame.size.height - dividerThickness - _sendHeight;
505         displayFrame.size.width = newFrame.size.width;
506         displayFrame.origin = NSMakePoint( 0., 0. );
507
508         // Keep the send box the same size
509         sendFrame.size.height = _sendHeight;
510         sendFrame.size.width = newFrame.size.width;
511         sendFrame.origin.y = displayFrame.size.height + dividerThickness;
512
513         // Commit the changes
514         [[[send superview] superview] setFrame:sendFrame];
515         [[[display superview] superview] setFrame:displayFrame];
516 }
517 @end
518
519 #pragma mark -
520
521 @implementation JVChatConsole (JVChatConsolePrivate)
522 - (void) _gotRawMessage:(NSNotification *) notification {
523         if( _paused ) return;
524         [self addMessageToDisplay:[[notification userInfo] objectForKey:@"message"] asOutboundMessage:[[[notification userInfo] objectForKey:@"outbound"] boolValue]];
525 }
526
527 - (void) _refreshIcon:(NSNotification *) notification {
528         [_windowController reloadListItem:self andChildren:NO];
529 }
530 @end
531
532 #pragma mark -
533
534 @implementation JVChatConsole (JVChatConsoleScripting)
535 - (NSNumber *) uniqueIdentifier {
536         return [NSNumber numberWithUnsignedInt:(unsigned long) self];
537 }
538 @end
Note: See TracBrowser for help on using the browser.