Changeset 3589

Show
Ignore:
Timestamp:
02/25/07 18:04:50 (2 years ago)
Author:
timothy
Message:

Adds transient attributes for JVChatMessages, good for plugins to store objects in while handeling a message. Patch by hennk. #1015

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Additions/NSImageAdditions.m

    r3418 r3589  
    8686                        imageRep = object; 
    8787 
    88         if ( ! imageRep ) { 
     88        if( ! imageRep ) { 
    8989                imageRep = [NSBitmapImageRep imageRepWithData:[self TIFFRepresentation]]; 
    9090                if( imageRep ) [self addRepresentation:imageRep]; 
  • trunk/Chat Core/MVChatConnection.h

    r3584 r3589  
    407407 
    408408@interface NSObject (MVChatPluginConnectionSupport) 
    409 - (void) processIncomingMessageAsData:(NSMutableData *) message from:(MVChatUser *) sender to:(id) receiver isNotice:(BOOL) notice
    410 - (void) processOutgoingMessageAsData:(NSMutableData *) message to:(id) receiver
     409- (void) processIncomingMessageAsData:(NSMutableData *) message from:(MVChatUser *) sender to:(id) receiver attributes:(NSMutableDictionary *)msgAttributes
     410- (void) processOutgoingMessageAsData:(NSMutableData *) message to:(id) receiver attributes:(NSDictionary *)msgAttributes
    411411 
    412412- (BOOL) processSubcodeRequest:(NSString *) command withArguments:(NSData *) arguments fromUser:(MVChatUser *) user; 
  • trunk/Chat Core/MVChatRoom.h

    r3526 r3589  
    147147- (void) sendMessage:(NSAttributedString *) message asAction:(BOOL) action; 
    148148- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action; 
     149- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes; 
    149150 
    150151- (void) sendSubcodeRequest:(NSString *) command withArguments:(id) arguments; 
  • trunk/Chat Core/MVChatRoom.m

    r3539 r3589  
    229229 
    230230- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action { 
    231 // subclass this method, don't call super 
     231   [self sendMessage:message withEncoding:encoding withAttributes:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:action] forKey:@"action"]]; 
     232
     233 
     234- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes { 
     235   // subclass this method, don't call super 
    232236        [self doesNotRecognizeSelector:_cmd]; 
    233237} 
  • trunk/Chat Core/MVChatUser.h

    r3526 r3589  
    181181 
    182182- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action; 
     183- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes; 
    183184- (MVUploadFileTransfer *) sendFile:(NSString *) path passively:(BOOL) passive; 
    184185 
  • trunk/Chat Core/MVChatUser.m

    r3530 r3589  
    422422 
    423423- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action { 
    424 // subclass this method, don't call super 
     424   [self sendMessage:message withEncoding:encoding withAttributes:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:action] forKey:@"action"]]; 
     425
     426 
     427- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes { 
     428   // subclass this method, don't call super 
    425429        [self doesNotRecognizeSelector:_cmd]; 
    426430} 
  • trunk/Chat Core/MVDirectChatConnection.h

    r3545 r3589  
    5858 
    5959- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action; 
     60- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *)attributes; 
    6061@end 
  • trunk/Chat Core/MVDirectChatConnection.m

    r3545 r3589  
    160160 
    161161- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action { 
     162        [self sendMessage:message withEncoding:encoding withAttributes:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:action] forKey:@"action"]]; 
     163} 
     164 
     165- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *)attributes { 
    162166        NSParameterAssert( message != nil ); 
    163167 
     
    183187        NSData *msg = [message chatFormatWithOptions:options]; 
    184188 
    185         if( action ) { 
     189        if( [[attributes objectForKey:@"action"] boolValue] ) { 
    186190                NSMutableData *newMsg = [[NSMutableData allocWithZone:nil] initWithCapacity:[msg length] + 11]; 
    187191                [newMsg appendBytes:"\001ACTION " length:8]; 
  • trunk/Chat Core/MVICBChatRoom.h

    r3582 r3589  
    4646- (void) setTopic:(NSAttributedString *) newTopic; 
    4747- (void) sendMessage:(NSAttributedString *) message 
    48          withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action
     48         withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes
    4949@end 
  • trunk/Chat Core/MVICBChatRoom.m

    r3582 r3589  
    6161 
    6262- (void) sendMessage:(NSAttributedString *) message 
    63          withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action
     63         withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes
    6464        if( [_memberUsers count] > 1 ) 
    6565                [(MVICBChatConnection *)_connection ctsOpenPacket:[message string]]; 
  • trunk/Chat Core/MVICBChatUser.m

    r3584 r3589  
    7070- (void) sendMessage:(NSAttributedString *) message 
    7171         withEncoding:(NSStringEncoding) encoding 
    72                  asAction:(BOOL) action
     72                 withAttributes:(NSDictionary *) attributes
    7373        [(MVICBChatConnection *)_connection ctsCommandPersonal:_nickname withMessage:[message string]]; 
    7474} 
  • trunk/Chat Core/MVIRCChatConnection.h

    r3584 r3589  
    4646         
    4747+ (NSData *) _flattenedIRCDataForMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) enc andChatFormat:(MVChatMessageFormat) format; 
    48 - (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(id) target asAction:(BOOL) action
     48- (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(id) target withAttributes:(NSDictionary *) attributes
    4949 
    5050- (void) _processErrorCode:(int) errorCode withContext:(char *) context; 
  • trunk/Chat Core/MVIRCChatConnection.m

    r3584 r3589  
    931931} 
    932932 
    933 - (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(id) target asAction:(BOOL) action
     933- (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(id) target withAttributes:(NSDictionary *) attributes
    934934        NSParameterAssert( [target isKindOfClass:[MVChatUser class]] || [target isKindOfClass:[MVChatRoom class]] ); 
    935935 
    936936        NSMutableData *msg = [[[self class] _flattenedIRCDataForMessage:message withEncoding:msgEncoding andChatFormat:[self outgoingChatFormat]] mutableCopyWithZone:nil]; 
    937937 
    938         NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( id ), nil]; 
     938        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( id ), @encode( NSDictionary * ), nil]; 
    939939        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
    940         [invocation setSelector:@selector( processOutgoingMessageAsData:to: )]; 
     940        [invocation setSelector:@selector( processOutgoingMessageAsData:to:attributes: )]; 
    941941        [invocation setArgument:&msg atIndex:2]; 
    942942        [invocation setArgument:&target atIndex:3]; 
     943        [invocation setArgument:&attributes atIndex:4]; 
    943944 
    944945        [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     
    950951        NSString *targetName = [target isKindOfClass:[MVChatRoom class]] ? [target name] : [target nickname]; 
    951952 
    952         if( action ) { 
     953        if( [[attributes objectForKey:@"action"] boolValue] ) { 
    953954                NSString *prefix = [[NSString allocWithZone:nil] initWithFormat:@"PRIVMSG %@ :\001ACTION ", targetName]; 
    954955                [self sendRawMessageWithComponents:prefix, msg, @"\001", nil]; 
     
    14631464        MVChatUser *sender = [privmsgInfo objectForKey:@"user"]; 
    14641465        NSMutableData *message = [privmsgInfo objectForKey:@"message"]; 
    1465         BOOL isNotice = NO; 
    1466  
    1467         NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( BOOL ), nil]; 
     1466        NSMutableDictionary *msgAttributes = [privmsgInfo mutableCopyWithZone:nil]; 
     1467        [msgAttributes setObject:[NSNumber numberWithBool:NO] forKey:@"notice"]; 
     1468 
     1469        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( NSMutableDictionary * ), nil]; 
    14681470        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
    1469         [invocation setSelector:@selector( processIncomingMessageAsData:from:to:isNotice: )]; 
     1471        [invocation setSelector:@selector( processIncomingMessageAsData:from:to:attributes: )]; 
    14701472        [invocation setArgument:&message atIndex:2]; 
    14711473        [invocation setArgument:&sender atIndex:3]; 
    14721474        [invocation setArgument:&room atIndex:4]; 
    1473         [invocation setArgument:&isNotice atIndex:5]; 
     1475        [invocation setArgument:&msgAttributes atIndex:5]; 
    14741476 
    14751477        [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     
    14771479 
    14781480        if( room ) { 
    1479                 [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:privmsgInfo]; 
     1481                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:msgAttributes]; 
    14801482        } else { 
    1481                 [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:privmsgInfo]; 
     1483                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:msgAttributes]; 
    14821484        } 
    14831485} 
     
    15311533        MVChatUser *sender = [noticeInfo objectForKey:@"user"]; 
    15321534        NSMutableData *message = [noticeInfo objectForKey:@"message"]; 
    1533         BOOL isNotice = YES; 
    1534  
    1535         NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( BOOL ), nil]; 
     1535        NSMutableDictionary *msgAttributes = [noticeInfo mutableCopyWithZone:nil]; 
     1536        [msgAttributes setObject:[NSNumber numberWithBool:YES] forKey:@"notice"]; 
     1537 
     1538        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( void ), @encode( NSMutableData * ), @encode( MVChatUser * ), @encode( id ), @encode( NSMutableDictionary * ), nil]; 
    15361539        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
    1537         [invocation setSelector:@selector( processIncomingMessageAsData:from:to:isNotice: )]; 
     1540        [invocation setSelector:@selector( processIncomingMessageAsData:from:to:attributes: )]; 
    15381541        [invocation setArgument:&message atIndex:2]; 
    15391542        [invocation setArgument:&sender atIndex:3]; 
    15401543        [invocation setArgument:&room atIndex:4]; 
    1541         [invocation setArgument:&isNotice atIndex:5]; 
     1544        [invocation setArgument:&msgAttributes atIndex:5]; 
    15421545 
    15431546        [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     
    15451548 
    15461549        if( room ) { 
    1547                 [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:noticeInfo]; 
     1550                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatRoomGotMessageNotification object:room userInfo:msgAttributes]; 
    15481551        } else { 
    1549                 [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:noticeInfo]; 
     1552                [[NSNotificationCenter defaultCenter] postNotificationName:MVChatConnectionGotPrivateMessageNotification object:sender userInfo:msgAttributes]; 
    15501553 
    15511554                if( [[sender nickname] isEqualToString:@"NickServ"] ) { 
  • trunk/Chat Core/MVIRCChatRoom.m

    r3584 r3589  
    5454#pragma mark - 
    5555 
    56 - (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding asAction:(BOOL) action
     56- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding withAttributes:(NSDictionary *) attributes
    5757        NSParameterAssert( message != nil ); 
    58         [[self connection] _sendMessage:message withEncoding:msgEncoding toTarget:self asAction:action]; 
     58        [[self connection] _sendMessage:message withEncoding:msgEncoding toTarget:self withAttributes:attributes]; 
    5959} 
    6060 
  • trunk/Chat Core/MVIRCChatUser.m

    r3584 r3589  
    4242#pragma mark - 
    4343 
    44 - (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action
     44- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes
    4545        NSParameterAssert( message != nil ); 
    46         [[self connection] _sendMessage:message withEncoding:encoding toTarget:self asAction:action]; 
     46        [[self connection] _sendMessage:message withEncoding:encoding toTarget:self withAttributes:attributes]; 
    4747} 
    4848 
  • trunk/Chat Core/MVSILCChatRoom.m

    r3420 r3589  
    6666#pragma mark - 
    6767 
    68 - (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action
     68- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes
    6969        NSParameterAssert( message != nil ); 
    7070 
     
    7272        SilcMessageFlags flags = SILC_MESSAGE_FLAG_UTF8; 
    7373 
    74         if( action ) flags |= SILC_MESSAGE_FLAG_ACTION; 
     74        if( [[attributes objectForKey:@"action"] boolValue] ) flags |= SILC_MESSAGE_FLAG_ACTION; 
    7575 
    7676        SilcLock( [[self connection] _silcClient] ); 
  • trunk/Chat Core/MVSILCChatUser.m

    r3512 r3589  
    105105#pragma mark - 
    106106 
    107 - (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action
     107- (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding withAttributes:(NSDictionary *) attributes
    108108        NSParameterAssert( message != nil ); 
    109109 
     
    111111        SilcMessageFlags flags = SILC_MESSAGE_FLAG_UTF8; 
    112112 
    113         if( action) flags |= SILC_MESSAGE_FLAG_ACTION; 
     113        if( [[attributes objectForKey:@"action"] boolValue]) flags |= SILC_MESSAGE_FLAG_ACTION; 
    114114 
    115115        // unpack the identifier here for now 
  • trunk/Controllers/JVChatController.m

    r3582 r3589  
    564564        if( ( [self shouldIgnoreUser:user withMessage:nil inView:nil] == JVNotIgnored ) ) { 
    565565                JVDirectChatPanel *controller = [self chatViewControllerForDirectChatConnection:connection ifExists:NO userInitiated:NO]; 
    566                 [controller addMessageToDisplay:message fromUser:user asAction:[[[notification userInfo] objectForKey:@"action"] boolValue] withIdentifier:[[notification userInfo] objectForKey:@"identifier"] andType:JVChatMessageNormalType]; 
     566                [controller addMessageToDisplay:message fromUser:user withAttributes:[notification userInfo] withIdentifier:[[notification userInfo] objectForKey:@"identifier"] andType:JVChatMessageNormalType]; 
    567567        } 
    568568} 
     
    632632                JVDirectChatPanel *controller = [self chatViewControllerForUser:user ifExists:NO userInitiated:NO]; 
    633633                JVChatMessageType type = ( [[[notification userInfo] objectForKey:@"notice"] boolValue] ? JVChatMessageNoticeType : JVChatMessageNormalType ); 
    634                 [controller addMessageToDisplay:message fromUser:user asAction:[[[notification userInfo] objectForKey:@"action"] boolValue] withIdentifier:[[notification userInfo] objectForKey:@"identifier"] andType:type]; 
     634                [controller addMessageToDisplay:message fromUser:user withAttributes:[notification userInfo] withIdentifier:[[notification userInfo] objectForKey:@"identifier"] andType:type]; 
    635635        } 
    636636} 
  • trunk/Models/JVChatMessage.h

    r3247 r3589  
    3434        BOOL _bodyLoaded; 
    3535        BOOL _senderLoaded; 
     36        NSMutableDictionary *_attributes; 
    3637} 
    3738- (/* xmlNode */ void *) node; 
     
    6465- (NSScriptObjectSpecifier *) objectSpecifier; 
    6566- (void) setObjectSpecifier:(NSScriptObjectSpecifier *) objectSpecifier; 
     67 
     68- (NSDictionary *) attributes; 
     69- (id) attributeForKey:(id) key; 
    6670@end 
    6771 
     
    8993- (void) setSource:(NSURL *) source; 
    9094- (void) setMessageIdentifier:(NSString *) identifier; 
     95 
     96- (NSMutableDictionary *) attributes; 
     97- (void) setAttributes:(NSDictionary *) attributes; 
     98- (void) setAttribute:(id) object forKey:(id) key; 
    9199@end 
  • trunk/Models/JVChatMessage.m

    r3450 r3589  
    9797                ret -> _ignoreStatus = [self ignoreStatus]; 
    9898                ret -> _type = [self type]; 
     99                ret -> _attributes = [[self attributes] copyWithZone:zone]; 
    99100        } 
    100101 
     
    108109        [_source release]; 
    109110        [_objectSpecifier release]; 
     111        [_attributes release]; 
    110112 
    111113        [_senderIdentifier release]; 
     
    329331#pragma mark - 
    330332 
     333- (NSDictionary *) attributes { 
     334        // Add important attributes which are set via normal setters, and therefore don't exist normally in the attributes-dict. 
     335        if( ! _attributes ) 
     336                _attributes = [[NSMutableDictionary alloc] init]; 
     337        [_attributes setObject:[NSNumber numberWithBool:_action] forKey:@"action"]; 
     338 
     339        return _attributes; 
     340} 
     341 
     342- (id) attributeForKey:(id) key { 
     343        return [_attributes objectForKey:key]; 
     344} 
     345 
     346#pragma mark - 
     347 
    331348- (NSString *) description { 
    332349        return [self bodyAsPlainText]; 
     
    557574} 
    558575 
     576- (NSMutableDictionary *) attributes { 
     577        // This depends on the implementation of JVChatMessage using an NSMutableDictionary for its attributes, and actually returning a mutable version of it. 
     578        return (NSMutableDictionary *)[super attributes]; 
     579} 
     580 
     581- (void) setAttributes:(NSDictionary *) attributes { 
     582        [self _setNode:NULL]; 
     583        id old = _attributes; 
     584        _attributes = [attributes mutableCopyWithZone:[self zone]]; 
     585        [old release]; 
     586} 
     587 
     588- (void) setAttribute:(id) object forKey:(id) key { 
     589        if( ! _attributes ) 
     590                _attributes = [[NSMutableDictionary alloc] init]; 
     591        [_attributes setObject:object forKey:key]; 
     592} 
     593 
    559594#pragma mark - 
    560595 
  • trunk/Panels/JVChatRoomPanel.m

    r3579 r3589  
    319319- (void) handleRoomMessageNotification:(NSNotification *) notification { 
    320320        JVChatMessageType type = ( [[[notification userInfo] objectForKey:@"notice"] boolValue] ? JVChatMessageNoticeType : JVChatMessageNormalType ); 
    321         [self addMessageToDisplay:[[notification userInfo] objectForKey:@"message"] fromUser:[[notification userInfo] objectForKey:@"user"] asAction:[[[notification userInfo] objectForKey:@"action"] boolValue] withIdentifier:[[notification userInfo] objectForKey:@"identifier"] andType:type]; 
     321        [self addMessageToDisplay:[[notification userInfo] objectForKey:@"message"] fromUser:[[notification userInfo] objectForKey:@"user"] withAttributes:[notification userInfo] withIdentifier:[[notification userInfo] objectForKey:@"identifier"] andType:type]; 
    322322} 
    323323 
  • trunk/Panels/JVDirectChatPanel.h

    r3570 r3589  
    5959- (void) addEventMessageToDisplay:(NSString *) message withName:(NSString *) name andAttributes:(NSDictionary *) attributes; 
    6060- (void) addMessageToDisplay:(NSData *) message fromUser:(MVChatUser *) user asAction:(BOOL) action withIdentifier:(NSString *) identifier andType:(JVChatMessageType) type; 
     61- (void) addMessageToDisplay:(NSData *) message fromUser:(MVChatUser *) user withAttributes:(NSDictionary *) msgAttributes withIdentifier:(NSString *) identifier andType:(JVChatMessageType) type; 
    6162- (void) processIncomingMessage:(JVMutableChatMessage *) message; 
    6263- (void) echoSentMessageToDisplay:(JVMutableChatMessage *) message; 
  • trunk/Panels/JVDirectChatPanel.m

    r3570 r3589  
    741741} 
    742742 
    743 - (void) addMessageToDisplay:(NSData *) message fromUser:(MVChatUser *) user asAction:(BOOL) action withIdentifier:(NSString *) identifier andType:(JVChatMessageType) type { 
     743- (void) addMessageToDisplay:(NSData *) message fromUser:(MVChatUser *) user asAction:(BOOL) action withIdentifier:(NSString *) identifier andType:(JVChatMessageType) type; 
     744
     745        [self addMessageToDisplay:message fromUser:user withAttributes:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:action] forKey:@"action"] withIdentifier:identifier andType:type]; 
     746
     747 
     748- (void) addMessageToDisplay:(NSData *) message fromUser:(MVChatUser *) user withAttributes:(NSDictionary *) msgAttributes withIdentifier:(NSString *) identifier andType:(JVChatMessageType) type { 
    744749        if( ! _nibLoaded ) [self view]; 
    745750 
     
    770775        JVMutableChatMessage *cmessage = [[JVMutableChatMessage alloc] initWithText:messageString sender:user]; 
    771776        [cmessage setMessageIdentifier:identifier]; 
    772         [cmessage setAction:action]; 
     777        [cmessage setAttributes:msgAttributes]; 
     778        [cmessage setAction:[[msgAttributes objectForKey:@"action"] boolValue]]; 
    773779        [cmessage setType:type]; 
    774780 
     
    948954        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:[self encoding]], @"StringEncoding", cformat, @"FormatType", nil]; 
    949955        NSData *msgData = [[message body] chatFormatWithOptions:options]; // we could save this back to the message object before sending 
    950         [self addMessageToDisplay:msgData fromUser:[message sender] asAction:[message isAction] withIdentifier:[message messageIdentifier] andType:[message type]]; 
     956        [self addMessageToDisplay:msgData fromUser:[message sender] withAttributes:[message attributes] withIdentifier:[message messageIdentifier] andType:[message type]]; 
    951957} 
    952958 
     
    10891095 
    10901096        if( [[message body] length] ) 
    1091                 [[self target] sendMessage:[message body] withEncoding:_encoding asAction:[message isAction]]; 
     1097                [[self target] sendMessage:[message body] withEncoding:_encoding withAttributes:[message attributes]]; 
    10921098} 
    10931099 
     
    11491155        } else if( ( [event modifierFlags] & NSAlternateKeyMask ) != 0 ) { 
    11501156                ret = NO; 
    1151         } else if ( ([event modifierFlags] & NSControlKeyMask) != 0 ) { 
     1157        } else if( ([event modifierFlags] & NSControlKeyMask) != 0 ) { 
    11521158                [self send:[NSNumber numberWithBool:YES]]; 
    11531159                ret = YES;