Changeset 2161
- Timestamp:
- 12/28/04 13:06:07 (4 years ago)
- Files:
-
- branches/overhaul/JVChatTranscript.m (modified) (4 diffs)
- branches/overhaul/JVDirectChat.m (modified) (21 diffs)
- branches/overhaul/MVIRCChatConnection.m (modified) (3 diffs)
- branches/overhaul/MVIRCFileTransfer.m (modified) (11 diffs)
- branches/overhaul/Plug-Ins/Standard Commands/JVStandardCommands.m (modified) (2 diffs)
- branches/overhaul/Resources/Changes.rtf (modified) (9 diffs)
- branches/overhaul/Resources/Info.plist (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/overhaul/JVChatTranscript.m
r2132 r2161 676 676 677 677 // Allows some simple code to work when not built with WebKit/Safari 1.3 678 #ifndef _WEB_SCRIPT_OBJECT_H_678 #ifndef WebKitVersion146 679 679 #define WebMenuItemTagGoBack 9 680 680 #define WebMenuItemTagGoForward 10 … … 810 810 - (void) webView:(WebView *) sender didFinishLoadForFrame:(WebFrame *) frame { 811 811 // Test for WebKit/Safari 1.3 812 #ifdef _WEB_SCRIPT_OBJECT_H_812 #ifdef WebKitVersion146 813 813 if( [display respondsToSelector:@selector( setDrawsBackground: )] ) { 814 814 DOMCSSStyleDeclaration *style = [sender computedStyleForElement:[(DOMHTMLDocument *)[[sender mainFrame] DOMDocument] body] pseudoElement:nil]; … … 954 954 955 955 - (void) _prependMessages:(NSString *) messages { 956 #ifdef WebKitVersion146 956 957 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 957 #ifdef _WEB_SCRIPT_OBJECT_H_958 958 NSMutableString *result = [messages mutableCopy]; 959 959 [result replaceOccurrencesOfString:@" " withString:@" " options:NSLiteralSearch range:NSMakeRange( 0, [result length] )]; … … 979 979 // scroll down if we need to 980 980 if( [scrollNeeded boolValue] ) [body setValue:[body valueForKey:@"offsetHeight"] forKey:@"scrollTop"]; 981 } else 981 982 #endif 982 } else {983 { // old JavaScript method 983 984 NSMutableString *result = [messages mutableCopy]; 984 985 [result escapeCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\\\"'"]]; branches/overhaul/JVDirectChat.m
r2141 r2161 102 102 - (void) addEventMessageToLogAndDisplay:(NSString *) message withName:(NSString *) name andAttributes:(NSDictionary *) attributes entityEncodeAttributes:(BOOL) encode; 103 103 - (void) addMessageToLogAndDisplay:(NSData *) message fromUser:(MVChatUser *) user asAction:(BOOL) action; 104 - (int) visibleMessageCount; 104 105 - (int) locationOfMessage:(unsigned int) identifier; 105 106 - (int) locationOfElementByIndex:(unsigned int) index; … … 119 120 - (void) _saveSelfIcon; 120 121 - (void) _saveBuddyIcon:(JVBuddy *) buddy; 122 - (void) _setCurrentMessage:(JVMutableChatMessage *) message; 121 123 @end 122 124 … … 499 501 500 502 - (void) handleDraggedFile:(NSString *) path { 501 [[self target] sendFile:path passively:NO]; 503 BOOL passive = [[NSUserDefaults standardUserDefaults] boolForKey:@"JVSendFilesPassively"]; 504 [[self target] sendFile:path passively:passive]; 502 505 } 503 506 … … 798 801 [[self connection] sendRawMessage:[command stringByAppendingFormat:@" %@", [arguments string]]]; 799 802 } else { 800 if( [[subMsg string] hasPrefix:@"//"] ) { 801 [subMsg deleteCharactersInRange:NSMakeRange(0,1)]; 802 } 803 if( [[subMsg string] hasPrefix:@"//"] ) [subMsg deleteCharactersInRange:NSMakeRange( 0, 1 )]; 803 804 if( [[NSUserDefaults standardUserDefaults] boolForKey:@"MVChatNaturalActions"] && ! action ) { 804 805 extern NSArray *JVAutoActionVerbs; … … 816 817 } 817 818 818 [_currentMessage autorelease]; // set the message to an object property for plugins, if needed... 819 _currentMessage = [[JVMutableChatMessage alloc] initWithText:subMsg sender:[[self connection] nickname] andTranscript:self]; 820 [_currentMessage setAction:action]; 821 822 id classDescription = [NSClassDescription classDescriptionForClass:[self class]]; 823 id msgSpecifier = [[[NSPropertySpecifier alloc] initWithContainerClassDescription:classDescription containerSpecifier:[self objectSpecifier] key:@"currentMessage"] autorelease]; 824 [_currentMessage setObjectSpecifier:msgSpecifier]; 825 826 [self sendMessage:_currentMessage]; 819 JVMutableChatMessage *cmessage = [[JVMutableChatMessage alloc] initWithText:subMsg sender:[[self connection] nickname] andTranscript:self]; 820 [cmessage setAction:action]; 821 822 [self sendMessage:cmessage]; 827 823 828 824 if( [[subMsg string] length] ) 829 [self echoSentMessageToDisplay:[_currentMessage body] asAction:[_currentMessage isAction]]; 830 831 [_currentMessage release]; 832 _currentMessage = nil; 825 [self echoSentMessageToDisplay:[cmessage body] asAction:[cmessage isAction]]; 826 827 [cmessage release]; 833 828 } 834 829 } … … 849 844 [invocation setArgument:&message atIndex:2]; 850 845 846 [self _setCurrentMessage:message]; 851 847 [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation stoppingOnFirstSuccessfulReturn:NO]; 848 [self _setCurrentMessage:nil]; 852 849 853 850 if( [[message body] length] ) … … 1296 1293 } 1297 1294 1298 [_currentMessage autorelease]; // set the message to an object property for plugins, if needed... 1299 _currentMessage = [[JVMutableChatMessage alloc] initWithText:messageString sender:[user nickname] andTranscript:self]; 1300 [_currentMessage setAction:action]; 1301 1302 id classDescription = [NSClassDescription classDescriptionForClass:[self class]]; 1303 id msgSpecifier = [[[NSPropertySpecifier alloc] initWithContainerClassDescription:classDescription containerSpecifier:[self objectSpecifier] key:@"currentMessage"] autorelease]; 1304 [_currentMessage setObjectSpecifier:msgSpecifier]; 1295 JVMutableChatMessage *cmessage = [[JVMutableChatMessage alloc] initWithText:messageString sender:user andTranscript:self]; 1296 [cmessage setAction:action]; 1297 1298 [self _setCurrentMessage:cmessage]; 1305 1299 1306 1300 if( ! [user isLocalUser] ) 1307 [ _currentMessage setIgnoreStatus:[[JVChatController defaultManager] shouldIgnoreUser:user withMessage:messageString inView:self]];1308 1309 if( ! [user isLocalUser] && [ _currentMessage ignoreStatus] == JVNotIgnored )1301 [cmessage setIgnoreStatus:[[JVChatController defaultManager] shouldIgnoreUser:user withMessage:messageString inView:self]]; 1302 1303 if( ! [user isLocalUser] && [cmessage ignoreStatus] == JVNotIgnored ) 1310 1304 _newMessageCount++; 1311 1305 … … 1346 1340 else [classes addObject:@"highlight"]; 1347 1341 [messageString addAttribute:@"CSSClasses" value:classes range:foundRange]; 1348 [ _currentMessage setHighlighted:YES];1342 [cmessage setHighlighted:YES]; 1349 1343 } 1350 1344 } 1351 1345 } 1352 1346 1353 [self processIncomingMessage: _currentMessage];1354 1355 // user = [[ _currentMessage sender] description]; // if plugins changed the sending user for some reason, allow it1356 1357 if( ! [messageString length] && [ _currentMessage ignoreStatus] == JVNotIgnored ) { // plugins decided to excluded this message, decrease the new message counts1347 [self processIncomingMessage:cmessage]; 1348 1349 // user = [[cmessage sender] description]; // if plugins changed the sending user for some reason, allow it 1350 1351 if( ! [messageString length] && [cmessage ignoreStatus] == JVNotIgnored ) { // plugins decided to excluded this message, decrease the new message counts 1358 1352 _newMessageCount--; 1359 1353 return; … … 1362 1356 [self _breakLongLinesInString:messageString]; 1363 1357 1364 if( [ _currentMessage isHighlighted] && [_currentMessage ignoreStatus] == JVNotIgnored ) {1358 if( [cmessage isHighlighted] && [cmessage ignoreStatus] == JVNotIgnored ) { 1365 1359 _newHighlightMessageCount++; 1366 1360 NSMutableDictionary *context = [NSMutableDictionary dictionary]; … … 1374 1368 } 1375 1369 1376 if( [ _currentMessage ignoreStatus] != JVNotIgnored ) {1370 if( [cmessage ignoreStatus] != JVNotIgnored ) { 1377 1371 NSMutableDictionary *context = [NSMutableDictionary dictionary]; 1378 [context setObject:( ( [ _currentMessage ignoreStatus] == JVUserIgnored ) ? NSLocalizedString( @"User Ignored", "user ignored bubble title" ) : NSLocalizedString( @"Message Ignored", "message ignored bubble title" ) ) forKey:@"title"];1372 [context setObject:( ( [cmessage ignoreStatus] == JVUserIgnored ) ? NSLocalizedString( @"User Ignored", "user ignored bubble title" ) : NSLocalizedString( @"Message Ignored", "message ignored bubble title" ) ) forKey:@"title"]; 1379 1373 if( [self isMemberOfClass:[JVChatRoom class]] ) [context setObject:[NSString stringWithFormat:@"%@'s message was ignored in %@.", user, [self title]] forKey:@"description"]; 1380 1374 else [context setObject:[NSString stringWithFormat:@"%@'s message was ignored.", user] forKey:@"description"]; 1381 1375 [context setObject:[NSImage imageNamed:@"activity"] forKey:@"image"]; 1382 [[JVNotificationController defaultManager] performNotification:( ( [ _currentMessage ignoreStatus] == JVUserIgnored ) ? @"JVUserIgnored" : @"JVMessageIgnored" ) withContextInfo:context];1376 [[JVNotificationController defaultManager] performNotification:( ( [cmessage ignoreStatus] == JVUserIgnored ) ? @"JVUserIgnored" : @"JVMessageIgnored" ) withContextInfo:context]; 1383 1377 } 1384 1378 … … 1458 1452 1459 1453 child = xmlDocCopyNode( xmlDocGetRootElement( msgDoc ), doc, 1 ); 1460 xmlSetProp( child, "received", [[[ _currentMessage date] description] UTF8String] );1461 if( [ _currentMessage isAction] ) xmlSetProp( child, "action", "yes" );1462 if( [ _currentMessage isHighlighted] ) xmlSetProp( child, "highlight", "yes" );1463 if( [ _currentMessage ignoreStatus] == JVMessageIgnored ) xmlSetProp( child, "ignored", "yes" );1464 else if( [ _currentMessage ignoreStatus] == JVUserIgnored ) xmlSetProp( root, "ignored", "yes" );1454 xmlSetProp( child, "received", [[[cmessage date] description] UTF8String] ); 1455 if( [cmessage isAction] ) xmlSetProp( child, "action", "yes" ); 1456 if( [cmessage isHighlighted] ) xmlSetProp( child, "highlight", "yes" ); 1457 if( [cmessage ignoreStatus] == JVMessageIgnored ) xmlSetProp( child, "ignored", "yes" ); 1458 else if( [cmessage ignoreStatus] == JVUserIgnored ) xmlSetProp( root, "ignored", "yes" ); 1465 1459 xmlAddChild( root, child ); 1466 1460 … … 1494 1488 [self appendMessage:transformedMessage subsequent:subsequent]; 1495 1489 1496 if( [ _currentMessage isHighlighted] ) {1490 if( [cmessage isHighlighted] ) { 1497 1491 NSScroller *scroller = [[[[[display mainFrame] frameView] documentView] enclosingScrollView] verticalScroller]; 1498 1492 if( [scroller isKindOfClass:[JVMarkedScroller class]] ) { … … 1506 1500 _firstMessage = NO; // not the first message anymore 1507 1501 _requiresFullMessage = NO; // next message will not require a new envelope if it is consecutive 1508 } else if( [ _currentMessage ignoreStatus] == JVNotIgnored ) {1502 } else if( [cmessage ignoreStatus] == JVNotIgnored ) { 1509 1503 // the style decided to excluded this message, decrease the new message counts 1510 if( [ _currentMessage isHighlighted] ) _newHighlightMessageCount--;1504 if( [cmessage isHighlighted] ) _newHighlightMessageCount--; 1511 1505 _newMessageCount--; 1512 1506 } … … 1514 1508 xmlFreeDoc( doc ); 1515 1509 1516 [ _currentMessage release]; // not needed anymore1517 _currentMessage = nil;1510 [self _setCurrentMessage:nil]; 1511 [cmessage release]; 1518 1512 1519 1513 [_windowController reloadListItem:self andChildren:NO]; … … 1521 1515 1522 1516 - (int) locationOfMessage:(unsigned int) identifier { 1517 #ifdef WebKitVersion146 1523 1518 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1524 #ifdef _WEB_SCRIPT_OBJECT_H_1525 1519 DOMElement *element = [[[display mainFrame] DOMDocument] getElementById:[NSString stringWithFormat:@"%d", identifier]]; 1526 1520 return [[element valueForKey:@"offsetTop"] intValue]; 1521 } else 1527 1522 #endif 1528 } else { // old JavaScript method 1529 return [[display stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"locationOfMessage( \"%d\" );", identifier]] intValue]; 1530 } 1523 // old JavaScript method 1524 return [[display stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"locationOfMessage( \"%d\" );", identifier]] intValue]; 1531 1525 } 1532 1526 1533 1527 - (int) locationOfElementByIndex:(unsigned int) index { 1528 #ifdef WebKitVersion146 1534 1529 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1535 #ifdef _WEB_SCRIPT_OBJECT_H_1536 1530 DOMHTMLElement *body = [(DOMHTMLDocument *)[[display mainFrame] DOMDocument] body]; 1537 1531 if( index < [[body children] length] ) return [[[[body children] item:index] valueForKey:@"offsetTop"] intValue]; 1538 1532 else return 0; 1533 } else 1539 1534 #endif 1540 } else { // old JavaScript method 1541 return [[display stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"locationOfElementByIndex( %d );", index]] intValue]; 1542 } 1535 // old JavaScript method 1536 return [[display stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"locationOfElementByIndex( %d );", index]] intValue]; 1537 } 1538 1539 - (int) visibleMessageCount { 1540 #ifdef WebKitVersion146 1541 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1542 return [[[(DOMHTMLDocument *)[[display mainFrame] DOMDocument] body] children] length]; 1543 } else 1544 #endif 1545 // old JavaScript method 1546 return [[display stringByEvaluatingJavaScriptFromString:@"scrollBackMessageCount();"] intValue]; 1543 1547 } 1544 1548 1545 1549 - (void) scrollToBottom { 1550 #ifdef WebKitVersion146 1546 1551 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1547 #ifdef _WEB_SCRIPT_OBJECT_H_1548 1552 DOMHTMLElement *body = [(DOMHTMLDocument *)[[display mainFrame] DOMDocument] body]; 1549 1553 [body setValue:[body valueForKey:@"offsetHeight"] forKey:@"scrollTop"]; 1554 } else 1550 1555 #endif 1551 } else { 1552 [display stringByEvaluatingJavaScriptFromString:@"scrollToBottom();"]; 1553 } 1556 // old JavaScript method 1557 [display stringByEvaluatingJavaScriptFromString:@"scrollToBottom();"]; 1554 1558 } 1555 1559 1556 1560 - (void) appendMessage:(NSString *) html subsequent:(BOOL) subsequent { 1557 unsigned int messageCount = 0;1561 unsigned int messageCount = [self visibleMessageCount]; 1558 1562 unsigned int scrollbackLimit = [[NSUserDefaults standardUserDefaults] integerForKey:@"JVChatScrollbackLimit"]; 1559 1563 NSScroller *scroller = [[[[[display mainFrame] frameView] documentView] enclosingScrollView] verticalScroller]; 1560 1564 1561 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1562 #ifdef _WEB_SCRIPT_OBJECT_H_ 1563 messageCount = [[[(DOMHTMLDocument *)[[display mainFrame] DOMDocument] body] children] length]; 1564 #endif 1565 } else messageCount = [[display stringByEvaluatingJavaScriptFromString:@"scrollBackMessageCount();"] intValue]; 1566 1567 if( ( messageCount + 1 ) > scrollbackLimit ) { 1565 if( ! subsequent && ( messageCount + 1 ) > scrollbackLimit ) { 1568 1566 int loc = [self locationOfElementByIndex:( ( messageCount + 1 ) - scrollbackLimit )]; 1569 1567 if( loc > 0 && [scroller isKindOfClass:[JVMarkedScroller class]] ) … … 1571 1569 } 1572 1570 1571 #ifdef WebKitVersion146 1573 1572 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1574 #ifdef _WEB_SCRIPT_OBJECT_H_1575 1573 DOMHTMLElement *element = (DOMHTMLElement *)[[[display mainFrame] DOMDocument] createElement:@"span"]; 1576 1574 DOMHTMLElement *replaceElement = (DOMHTMLElement *)[[[display mainFrame] DOMDocument] getElementById:@"consecutiveInsert"]; … … 1613 1611 // scroll down if we need to 1614 1612 if( [scrollNeeded boolValue] ) [self scrollToBottom]; 1615 #endif 1616 } else { // old JavaScript method 1613 } else 1614 #endif 1615 { // old JavaScript method 1617 1616 NSMutableString *transformedMessage = [html mutableCopy]; 1618 1617 [transformedMessage escapeCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\\\"'"]]; … … 1860 1859 [self addEventMessageToDisplay:[NSString stringWithFormat:NSLocalizedString( @"You have set yourself away with \"%@\".", "self away status set message" ), msgString] withName:@"awaySet" andAttributes:[NSDictionary dictionaryWithObjectsAndKeys:messageString, @"away-message", nil]]; 1861 1860 1862 unsigned int messageCount = 0; 1863 unsigned long loc = 0; 1864 1865 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1866 #ifdef _WEB_SCRIPT_OBJECT_H_ 1867 messageCount = [[[(DOMHTMLDocument *)[[display mainFrame] DOMDocument] body] children] length]; 1868 loc = [self locationOfElementByIndex:( messageCount - 1 )]; 1869 #endif 1870 } else { 1871 messageCount = [[display stringByEvaluatingJavaScriptFromString:@"scrollBackMessageCount();"] intValue]; 1872 loc = [[display stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"locationOfElementByIndex( %d );", ( messageCount - 1 )]] intValue]; 1873 } 1861 unsigned int messageCount = [self visibleMessageCount]; 1862 unsigned long loc = [self locationOfElementByIndex:( messageCount - 1 )]; 1874 1863 1875 1864 NSScroller *scroller = [[[[[display mainFrame] frameView] documentView] enclosingScrollView] verticalScroller]; … … 1878 1867 [self addEventMessageToDisplay:NSLocalizedString( @"You have returned from away.", "self away status removed message" ) withName:@"awayRemoved" andAttributes:nil]; 1879 1868 1880 unsigned int messageCount = 0; 1881 unsigned long loc = 0; 1882 1883 if( [[display mainFrame] respondsToSelector:@selector( DOMDocument )] ) { 1884 #ifdef _WEB_SCRIPT_OBJECT_H_ 1885 messageCount = [[[(DOMHTMLDocument *)[[display mainFrame] DOMDocument] body] children] length]; 1886 loc = [self locationOfElementByIndex:( messageCount - 1 )]; 1887 #endif 1888 } else { 1889 messageCount = [[display stringByEvaluatingJavaScriptFromString:@"scrollBackMessageCount();"] intValue]; 1890 loc = [[display stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"locationOfElementByIndex( %d );", ( messageCount - 1 )]] intValue]; 1891 } 1869 unsigned int messageCount = [self visibleMessageCount]; 1870 unsigned long loc = [self locationOfElementByIndex:( messageCount - 1 )]; 1892 1871 1893 1872 NSScroller *scroller = [[[[[display mainFrame] frameView] documentView] enclosingScrollView] verticalScroller]; … … 2100 2079 } 2101 2080 } 2081 2082 - (void) _setCurrentMessage:(JVMutableChatMessage *) message { 2083 [_currentMessage setObjectSpecifier:nil]; 2084 [_currentMessage autorelease]; 2085 _currentMessage = [message retain]; 2086 2087 id classDescription = [NSClassDescription classDescriptionForClass:[self class]]; 2088 id msgSpecifier = [[[NSPropertySpecifier alloc] initWithContainerClassDescription:classDescription containerSpecifier:[self objectSpecifier] key:@"currentMessage"] autorelease]; 2089 [_currentMessage setObjectSpecifier:msgSpecifier]; 2090 } 2102 2091 @end 2103 2092 … … 2122 2111 BOOL localEcho = ( [[command evaluatedArguments] objectForKey:@"echo"] ? [[[command evaluatedArguments] objectForKey:@"echo"] boolValue] : YES ); 2123 2112 2124 [_currentMessage autorelease]; // set the message to an object property for plugins, if needed... 2125 _currentMessage = [[JVMutableChatMessage alloc] initWithText:attributeMsg sender:[[self connection] nickname] andTranscript:self]; 2126 [_currentMessage setAction:action]; 2127 2128 id classDescription = [NSClassDescription classDescriptionForClass:[self class]]; 2129 id msgSpecifier = [[[NSPropertySpecifier alloc] initWithContainerClassDescription:classDescription containerSpecifier:[self objectSpecifier] key:@"currentMessage"] autorelease]; 2130 [_currentMessage setObjectSpecifier:msgSpecifier]; 2131 2132 [self sendMessage:_currentMessage]; 2133 2134 if( localEcho ) [self echoSentMessageToDisplay:[_currentMessage body] asAction:[_currentMessage isAction]]; 2135 2136 [_currentMessage release]; 2137 _currentMessage = nil; 2113 JVMutableChatMessage *cmessage = [[JVMutableChatMessage alloc] initWithText:attributeMsg sender:[[self connection] nickname] andTranscript:self]; 2114 [cmessage setAction:action]; 2115 2116 [self sendMessage:cmessage]; 2117 2118 if( localEcho ) [self echoSentMessageToDisplay:[cmessage body] asAction:[cmessage isAction]]; 2119 2120 [cmessage release]; 2138 2121 } 2139 2122 branches/overhaul/MVIRCChatConnection.m
r2113 r2161 1 1 #import <unistd.h> 2 #import <pthread.h> 2 3 3 4 #define HAVE_IPV6 1 … … 190 191 MVIRCChatConnection *self = [MVIRCChatConnection _connectionForServer:server]; 191 192 192 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 193 [self performSelectorOnMainThread:@selector( _didDisconnect ) withObject:nil waitUntilDone:YES]; 194 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 193 if( ! pthread_main_np() ) { // if not main thread 194 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 195 [self performSelectorOnMainThread:@selector( _didDisconnect ) withObject:nil waitUntilDone:YES]; 196 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 197 } else [self performSelector:@selector( _didDisconnect )]; 195 198 } 196 199 … … 199 202 if( ! self ) return; 200 203 201 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 202 [self performSelectorOnMainThread:@selector( _didNotConnect ) withObject:nil waitUntilDone:YES]; 203 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 204 server_ref( server ); 205 206 if( ! pthread_main_np() ) { // if not main thread 207 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 208 [self performSelectorOnMainThread:@selector( _didNotConnect ) withObject:nil waitUntilDone:YES]; 209 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 210 } else [self performSelector:@selector( _didNotConnect )]; 204 211 } 205 212 branches/overhaul/MVIRCFileTransfer.m
r2026 r2161 1 #import <pthread.h> 2 1 3 #define HAVE_IPV6 1 2 4 #define MODULE_NAME "MVIRCFileTransfer" … … 36 38 if( ! self ) return; 37 39 38 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 39 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 40 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 40 if( ! pthread_main_np() ) { // if not main thread 41 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 42 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 43 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 44 } else [self performSelector:@selector( _destroying )]; 41 45 42 46 if( dcc -> size != dcc -> transfd ) { … … 55 59 if( ! self ) return; 56 60 57 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 58 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 59 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 61 if( ! pthread_main_np() ) { // if not main thread 62 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 63 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 64 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 65 } else [self performSelector:@selector( _destroying )]; 60 66 61 67 NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"The file transfer connection could not be made.", NSLocalizedDescriptionKey, nil]; … … 68 74 if( ! self ) return; 69 75 70 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 71 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 72 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 76 if( ! pthread_main_np() ) { // if not main thread 77 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 78 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 79 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 80 } else [self performSelector:@selector( _destroying )]; 73 81 74 82 NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"The file %@ could not be created, please make sure you have write permissions in the %@ folder.", NSLocalizedDescriptionKey, nil]; … … 81 89 if( ! self ) return; 82 90 83 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 84 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 85 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 86 91 if( ! pthread_main_np() ) { // if not main thread 92 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 93 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 94 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 95 } else [self performSelector:@selector( _destroying )]; 96 87 97 NSError *ferror = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]; 88 98 NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"The file %@ could not be opened, please make sure you have read permissions for this file.", NSLocalizedDescriptionKey, ferror, @"NSUnderlyingErrorKey", nil]; … … 95 105 if( ! self ) return; 96 106 97 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 98 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 99 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 107 if( ! pthread_main_np() ) { // if not main thread 108 [MVIRCChatConnectionThreadLock unlock]; // prevents a deadlock, since waitUntilDone is required. threads synced 109 [self performSelectorOnMainThread:@selector( _destroying ) withObject:nil waitUntilDone:YES]; 110 [MVIRCChatConnectionThreadLock lock]; // lock back up like nothing happened 111 } else [self performSelector:@selector( _destroying )]; 100 112 101 113 NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"The file %@ is already being offerend to %@.", NSLocalizedDescriptionKey, nil]; … … 106 118 #pragma mark - 107 119 120 static BOOL fileTransferSignalsRegistered = NO; 121 108 122 @implementation MVFileTransfer (MVIRCFileTransferPrivate) 109 123 + (id) _transferForDCCFileRecord:(FILE_DCC_REC *) record { … … 122 136 + (void) initialize { 123 137 [super initialize]; 124 static BOOL tooLate = NO; 125 if( ! tooLate ) { 138 if( ! fileTransferSignalsRegistered ) { 126 139 [MVIRCChatConnectionThreadLock lock]; 127 140 signal_add_last( "dcc connected", (SIGNAL_FUNC) MVFileTransferConnected ); … … 132 145 signal_add_last( "dcc error send exists", (SIGNAL_FUNC) MVFileTransferErrorSendExists ); 133 146 [MVIRCChatConnectionThreadLock unlock]; 134 tooLate= YES;147 fileTransferSignalsRegistered = YES; 135 148 } 136 149 } … … 329 342 static BOOL tooLate = NO; 330 343 if( ! tooLate ) { 344 [MVIRCChatConnectionThreadLock lock]; 345 signal_add_last( "dcc get receive", (SIGNAL_FUNC) MVIRCDownloadFileTransferSpecifyPath ); 346 [MVIRCChatConnectionThreadLock unlock]; 347 tooLate = YES; 348 } 349 350 if( ! fileTransferSignalsRegistered ) { 331 351 [MVIRCChatConnectionThreadLock lock]; 332 352 signal_add_last( "dcc connected", (SIGNAL_FUNC) MVFileTransferConnected ); … … 336 356 signal_add_last( "dcc error file open", (SIGNAL_FUNC) MVFileTransferErrorFileOpen ); 337 357 signal_add_last( "dcc error send exists", (SIGNAL_FUNC) MVFileTransferErrorSendExists ); 338 signal_add_last( "dcc get receive", (SIGNAL_FUNC) MVIRCDownloadFileTransferSpecifyPath );339 358 [MVIRCChatConnectionThreadLock unlock]; 340 tooLate= YES;359 fileTransferSignalsRegistered = YES; 341 360 } 342 361 } branches/overhaul/Plug-Ins/Standard Commands/JVStandardCommands.m
r2020 r2161 55 55 if( ! [command caseInsensitiveCompare:@"me"] || ! [command caseInsensitiveCompare:@"action"] || ! [command caseInsensitiveCompare:@"say"] ) { 56 56 if( [arguments length] ) { 57 BOOL action = ( ! [command caseInsensitiveCompare:@"me"] || ! [command caseInsensitiveCompare:@"action"] ); 58 [chat echoSentMessageToDisplay:arguments asAction:action]; 59 if( isChatRoom ) [[room target] sendMessage:arguments asAction:action]; 60 else [[chat target] sendMessage:arguments withEncoding:[chat encoding] asAction:action]; 61 } 62 return YES; 63 } else if( [[command substringToIndex:1] isEqualToString:@"/"] ) { 64 NSMutableAttributedString *line = [[[NSMutableAttributedString alloc] init] autorelease]; 65 if( [command length] > 1 ) [line replaceCharactersInRange:NSMakeRange( 0, 0 ) withString:command]; 66 if( [arguments length] ) { 67 [line replaceCharactersInRange:NSMakeRange( [line length], 0 ) withString:@" "]; 68 [line appendAttributedString:arguments]; 69 } 70 if( [line length] ) { 71 [chat echoSentMessageToDisplay:line asAction:NO]; 72 if( isChatRoom ) [[room target] sendMessage:line asAction:NO]; 73 else [[chat target] sendMessage:line withEncoding:[chat encoding] asAction:NO]; 57 if( ! [command caseInsensitiveCompare:@"me"] || ! [command caseInsensitiveCompare:@"action"] ) { 58 // This is so plugins can process /me actions as well 59 // We're avoiding /say for now, as that really should just output exactly what 60 // the input was so we should still bypass plugins for /say 61 JVMutableChatMessage *message = [[[NSClassFromString( @"JVMutableChatMessage" ) alloc] initWithText:arguments sender:[[chat connection] nickname] andTranscript:chat] autorelease]; 62 [message setAction:YES]; 63 [chat sendMessage:message]; 64 [chat echoSentMessageToDisplay:[message body] asAction:YES]; 65 } else { 66 [chat echoSentMessageToDisplay:arguments asAction:NO]; 67 if( isChatRoom ) [[room target] sendMessage:arguments asAction:NO]; 68 else [[chat target] sendMessage:arguments withEncoding:[chat encoding] asAction:NO]; 69 } 74 70 } 75 71 return YES; … … 592 588 } 593 589 594 if( offset < [argsArray count] )590 if( offset < [argsArray count] && [(NSString *)[argsArray objectAtIndex:offset] length] ) 595 591 rooms = [argsArray subarrayWithRange:NSMakeRange( offset, [argsArray count] - offset )]; 596 592 branches/overhaul/Resources/Changes.rtf
r1954 r2161 14 14 15 15 \f2\b0\fs20 \cf0 \'b7 16 \f3 Can't join channels that require a key with the GUI. A workaround is to use this command "/join #room password" for the room.\ 17 18 \f2 \'b7 16 19 \f3 SOCKS and HTTP proxies don't function still.\ 17 20 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural … … 21 24 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 22 25 23 \fs20 \cf0 Build 2C11 24 \f3\b0 (October, 2004) \'d1 25 \f1\b\fs28 \ 26 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 27 28 \f2\b0\fs20 \cf0 \'b7 29 \f3 Rewrite of most of the legacy code.\ 30 31 \f2 \'b7 32 \f3 Support for the Quieted mode for servers that support it, SILC also supports it.\ 33 34 \f2 \'b7 35 \f3 Joining chat rooms with a password is now supported.\ 36 37 \f2 \'b7 38 \f3 Kicks that you perform on another user can have colors and text formatting, and will use the room's encoding.\ 26 \fs20 \cf0 Build 2C12 27 \f3\b0 (November, 2004) \'d1 28 \f1\b\fs28 \ 29 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 30 31 \f2\b0\fs20 \cf0 \'b7 32 \f3\fs24 33 \fs20 Fixed a crash that occurred sometimes when changing away status and when members parted a room with a malformed part reason.\ 34 35 \f2 \'b7 36 \f3\fs24 37 \fs20 Fixed a few reported exception errors.\ 38 39 \f2 \'b7 40 \f3 Added the German (Deutsch) localization by Alexander Kempgen.\ 41 42 \f2 \'b7 43 \f3 Fixed the appearance of the Direct Chat panel where it meets the tab bar. There is now a divider line like Chat Rooms.\ 44 45 \f2 \'b7 46 \f3 Enabled the Send File context menu for private chat panels.\ 47 48 \f2 \'b7 49 \f3\fs24 50 \fs20 Dragging files to private chat tabs will transfer the files to that user.\ 51 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 52 53 \f1\b \cf0 \ 54 Build 2C11 55 \f3\b0 (November 9, 2004) \'d1 56 \f1\b\fs28 \ 57 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 58 59 \f2\b0\fs20 \cf0 \'b7 60 \f3 All DCC file transfer crashes fixed, thank you for submiting your crash reports!\ 61 62 \f2 \'b7 63 \f3 Plugins and script plugins can now add contextual menu items to any GUI element in Colloquy that has an existing contextual menu.\ 64 65 \f2 \'b7 66 \f3 Updated iTunes script that has the option to show a progress bar, current and duration time and save the preferences. To see all the preference keys, type: 67 \f4\fs18 \cf4 \CocoaLigature0 /itunes prefs 68 \f3\fs20 \cf0 \CocoaLigature1 To toggle a preference, type: 69 \f4\fs18 \cf4 \CocoaLigature0 /itunes prefs <key> [on|off] 70 \f3\fs20 \cf0 \CocoaLigature1 \ 71 72 \f2 \'b7 73 \f3 Added a multi-search script that lets you search any of 11 search engines from Yahoo!, Google, ADC, VersionTracker, PHP, Google Image Search and more. For a list of all the commands type: 74 \f4\fs18 \cf4 \CocoaLigature0 /search help 75 \f3\fs20 \cf0 \CocoaLigature1 \ 39 76 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 40 77 41 78 \f1\b \cf0 \ 42 79 Build 2C10 43 \f3\b0 (September, 2004) \'d1 44 \f1\b\fs28 \ 45 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 46 47 \f2\b0\fs20 \cf0 \'b7 80 \f3\b0 (October 21, 2004) \'d1 81 \f1\b\fs28 \ 82 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 83 84 \f2\b0\fs20 \cf0 \'b7 85 \f3 Some DCC file transfer crashes fixed.\ 86 87 \f2 \'b7 48 88 \f3 The SILC protocol is now supported right along side existing IRC connections. For more information about SILC visit http://silcnet.org.\ 49 89 … … 75 115 \f1\b \cf0 \ 76 116 Build 2C9 77 \f3\b0 (August , 2004) \'d1117 \f3\b0 (August & September, 2004) \'d1 78 118 \f1\b\fs28 \ 79 119 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural … … 861 901 \f2 \'b7 862 902 \f3 Some perferences will not carry over from version 1.\ 863 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 864 865 \f2 \cf0 \'b7 903 904 \f2 \'b7 866 905 \f3 No longer crashes when you don't have an outside internet connection and/or the host-name can't be resolved.\ 867 906 … … 924 963 \f2 \'b7 925 964 \f3 Windows that are miniaturized into the Dock will not keep popping out when either "Show hidden \'c9 on \'c9 activity" preferences are on.\ 926 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 927 928 \f2 \cf0 \'b7 965 966 \f2 \'b7 929 967 \f3 All windows remember their position on screen better, and chat windows remember the member drawer size and state.\ 930 968 … … 957 995 \f5\i /itunes 958 996 \f3\i0 in a room to test the basic iTunes plugin.\ 959 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 960 961 \f2 \cf0 \'b7 997 998 \f2 \'b7 962 999 \f3 Added the French localization.\ 963 1000 … … 1010 1047 \f2 \'b7 1011 1048 \f3 NickServ password authorization enabled with password prompts and saving passwords in your keychain.\ 1012 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 1013 1014 \f2 \cf0 \'b7 1049 1050 \f2 \'b7 1015 1051 \f3 Connections are stored different now, old bookmarks will not load and may show up as blank lines in the connection manager.\ 1016 1052 … … 1111 1147 \f2 \'b7 1112 1148 \f3 IRC URLs are now handled from the system and internally in chat dialog (was only rooms before, now allows new server connections). Here is an example URL that will connect to 'javelin.cc' as user 'test' on port '6669' and will join the room 'colloquy' when connected: \ul irc://test@javelin.cc:6669/#colloquy\ulnone . Note that only the scheme and host part of the URL need to be present. Valid room paths a begin with '#', '&' or '+'; if the path of the URL is not a valid room then a new message to that user is made. Mozilla's Chatzilla handles IRC URLs in this manner also.\ 1113 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 1114 1115 \f2 \cf0 \'b7 1149 1150 \f2 \'b7 1116 1151 \f3 Nickname changes were not being reported due to a Firetalk API change \'d1 now fixed.\ 1117 1152 … … 1144 1179 \f3\b0 (Wednesday November 13, 2002) \'d1 1145 1180 \f1\b\fs28 \ 1146 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 1147 1148 \f3\b0\fs20 \cf0 1181 1182 \f3\b0\fs20 1149 1183 \f2 \'b7 1150 1184 \f3 Enabled the Software Update check.\ branches/overhaul/Resources/Info.plist
r1953 r2161 58 58 </array> 59 59 <key>CFBundleTypeName</key> 60 <string>Chat transcript</string>60 <string>Chat Transcript</string> 61 61 <key>CFBundleTypeOSTypes</key> 62 62 <array> … … 65 65 <key>CFBundleTypeRole</key> 66 66 <string>Viewer</string> 67 </dict> 68 </array> 69 <key>UTExportedTypeDeclarations</key> 70 <array> 71 <dict> 72 <key>UTTypeIdentifier</key> 73 <string>cc.javelin.colloquy.colloquystyle</string> 74 <key>UTTypeReferenceURL</key> 75 <string>http://www.colloquy.info/</string> 76 <key>UTTypeDescription</key> 77 <string>Colloquy View Style</string> 78 <key>UTTypeIconName</key> 79 <string>Generic.icns</string> 80 <key>UTTypeConformsTo</key> 81 <array> 82 <string>public.bundle</string> 83 </array> 84 <key>UTTypeTagSpecification</key> 85 <dict> 86 <key>com.apple.ostype</key> 87 <string>coSt</string> 88 <key>public.filename-extension</key> 89 <array> 90 <string>colloquyStyle</string> 91 <string>colloquystyle</string> 92 </array> 93 <key>public.mime-type</key> 94 <string>application/data</string> 95 </dict> 96 </dict> 97 <dict> 98 <key>UTTypeIdentifier</key> 99 <string>cc.javelin.colloquy.colloquyemoticons</string> 100 <key>UTTypeReferenceURL</key> 101 <string>http://www.colloquy.info/</string> 102 <key>UTTypeDescription</key> 103 <string>Colloquy Emoticon Set</string> 104 <key>UTTypeIconName</key> 105 <string>Generic.icns</string> 106 <key>UTTypeConformsTo</key>
