Changeset 3414
- Timestamp:
- 01/04/06 18:05:22 (3 years ago)
- Files:
-
- WiredClient/trunk/WCAccounts.m (modified) (2 diffs)
- WiredClient/trunk/WCChat.m (modified) (54 diffs)
- WiredClient/trunk/WCMessages.m (modified) (24 diffs)
- WiredClient/trunk/WCPublicChat.m (modified) (18 diffs)
- WiredClient/trunk/WCSearch.m (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
WiredClient/trunk/WCAccounts.m
r3413 r3414 36 36 - (void)_updateStatus; 37 37 - (void)_validate; 38 39 - (WCAccount *)_accountAtIndex:(unsigned int)index; 38 40 - (WCAccount *)_selectedAccount; 39 41 - (NSArray *)_selectedAccounts; … … 87 89 88 90 89 - (WCAccount *)_accountAtIndex:(int)index { 90 int i; 91 #pragma mark - 92 93 - (WCAccount *)_accountAtIndex:(unsigned int)index { 94 unsigned int i; 91 95 92 96 i = ([_accountsTableView sortOrder] == WISortDescending) 93 ? [_shownAccounts count] - (unsigned int)index - 194 : (unsigned int)index;97 ? [_shownAccounts count] - index - 1 98 : index; 95 99 96 100 return [_shownAccounts objectAtIndex:i]; WiredClient/trunk/WCChat.m
r3413 r3414 44 44 @interface WCChat(Private) 45 45 46 - (void) update;47 - (void) updateTopic;48 49 - (void) printString:(NSString *)message;50 - (void) printTimestamp;51 - (void) printUserJoin:(WCUser *)user;52 - (void) printUserLeave:(WCUser *)user;53 - (void) printUserChange:(WCUser *)user nick:(NSString *)nick;54 - (void) printUserKick:(WCUser *)victim by:(WCUser *)killer message:(NSString *)message;55 - (void) printUserBan:(WCUser *)victim by:(WCUser *)killer message:(NSString *)message;56 - (void) printChat:(NSString *)chat by:(WCUser *)user;57 - (void) printActionChat:(NSString *)chat by:(WCUser *)user;58 59 - (BOOL) runCommand:(NSString *)command;46 - (void)_update; 47 - (void)_updateTopic; 48 49 - (void)_printString:(NSString *)message; 50 - (void)_printTimestamp; 51 - (void)_printUserJoin:(WCUser *)user; 52 - (void)_printUserLeave:(WCUser *)user; 53 - (void)_printUserChange:(WCUser *)user nick:(NSString *)nick; 54 - (void)_printUserKick:(WCUser *)victim by:(WCUser *)killer message:(NSString *)message; 55 - (void)_printUserBan:(WCUser *)victim by:(WCUser *)killer message:(NSString *)message; 56 - (void)_printChat:(NSString *)chat by:(WCUser *)user; 57 - (void)_printActionChat:(NSString *)chat by:(WCUser *)user; 58 59 - (BOOL)_runCommand:(NSString *)command; 60 60 61 61 @end 62 62 63 63 64 @implementation WCChat(Private) 65 66 - (void)_update { 67 NSFont *font; 68 NSColor *color; 69 70 font = [WCSettings objectForKey:WCChatFont]; 71 72 if(![[_chatOutputTextView font] isEqualTo:font]) { 73 [_chatOutputTextView setFont:font]; 74 [_chatInputTextView setFont:font]; 75 [_setTopicTextView setFont:font]; 76 } 77 78 color = [WCSettings objectForKey:WCChatBackgroundColor]; 79 80 if(![[_chatOutputTextView backgroundColor] isEqualTo:color]) { 81 [_chatOutputTextView setBackgroundColor:color]; 82 [_chatInputTextView setBackgroundColor:color]; 83 [_setTopicTextView setBackgroundColor:color]; 84 } 85 86 color = [WCSettings objectForKey:WCChatTextColor]; 87 88 if(![[_chatOutputTextView textColor] isEqualTo:color]) { 89 [_chatOutputTextView setTextColor:color]; 90 [_chatInputTextView setTextColor:color]; 91 [_chatInputTextView setInsertionPointColor:color]; 92 [_setTopicTextView setTextColor:color]; 93 [_setTopicTextView setInsertionPointColor:color]; 94 95 [_chatOutputTextView setString:[_chatOutputTextView string] withFilter:_chatFilter]; 96 } 97 98 [_userListTableView setFont:[WCSettings objectForKey:WCChatUserListFont]]; 99 [_userListTableView setDrawsStripes:[WCSettings boolForKey:WCChatUserListAlternateRows]]; 100 101 [_chatOutputTextView setNeedsDisplay:YES]; 102 [_chatInputTextView setNeedsDisplay:YES]; 103 [_setTopicTextView setNeedsDisplay:YES]; 104 [_userListTableView setNeedsDisplay:YES]; 105 } 106 107 108 109 - (void)_updateTopic { 110 [_topicTextField setToolTip:[_topic topic]]; 111 [_topicTextField setStringValue:[_topic topic]]; 112 [_topicNickTextField setStringValue:[NSSWF: 113 NSLS(@"%@ %C %@", @"Chat topic set by (nick, time)"), 114 [_topic nick], 115 0x2014, 116 [[_topic date] commonDateStringWithSeconds:NO relative:YES capitalized:YES]]]; 117 } 118 119 120 121 #pragma mark - 122 123 - (void)_printString:(NSString *)string { 124 float position; 125 126 position = [[_chatOutputScrollView verticalScroller] floatValue]; 127 128 if([[_chatOutputTextView textStorage] length] > 0) 129 [[[_chatOutputTextView textStorage] mutableString] appendString:@"\n"]; 130 131 [_chatOutputTextView appendString:string withFilter:_chatFilter]; 132 133 if(position == 1.0) 134 [_chatOutputTextView performSelectorOnce:@selector(scrollToBottom) withObject:NULL afterDelay:0.05]; 135 } 136 137 138 139 - (void)_printTimestamp { 140 NSDate *date; 141 NSTimeInterval interval; 142 143 if(!_timestamp) 144 _timestamp = [[NSDate date] retain]; 145 146 interval = [[WCSettings objectForKey:WCTimestampChatInterval] doubleValue]; 147 date = [NSDate dateWithTimeIntervalSinceNow:-interval]; 148 149 if([date compare:_timestamp] == NSOrderedDescending) { 150 [self printEvent:[[NSDate date] fullDateStringWithSeconds:NO]]; 151 152 [_timestamp release]; 153 _timestamp = [[NSDate date] retain]; 154 } 155 } 156 157 158 159 - (void)_printUserJoin:(WCUser *)user { 160 [self printEvent:[NSSWF: 161 NSLS(@"%@ has joined", @"Client has joined message (nick)"), 162 [user nick]]]; 163 } 164 165 166 167 - (void)_printUserLeave:(WCUser *)user { 168 [self printEvent:[NSSWF: 169 NSLS(@"%@ has left", @"Client has left message (nick)"), 170 [user nick]]]; 171 } 172 173 174 175 - (void)_printUserChange:(WCUser *)user nick:(NSString *)nick { 176 [self printEvent:[NSSWF: 177 NSLS(@"%@ is now known as %@", @"Client rename message (oldnick, newnick)"), 178 [user nick], 179 nick]]; 180 } 181 182 183 184 - (void)_printUserKick:(WCUser *)victim by:(WCUser *)killer message:(NSString *)message { 185 [self printEvent:[NSSWF: 186 NSLS(@"%@ was kicked by %@ (%@)", @"Client kicked message (victim, killer, message)"), 187 [victim nick], 188 [killer nick], 189 message]]; 190 } 191 192 193 194 - (void)_printUserBan:(WCUser *)victim by:(WCUser *)killer message:(NSString *)message { 195 [self printEvent:[NSSWF: 196 NSLS(@"%@ was banned by %@ (%@)", @"Client banned message (victim, killer, message)"), 197 [victim nick], 198 [killer nick], 199 message]]; 200 } 201 202 203 204 - (void)_printChat:(NSString *)chat by:(WCUser *)user { 205 NSString *output, *nick; 206 int offset, length; 207 208 switch([WCSettings intForKey:WCChatStyle]) { 209 case WCChatStyleWired: 210 default: 211 offset = [WCSettings boolForKey:WCTimestampEveryLine] ? WCChatPrepend - 4 : WCChatPrepend; 212 nick = [user nick]; 213 length = offset - [nick length]; 214 215 if(length < 0) 216 nick = [nick substringToIndex:offset]; 217 218 output = [NSSWF:NSLS(@"%@: %@", @"Chat message, Wired style (nick, message)"), 219 nick, chat]; 220 221 if(length > 0) 222 output = [NSSWF:@"%*s%@", length, " ", output]; 223 break; 224 225 case WCChatStyleIRC: 226 output = [NSSWF:NSLS(@"<%@> %@", @"Chat message, IRC style (nick, message)"), 227 [user nick], chat]; 228 break; 229 } 230 231 if([WCSettings boolForKey:WCTimestampEveryLine]) 232 output = [NSSWF:@"%@ %@", [[NSDate date] timeStringWithSeconds:NO], output]; 233 234 [self _printString:output]; 235 } 236 237 238 239 - (void)_printActionChat:(NSString *)chat by:(WCUser *)user { 240 NSString *output; 241 242 switch([WCSettings intForKey:WCChatStyle]) { 243 case WCChatStyleWired: 244 default: 245 output = [NSSWF:NSLS(@" *** %@ %@", @"Action chat message, Wired style (nick, message)"), 246 [user nick], chat]; 247 break; 248 249 case WCChatStyleIRC: 250 output = [NSSWF:NSLS(@" * %@ %@", @"Action chat message, IRC style (nick, message)"), 251 [user nick], chat]; 252 break; 253 } 254 255 if([WCSettings boolForKey:WCTimestampEveryLine]) 256 output = [NSSWF:@"%@ %@", [[NSDate date] timeStringWithSeconds:NO], output]; 257 258 [self _printString:output]; 259 } 260 261 262 263 #pragma mark - 264 265 - (BOOL)_runCommand:(NSString *)string { 266 NSString *command, *argument; 267 NSRange range; 268 269 range = [string rangeOfString:@" "]; 270 271 if(range.location == NSNotFound) { 272 command = string; 273 argument = @""; 274 } else { 275 command = [string substringToIndex:range.location]; 276 argument = [string substringFromIndex:range.location + 1]; 277 } 278 279 if([command isEqualToString:@"/me"] && [argument length] > 0) { 280 if([argument length] > WCChatLimit) 281 argument = [argument substringToIndex:WCChatLimit]; 282 283 [[self connection] sendCommand:WCMeCommand 284 withArgument:[NSSWF:@"%u", [self chatID]] 285 withArgument:argument]; 286 287 [WCStats addUnsignedLongLong:[argument length] forKey:WCStatsChat]; 288 289 return YES; 290 } 291 else if([command isEqualToString:@"/exec"] && [argument length] > 0) { 292 NSTask *task; 293 NSPipe *pipe; 294 NSFileHandle *fileHandle; 295 NSDictionary *environment; 296 NSData *data; 297 NSString *output; 298 double timeout = 10.0; 299 300 pipe = [NSPipe pipe]; 301 fileHandle = [pipe fileHandleForReading]; 302 303 environment = [NSDictionary dictionaryWithObjectsAndKeys: 304 @"/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin", 305 @"PATH", 306 NULL]; 307 308 task = [[NSTask alloc] init]; 309 [task setLaunchPath:@"/bin/sh"]; 310 [task setArguments:[NSArray arrayWithObjects:@"-c", argument, NULL]]; 311 [task setStandardOutput:pipe]; 312 [task setStandardError:pipe]; 313 [task setEnvironment:environment]; 314 [task launch]; 315 316 while([task isRunning]) { 317 sleep(1); 318 timeout -= 1.0; 319 320 if(timeout <= 0.0) { 321 [task terminate]; 322 323 break; 324 } 325 } 326 327 data = [fileHandle readDataToEndOfFile]; 328 output = [NSString stringWithData:data encoding:NSUTF8StringEncoding]; 329 330 if(output && [output length] > 0) { 331 if([output length] > WCChatLimit) 332 output = [output substringToIndex:WCChatLimit]; 333 334 [[self connection] sendCommand:WCSayCommand 335 withArgument:[NSSWF:@"%u", [self chatID]] 336 withArgument:output]; 337 338 [WCStats addUnsignedLongLong:[output length] forKey:WCStatsChat]; 339 } 340 341 [task release]; 342 343 return YES; 344 } 345 else if(([command isEqualToString:@"/nick"] || 346 [command isEqualToString:@"/n"]) && [argument length] > 0) { 347 [[self connection] sendCommand:WCNickCommand withArgument:argument]; 348 349 return YES; 350 } 351 else if([command isEqualToString:@"/status"] || [command isEqualToString:@"/s"]){ 352 [[self connection] sendCommand:WCStatusCommand withArgument:argument]; 353 354 return YES; 355 } 356 else if([command isEqualToString:@"/stats"]) { 357 [[self connection] sendCommand:WCSayCommand 358 withArgument:[NSSWF:@"%u", [self chatID]] 359 withArgument:[[WCStats stats] string]]; 360 361 return YES; 362 } 363 else if([command isEqualToString:@"/clear"]) { 364 [[[_chatOutputTextView textStorage] mutableString] setString:@""]; 365 366 return YES; 367 } 368 else if([command isEqualToString:@"/topic"]) { 369 [[self connection] sendCommand:WCTopicCommand 370 withArgument:[NSSWF:@"%u", [self chatID]] 371 withArgument:argument]; 372 373 return YES; 374 } 375 else if([command isEqualToString:@"/broadcast"] && [argument length] > 0) { 376 [[self connection] sendCommand:WCBroadcastCommand withArgument:argument]; 377 378 return YES; 379 } 380 #ifndef RELEASE 381 else if([command isEqualToString:@"/dump"]) { 382 [[self connection] sendCommand:WCDumpCommand]; 383 384 return YES; 385 } 386 #endif 387 388 return NO; 389 } 390 391 @end 392 393 64 394 @implementation WCChat 65 395 66 396 + (id)allocWithZone:(NSZone *)zone { 67 // --- guard against direct instantiaton68 397 if([self isEqual:[WCChat class]]) { 69 398 NSLog(@"*** -[%@ allocWithZone:]: attempt to instantiate abstract class", self); … … 85 414 _shownUsers = [[NSMutableArray alloc] init]; 86 415 87 // --- subscribe to these88 416 [[WCMain main] addObserver:self 89 417 selector:@selector(preferencesDidChange:) … … 94 422 name:WCDateDidChange]; 95 423 96 /* [[self connection] addObserver:self97 selector:@selector(chatConnectionHasClosed:)98 name:WCConnectionHasClosed];99 100 [[self connection] addObserver:self101 selector:@selector(chatConnectionHasReattached:)102 name:WCConnectionHasReattached];*/103 104 424 [[self connection] addObserver:self 105 425 selector:@selector(chatReceivedUser:) … … 175 495 WCUserCell *userCell; 176 496 177 // --- set up our custom cell type178 497 imageCell = [[NSImageCell alloc] init]; 179 498 [_iconTableColumn setDataCell:imageCell]; … … 184 503 [userCell release]; 185 504 186 // --- set up table view187 505 [_userListTableView setDoubleAction:@selector(sendPrivateMessage:)]; 188 506 189 // --- set up text view190 507 [_chatOutputTextView setForwardsTextToNextKeyView:YES]; 191 508 192 // --- create filter193 509 _chatFilter = [[WITextFilter alloc] init]; 194 510 [_chatFilter push:@selector(filterWiredChat)]; 195 511 [_chatFilter push:@selector(filterURLs)]; 196 512 197 // --- set from prefs 198 [self update]; 513 [self _update]; 199 514 [self validate]; 200 515 } … … 215 530 216 531 - (void)preferencesDidChange:(NSNotification *)notification { 217 [self update];532 [self _update]; 218 533 219 534 [_chatOutputTextView scrollToBottom]; … … 223 538 224 539 - (void)dateDidChange:(NSNotification *)notification { 225 [self updateTopic];540 [self _updateTopic]; 226 541 } 227 542 … … 268 583 return; 269 584 270 // --- allocate a new user and fill out the fields271 585 user = [[WCUser alloc] init]; 272 586 [user setUserID:[uid intValue]]; … … 280 594 [user setJoinDate:[NSDate date]]; 281 595 282 // --- decode image283 596 data = [NSData dataWithBase64EncodedString:icon]; 284 597 image = [[NSImage alloc] initWithData:data]; … … 286 599 [image release]; 287 600 288 // --- add it to our dictionary of users289 601 [_allUsers addObject:user]; 290 602 [_users setObject:user forKey:[NSNumber numberWithUnsignedInt:[user userID]]]; … … 298 610 NSString *cid; 299 611 300 // --- get the fields301 612 fields = [[notification userInfo] objectForKey:WCArgumentsKey]; 302 613 cid = [fields safeObjectAtIndex:0]; … … 305 616 return; 306 617 307 // --- enter the accumulated users308 618 [_shownUsers addObjectsFromArray:_allUsers]; 309 619 [_allUsers removeAllObjects]; … … 337 647 return; 338 648 339 // --- allocate a new user and fill out the fields340 649 user = [[WCUser alloc] init]; 341 650 [user setUserID:[uid intValue]]; … … 349 658 [user setJoinDate:[NSDate date]]; 350 659 351 // --- decode data352 660 data = [NSData dataWithBase64EncodedString:icon]; 353 661 image = [[NSImage alloc] initWithData:data]; … … 355 663 [image release]; 356 664 357 // --- add it to our dictionary of users358 665 [_shownUsers addObject:user]; 359 666 [_users setObject:user forKey:[NSNumber numberWithUnsignedInt:[user userID]]]; 360 667 361 // --- post chat about it362 668 if([[WCSettings eventForTag:WCEventsUserJoined] boolForKey:WCEventsPostInChat]) 363 [self printUserJoin:user]; 364 365 // --- reload 669 [self _printUserJoin:user]; 670 366 671 [[self connection] postNotificationName:WCChatUsersDidChange object:[self connection]]; 367 672 [_userListTableView reloadData]; 368 673 369 // --- trigger event370 674 [[self connection] postNotificationName:WCConnectionTriggeredEvent 371 675 object:[NSNumber numberWithInt:WCEventsUserJoined]]; … … 379 683 WCUser *user; 380 684 381 // --- get the fields382 685 fields = [[notification userInfo] objectForKey:WCArgumentsKey]; 383 686 cid = [fields safeObjectAtIndex:0]; … … 387 690 return; 388 691 389 // --- get user390 692 user = [self userWithUserID:[uid unsignedIntValue]]; 391 693 392 // --- post chat about it393 694 if([[WCSettings eventForTag:WCEventsUserLeft] boolForKey:WCEventsPostInChat]) 394 [self printUserLeave:user]; 395 396 // --- remove from lists 695 [self _printUserLeave:user]; 696 397 697 [_shownUsers removeObject:user]; 398 698 [_users removeObjectForKey:[NSNumber numberWithUnsignedInt:[user userID]]]; 399 699 400 // --- reload401 700 [[self connection] postNotificationName:WCChatUsersDidChange object:[self connection]]; 402 701 [_userListTableView reloadData]; 403 702 404 // --- trigger event405 703 [[self connection] postNotificationName:WCConnectionTriggeredEvent 406 704 object:[NSNumber numberWithInt:WCEventsUserLeft]]; … … 426 724 return; 427 725 428 // --- post chat about nick changes429 726 if(![nick isEqualToString:[user nick]]) { 430 727 if([[WCSettings eventForTag:WCEventsUserChangedNick] boolForKey:WCEventsPostInChat]) 431 [self printUserChange:user nick:nick]; 432 } 433 434 // --- update user 728 [self _printUserChange:user nick:nick]; 729 } 730 435 731 [user setIdle:[idle intValue]]; 436 732 [user setAdmin:[admin intValue]]; … … 459 755 return; 460 756 461 // --- decode image data462 757 data = [NSData dataWithBase64EncodedString:icon]; 463 758 image = [[NSImage alloc] initWithData:data]; … … 465 760 [image release]; 466 761 467 // --- reload the table468 762 [_userListTableView setNeedsDisplay:YES]; 469 763 } … … 487 781 return; 488 782 489 // --- post chat about it 490 [self printUserKick:victim by:killer message:message]; 491 492 // --- remove from lists 783 [self _printUserKick:victim by:killer message:message]; 784 493 785 [_shownUsers removeObject:victim]; 494 786 [_users removeObjectForKey:[NSNumber numberWithInt:[victim userID]]]; … … 505 797 WCUser *victim, *killer; 506 798 507 // --- get the fields508 799 fields = [[notification userInfo] objectForKey:WCArgumentsKey]; 509 800 uid1 = [fields safeObjectAtIndex:0]; … … 517 808 return; 518 809 519 // --- post chat about it 520 [self printUserBan:victim by:killer message:message]; 521 522 // --- remove from lists 810 [self _printUserBan:victim by:killer message:message]; 811 523 812 [_shownUsers removeObject:victim]; 524 813 [_users removeObjectForKey:[NSNumber numberWithInt:[victim userID]]]; 525 814 526 // --- reload527 815 [[self connection] postNotificationName:WCChatUsersDidChange object:[self connection]]; 528 816 [_userListTableView reloadData]; … … 549 837 return; 550 838 551 // --- insert a timestamp552 839 if([WCSettings boolForKey:WCTimestampChat]) 553 [self printTimestamp]; 554 555 // --- print chat 556 [self printChat:chat by:user]; 557 558 // --- trigger event 840 [self _printTimestamp]; 841 842 [self _printChat:chat by:user]; 843 559 844 [[self connection] postNotificationName:WCConnectionTriggeredEvent 560 845 object:[NSNumber numberWithInt:WCEventsChatReceived]]; … … 576 861 return; 577 862 578 // --- get user579 863 user = [self userWithUserID:[uid intValue]]; 580 864 581 // --- check ignore582 865 if(!user || [user isIgnored]) 583 866 return; 584 867 585 // --- insert a timestamp586 868 if([WCSettings boolForKey:WCTimestampChat]) 587 [self printTimestamp]; 588 589 // --- print chat 590 [self printActionChat:chat by:user]; 591 592 // --- trigger event 869 [self _printTimestamp]; 870 871 [self _printActionChat:chat by:user]; 872 593 873 [[self connection] postNotificationName:WCConnectionTriggeredEvent 594 874 object:[NSNumber numberWithInt:WCEventsChatReceived]]; … … 615 895 return; 616 896 617 // --- create new topic618 897 [_topic release]; 619 898 _topic = [[WCTopic alloc] init]; … … 624 903 [_topic setTopic:message]; 625 904 626 [self updateTopic];905 [self _updateTopic]; 627 906 } 628 907 … … 644 923 NSSize size, rightSize, leftSize; 645 924 646 // --- get split view size647 925 size = [_userListSplitView frame].size; 648 649 // --- get static right part size650 926 rightSize = [_userListView frame].size; 651 927 rightSize.height = size.height; 652 653 // --- set dynamic left part size654 928 leftSize.height = size.height; 655 929 leftSize.width = size.width - [_userListSplitView dividerThickness] - rightSize.width; 656 930 657 // --- set new frames658 931 [_chatView setFrameSize:leftSize]; 659 932 [_userListView setFrameSize:rightSize]; … … 662 935 NSSize size, bottomSize, topSize; 663 936 664 // --- get split view size665 937 size = [_chatSplitView frame].size; 666 667 // --- get static bottom part size668 938 bottomSize = [_chatInputScrollView frame].size; 669 939 bottomSize.width = size.width; 670 671 // --- set dynamic top part size672 940 topSize.width = size.width; 673 941 topSize.height = size.height - [_chatSplitView dividerThickness] - bottomSize.height; 674 942 675 // --- set new frames676 943 [_chatOutputScrollView setFrameSize:topSize]; 677 944 [_chatInputScrollView setFrameSize:bottomSize]; … … 696 963 } 697 964 698 // --- close sheet699 965 [_setTopicPanel close]; 700 966 [_setTopicTextView setString:@""]; … … 704 970 705 971 - (BOOL)topicTextView:(NSTextView *)textView doCommandBySelector:(SEL)selector { 706 // --- submit on enter707 972 if(selector == @selector(insertNewline:)) { 708 973 if([[NSApp currentEvent] character] == NSEnterCharacter) { … … 722 987 BOOL commandKey, optionKey, controlKey, historyScrollback; 723 988 724 // --- get key state725 989 commandKey = (([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) != 0); 726 990 optionKey = (([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0); 727 991 controlKey = (([[NSApp currentEvent] modifierFlags] & NSControlKeyMask) != 0); 728 992 729 // --- get history settings730 993 historyScrollback = [WCSettings boolForKey:WCHistoryScrollback]; 731 994 historyModifier = [WCSettings intForKey:WCHistoryScrollbackModifier]; … … 744 1007 return YES; 745 1008 746 // --- enforce length limit747 1009 if(length > WCChatLimit) 748 1010 string = [string substringToIndex:WCChatLimit]; 749 1011 750 // --- add it to the command history751 1012 [_commandHistory addObject:[[string copy] autorelease]]; 752 1013 _currentCommand = [_commandHistory count]; 753 1014 754 // --- attempt a command parse755 1015 if([string hasPrefix:@"/"]) { 756 if([self runCommand:string])1016 if([self _runCommand:string]) 757 1017 post = NO; 758 1018 } 759 1019 760 1020 if(post) { 761 // --- get command762 1021 if(selector == @selector(insertNewlineIgnoringFieldEditor:) || 763 1022 (selector == @selector(insertNewline:) && optionKey)) … … 766 1025 command = WCSayCommand; 767 1026 768 // --- send chat769 1027 [[self connection] sendCommand:command 770 1028 withArgument:[NSSWF:@"%u", [self chatID]] 771 1029 withArgument:string]; 772 1030 773 // --- save in stats774 1031 [WCStats addUnsignedLongLong:[string UTF8StringLength] forKey:WCStatsChat]; 775 1032 } … … 786 1043 int i, count, options; 787 1044 788 // --- get matching nicks789 1045 options = NSCaseInsensitiveSearch; 790 1046 nicks = [[self nicks] stringsMatchingString:[_chatInputTextView string] … … 808 1064 } 809 1065 810 // --- enter our partial match811 1066 if([p length] > 0) 812 1067 [_chatInputTextView setString:prefix]; … … 836 1091 controlKey))) { 837 1092 if(_currentCommand > 0) { 838 // --- save current string839 1093 if(_currentCommand == [_commandHistory count]) { 840 1094 [_currentString release]; … … 843 1097 } 844 1098 845 // --- move up in the command history846 1099 [_chatInputTextView setString:[_commandHistory objectAtIndex:--_currentCommand]]; 847 1100 … … 863 1116 controlKey))) { 864 1117 if(_currentCommand + 1 < [_commandHistory count]) { 865 // --- move down in the command history866 1118 [_chatInputTextView setString:[_commandHistory objectAtIndex:++_currentCommand]]; 867 1119 … … 869 1121 } 870 1122 else if(_currentCommand + 1 == [_commandHistory count]) { 871 // --- reset original string872 1123 _currentCommand++; 873 1124 [_chatInputTextView setString:_currentString]; … … 913 1164 914 1165 #pragma mark - 915 916 - (void)update {917 NSFont *font;918 NSColor *color;919 BOOL parse = NO;920 921 // --- set font922 font = [WCSettings objectForKey:WCChatFont];923 924 if(![[_chatOutputTextView font] isEqualTo:font]) {925 [_chatOutputTextView setFont:font];926 [_chatInputTextView setFont:font];927 [_setTopicTextView setFont:font];928 }929 930 // --- set background color931 color = [WCSettings objectForKey:WCChatBackgroundColor];932 933 if(![[_chatOutputTextView backgroundColor] isEqualTo:color]) {934 [_chatOutputTextView setBackgroundColor:color];935 [_chatInputTextView setBackgroundColor:color];936 [_setTopicTextView setBackgroundColor:color];937 }938 939 // --- set text color940 color = [WCSettings objectForKey:WCChatTextColor];941 942 if(![[_chatOutputTextView textColor] isEqualTo:color]) {943 [_chatOutputTextView setTextColor:color];944 [_chatInputTextView setTextColor:color];945 [_chatInputTextView setInsertionPointColor:color];946 [_setTopicTextView setTextColor:color];947 [_setTopicTextView setInsertionPointColor:color];948 949 parse = YES;950 }951 952 // --- parse text953 if(parse)954 [_chatOutputTextView setString:[_chatOutputTextView string] withFilter:_chatFilter];955 956 // --- set up user list957 [_userListTableView setFont:[WCSettings objectForKey:WCChatUserListFont]];958 [_userListTableView setDrawsStripes:[WCSettings boolForKey:WCChatUserListAlternateRows]];959 960 // --- mark them as updated961 [_chatOutputTextView setNeedsDisplay:YES];962 [_chatInputTextView setNeedsDisplay:YES];963 [_setTopicTextView setNeedsDisplay:YES];964 [_userListTableView setNeedsDisplay:YES];965 }966 967 968 969 - (void)updateTopic {970 [_topicTextField setToolTip:[_topic topic]];971 [_topicTextField setStringValue:[_topic topic]];972 [_topicNickTextField setStringValue:[NSSWF:973 NSLS(@"%@ %C %@", @"Chat topic set by (nick, time)"),974 [_topic nick],975 0x2014,976 [[_topic date] commonDateStringWithSeconds:NO relative:YES capitalized:YES]]];977 }978 979 980 1166 981 1167 - (void)validate { … … 1078 1264 #pragma mark - 1079 1265 1080 - (void)printString:(NSString *)string {1081 float position;1082 1083 // --- append string1084 position = [[_chatOutputScrollView verticalScroller] floatValue];1085 1086 if([[_chatOutputTextView textStorage] length] > 0)1087 [[[_chatOutputTextView textStorage] mutableString] appendString:@"\n"];1088 1089 [_chatOutputTextView appendString:string withFilter:_chatFilter];1090 1091 // --- scroll1092 if(position == 1.0)1093 [_chatOutputTextView performSelectorOnce:@selector(scrollToBottom) withObject:NULL afterDelay:0.05];1094 }1095 1096 1097 1098 1266 - (void)printEvent:(NSString *)message { 1099 1267 NSString *output; 1100 1268 1101 // --- build the output string1102 1269 output = [NSSWF:NSLS(@"<<< %@ >>>", @"Chat event (message)"), message]; 1103 1270 1104 // --- add tim
