Changeset 23850
- Timestamp:
- 06/08/2008 02:43:46 PM (6 months ago)
- Files:
-
- trunk/Adium.xcodeproj/project.pbxproj (modified) (7 diffs)
- trunk/Source/AIAbstractLogViewerWindowController.m (modified) (5 diffs)
- trunk/Source/AIXMLChatlogConverter.h (moved) (moved from trunk/Source/GBChatlogHTMLConverter.h) (2 diffs)
- trunk/Source/AIXMLChatlogConverter.m (moved) (moved from trunk/Source/GBChatlogHTMLConverter.m) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Adium.xcodeproj/project.pbxproj
r23835 r23850 571 571 34A1A8ED0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = 34A1A8EB0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.h */; }; 572 572 34A1A8EE0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A1A8EC0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.m */; }; 573 34A1AB6C0DFC531000AC78CF /* AIXMLChatlogConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A1AB6B0DFC531000AC78CF /* AIXMLChatlogConverter.m */; }; 573 574 34A1EDAF0DD3AF220090667A /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C103FAE057127A500F3C158 /* WebKit.framework */; }; 574 575 34A1EE990DD3BFB00090667A /* AIFacebookBuddyListManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A1EE980DD3BFB00090667A /* AIFacebookBuddyListManager.m */; }; … … 1321 1322 F551B1000B8F5130007D3A3C /* FireLogImporter.nib in Resources */ = {isa = PBXBuildFile; fileRef = F56E0DAF0A4CDF9C008D1EB5 /* FireLogImporter.nib */; }; 1322 1323 F58904F20A7828B9001F0ADC /* OTR.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 341BDBBA0968BC9A00CF83F5 /* OTR.framework */; }; 1323 F5DA8A740A546AC5004A41D0 /* GBChatlogHTMLConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DA8A720A546AC4004A41D0 /* GBChatlogHTMLConverter.m */; };1324 1324 F5F8CA4D0A1A9C9400154550 /* GBQuestionHandlerPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F8CA4B0A1A9C9400154550 /* GBQuestionHandlerPlugin.m */; }; 1325 1325 /* End PBXBuildFile section */ … … 3045 3045 34A1A8EB0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AICustomSocialNetworkingStatusWindowController.h; path = "Frameworks/Adium Framework/Source/AICustomSocialNetworkingStatusWindowController.h"; sourceTree = "<group>"; }; 3046 3046 34A1A8EC0DFB27A800AC78CF /* AICustomSocialNetworkingStatusWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AICustomSocialNetworkingStatusWindowController.m; path = "Frameworks/Adium Framework/Source/AICustomSocialNetworkingStatusWindowController.m"; sourceTree = "<group>"; }; 3047 34A1AB6A0DFC531000AC78CF /* AIXMLChatlogConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIXMLChatlogConverter.h; path = Source/AIXMLChatlogConverter.h; sourceTree = "<group>"; }; 3048 34A1AB6B0DFC531000AC78CF /* AIXMLChatlogConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIXMLChatlogConverter.m; path = Source/AIXMLChatlogConverter.m; sourceTree = "<group>"; }; 3047 3049 34A1EE970DD3BFB00090667A /* AIFacebookBuddyListManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIFacebookBuddyListManager.h; path = "Plugins/Facebook Service/AIFacebookBuddyListManager.h"; sourceTree = "<group>"; }; 3048 3050 34A1EE980DD3BFB00090667A /* AIFacebookBuddyListManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIFacebookBuddyListManager.m; path = "Plugins/Facebook Service/AIFacebookBuddyListManager.m"; sourceTree = "<group>"; }; … … 4270 4272 F59DB3E7033EB4B601A8010A /* Adium.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Adium.h; path = "Frameworks/Adium Framework/Source/Adium.h"; sourceTree = "<group>"; }; 4271 4273 F59DB6AD033EB74801A8010A /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Source/main.m; sourceTree = SOURCE_ROOT; }; 4272 F5DA8A710A546AC4004A41D0 /* GBChatlogHTMLConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GBChatlogHTMLConverter.h; path = Source/GBChatlogHTMLConverter.h; sourceTree = "<group>"; };4273 F5DA8A720A546AC4004A41D0 /* GBChatlogHTMLConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GBChatlogHTMLConverter.m; path = Source/GBChatlogHTMLConverter.m; sourceTree = "<group>"; };4274 4274 F5F0FE9C04B12CAC01A80106 /* AIEmoticonPreferences.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AIEmoticonPreferences.h; path = Plugins/Emoticons/AIEmoticonPreferences.h; sourceTree = "<group>"; }; 4275 4275 F5F0FE9D04B12CAC01A80106 /* AIEmoticonPreferences.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AIEmoticonPreferences.m; path = Plugins/Emoticons/AIEmoticonPreferences.m; sourceTree = "<group>"; }; … … 7435 7435 9ECB03E409F2A9D800996F44 /* AIXMLAppender.h */, 7436 7436 9ECB03E509F2A9D800996F44 /* AIXMLAppender.m */, 7437 F5DA8A710A546AC4004A41D0 /* GBChatlogHTMLConverter.h */,7438 F5DA8A720A546AC4004A41D0 /* GBChatlogHTMLConverter.m */,7437 34A1AB6A0DFC531000AC78CF /* AIXMLChatlogConverter.h */, 7438 34A1AB6B0DFC531000AC78CF /* AIXMLChatlogConverter.m */, 7439 7439 ); 7440 7440 name = "XML Logging"; … … 9631 9631 34382CEA0A50386C004BF6A2 /* DCMessageContextDisplayPlugin.m in Sources */, 9632 9632 348B250D0A50A1C900B2B972 /* ESSourceListBackgroundView.m in Sources */, 9633 F5DA8A740A546AC5004A41D0 /* GBChatlogHTMLConverter.m in Sources */,9634 9633 340670A90A55A4B4004E22AC /* ESGlassSplitView.m in Sources */, 9635 9634 345AFAEE0A5D9A5F00D7DA6F /* AINoisyTableColumn.m in Sources */, … … 9739 9738 EFB1C3140DDBDA3100B3973D /* AITwitterIMPlugin.m in Sources */, 9740 9739 11077B6F0DE647C100A4DD25 /* AIStatusItemView.m in Sources */, 9740 34A1AB6C0DFC531000AC78CF /* AIXMLChatlogConverter.m in Sources */, 9741 9741 ); 9742 9742 runOnlyForDeploymentPostprocessing = 0; trunk/Source/AIAbstractLogViewerWindowController.m
r23817 r23850 12 12 #import "AILoggerPlugin.h" 13 13 #import "ESRankingCell.h" 14 #import " GBChatlogHTMLConverter.h"14 #import "AIXMLChatlogConverter.h" 15 15 #import "AILogDateFormatter.h" 16 16 … … 720 720 if ([[theLog path] hasSuffix:@".AdiumHTMLLog"] || [[theLog path] hasSuffix:@".html"] || [[theLog path] hasSuffix:@".html.bak"]) { 721 721 //HTML log 722 NSString *logFileText = [NSString stringWithContentsOfFile:[logBasePath stringByAppendingPathComponent:[theLog path]]]; 723 722 NSString *logFileText = [NSString stringWithContentsOfFile:[logBasePath stringByAppendingPathComponent:[theLog path]]]; 723 NSAttributedString *attributedLogFileText = [AIHTMLDecoder decodeHTML:logFileText]; 724 725 if (showEmoticons) { 726 attributedLogFileText = [[adium contentController] filterAttributedString:attributedLogFileText 727 usingFilterType:AIFilterMessageDisplay 728 direction:AIFilterOutgoing 729 context:nil]; 730 } 731 724 732 if (displayText) { 725 [displayText appendAttributedString: [AIHTMLDecoder decodeHTML:logFileText]];733 [displayText appendAttributedString:attributedLogFileText]; 726 734 } else { 727 displayText = [ [AIHTMLDecoder decodeHTML:logFileText]mutableCopy];735 displayText = [attributedLogFileText mutableCopy]; 728 736 } 729 737 … … 738 746 [[[logFullPath lastPathComponent] stringByDeletingPathExtension] stringByAppendingPathExtension:@"xml"]]; 739 747 } 740 741 //If this log begins with a malformed UTF-8 BOM (which was written out by Adium for a brief time between 1.0b7 and 1.0b8), fix it before trying to read it in. 742 enum { 743 failedUtf8BomLength = 6 744 }; 745 NSData *data = [NSData dataWithContentsOfMappedFile:logFullPath]; 746 const unsigned char *ptr = [data bytes]; 747 unsigned len = [data length]; 748 if ((len >= failedUtf8BomLength) 749 && (ptr[0] == 0xC3) 750 && (ptr[1] == 0x94) 751 && (ptr[2] == 0xC2) 752 && (ptr[3] == 0xAA) 753 && (ptr[4] == 0xC3) 754 && (ptr[5] == 0xB8) 755 ) { 756 //Yup. Back up the old file, then strip it off. 757 NSLog(@"Transcript file at %@ has unwanted bytes at the front of it. (This is a bug in a previous version of Adium, not this version.) Attempting recovery.", logFullPath); 758 NSString *backupPath = [logFullPath stringByAppendingPathExtension:@"bak"]; 759 if(![[NSFileManager defaultManager] movePath:logFullPath toPath:backupPath handler:nil]) 760 NSLog(@"Could not back up file; recovery failed. This transcript will probably appear blank in the transcript viewer."); 761 else { 762 NSRange range = { failedUtf8BomLength, len - failedUtf8BomLength }; 763 NSData *theRestOfIt = [data subdataWithRange:range]; 764 if([theRestOfIt writeToFile:logFullPath atomically:YES]) 765 NSLog(@"Wrote fixed version to same file. The corrupted version was renamed to %@; you may remove this file at your leisure after you are satisfied that the recovery succeeded. You can test this by viewing the transcript (%@) in the transcript viewer.", backupPath, [logFullPath lastPathComponent]); 766 else 767 NSLog(@"Could not write fix!"); 768 } 769 } 770 771 NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:showTimestamps] 772 forKey:@"showTimestamps"]; 773 NSString *logFileText = [GBChatlogHTMLConverter readFile:logFullPath withOptions:options]; 774 if (logFileText) { 748 749 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 750 [NSNumber numberWithBool:showTimestamps], @"showTimestamps", 751 [NSNumber numberWithBool:showEmoticons], @"showEmoticons", 752 nil]; 753 NSAttributedString *attributedLogFileText = [AIXMLChatlogConverter readFile:logFullPath withOptions:options]; 754 if (attributedLogFileText) { 775 755 if (displayText) 776 [displayText appendAttributedString: [AIHTMLDecoder decodeHTML:logFileText]];756 [displayText appendAttributedString:attributedLogFileText]; 777 757 else 778 displayText = [ [AIHTMLDecoder decodeHTML:logFileText]mutableCopy];758 displayText = [attributedLogFileText mutableCopy]; 779 759 } 780 760 … … 784 764 if (logFileText) { 785 765 AITextAttributes *textAttributes = [AITextAttributes textAttributesWithFontFamily:@"Helvetica" traits:0 size:12]; 766 NSAttributedString *attributedLogFileText = [[[NSAttributedString alloc] initWithString:logFileText 767 attributes:[textAttributes dictionary]] autorelease]; 768 if (showEmoticons) { 769 attributedLogFileText = [[adium contentController] filterAttributedString:attributedLogFileText 770 usingFilterType:AIFilterMessageDisplay 771 direction:AIFilterOutgoing 772 context:nil]; 773 } 786 774 787 775 if (displayText) { 788 [displayText appendAttributedString:[[[NSAttributedString alloc] initWithString:logFileText 789 attributes:[textAttributes dictionary]] autorelease]]; 776 [displayText appendAttributedString:attributedLogFileText]; 790 777 } else { 791 displayText = [ [NSMutableAttributedString alloc] initWithString:logFileText attributes:[textAttributes dictionary]];778 displayText = [attributedLogFileText mutableCopy]; 792 779 } 793 780 } … … 885 872 } 886 873 887 //Filter emoticons 888 if (showEmoticons) { 889 finalDisplayText = [[adium contentController] filterAttributedString:displayText 890 usingFilterType:AIFilterMessageDisplay 891 direction:AIFilterOutgoing 892 context:nil]; 893 } else { 894 finalDisplayText = displayText; 895 } 874 finalDisplayText = displayText; 896 875 } 897 876 trunk/Source/AIXMLChatlogConverter.h
r23660 r23850 37 37 } AINameFormat; 38 38 39 @interface GBChatlogHTMLConverter : AIObject { 39 @class AIHTMLDecoder; 40 41 @interface AIXMLChatlogConverter : AIObject { 40 42 CFXMLParserRef parser; 41 43 NSString *inputFileString; … … 52 54 BOOL autoResponse; 53 55 BOOL showTimestamps; 56 BOOL showEmoticons; 54 57 NSString *status; 55 58 56 NSMutableString *output; 59 NSMutableAttributedString *output; 60 NSAttributedString *newlineAttributedString; 57 61 NSDictionary *statusLookup; 58 62 AIHTMLDecoder *htmlDecoder; 63 59 64 AINameFormat nameFormat; 60 65 } 61 66 62 + (NS String *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options;63 - (NS String *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options;67 + (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options; 68 - (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options; 64 69 65 70 @end trunk/Source/AIXMLChatlogConverter.m
r23660 r23850 15 15 */ 16 16 17 #import " GBChatlogHTMLConverter.h"17 #import "AIXMLChatlogConverter.h" 18 18 #import "AIStandardListWindowController.h" 19 #import <Adium/AIHTMLDecoder.h> 19 20 #import <Adium/AIListContact.h> 20 21 #import <Adium/AIAccountControllerProtocol.h> 21 22 #import <Adium/AIContactControllerProtocol.h> 23 #import <Adium/AIContentControllerProtocol.h> 22 24 #import <Adium/AIPreferenceControllerProtocol.h> 23 25 #import <Adium/AIStatusControllerProtocol.h> … … 26 28 #import <AIUtilities/AIStringAdditions.h> 27 29 28 29 30 #define PREF_GROUP_WEBKIT_MESSAGE_DISPLAY @"WebKit Message Display" 30 31 #define KEY_WEBKIT_USE_NAME_FORMAT @"Use Custom Name Format" … … 35 36 static void endStructure(CFXMLParserRef parser, void *xmlType, void *context); 36 37 37 @implementation GBChatlogHTMLConverter38 39 + (NS String *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options40 { 41 GBChatlogHTMLConverter *converter = [[GBChatlogHTMLConverter alloc] init];42 NS String *ret = [[converter readFile:filePath withOptions:options] retain];38 @implementation AIXMLChatlogConverter 39 40 + (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options 41 { 42 AIXMLChatlogConverter *converter = [[AIXMLChatlogConverter alloc] init]; 43 NSAttributedString *ret = [[converter readFile:filePath withOptions:options] retain]; 43 44 [converter release]; 44 45 return [ret autorelease]; … … 61 62 status = nil; 62 63 64 newlineAttributedString = [[NSAttributedString alloc] initWithString:@"\n" attributes:nil]; 65 63 66 statusLookup = [[NSDictionary alloc] initWithObjectsAndKeys: 64 67 AILocalizedString(@"Online", nil), @"online", … … 93 96 - (void)dealloc 94 97 { 98 [newlineAttributedString release]; 95 99 [inputFileString release]; 96 100 [eventTranslate release]; … … 104 108 [output release]; 105 109 [statusLookup release]; 110 [htmlDecoder release]; 106 111 [super dealloc]; 107 112 } 108 113 109 - (NS String *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options114 - (NSAttributedString *)readFile:(NSString *)filePath withOptions:(NSDictionary *)options 110 115 { 111 116 NSData *inputData = [NSData dataWithContentsOfFile:filePath]; 112 117 inputFileString = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding]; 113 118 NSURL *url = [[NSURL alloc] initFileURLWithPath:filePath]; 114 output = [[NSMutableString alloc] init]; 115 [output appendFormat:@"<head><base href=\"%@\" /></head>", [filePath stringByDeletingLastPathComponent]]; 119 output = [[NSMutableAttributedString alloc] init]; 120 121 htmlDecoder = [[AIHTMLDecoder alloc] init]; 122 [htmlDecoder setBaseURL:[filePath stringByDeletingLastPathComponent]]; 116 123 117 124 showTimestamps = [[options objectForKey:@"showTimestamps"] boolValue]; 125 showEmoticons = [[options objectForKey:@"showEmoticons"] boolValue]; 126 118 127 CFXMLParserCallBacks callbacks = { 119 128 0, … … 298 307 timeZone:nil 299 308 locale:nil]; 300 [output appendFormat:@"<div class=\"%@\">%@<span class=\"sender\">%@%@:</span> <pre class=\"message\">%@</pre></div>\n", 301 ([mySN isEqualToString:sender] ? @"send" : @"receive"), 302 (showTimestamps ? [NSString stringWithFormat:@"<span class=\"timestamp\">%@</span> ", timestampStr] : @""), 303 shownSender, (autoResponse ? AILocalizedString(@" (Autoreply)", nil) : @""), 304 message]; 309 BOOL sentMessage = [mySN isEqualToString:sender]; 310 [output appendAttributedString:[htmlDecoder decodeHTML:[NSString stringWithFormat: 311 @"<div class=\"%@\">%@<span class=\"sender\">%@%@:</span></div> ", 312 (sentMessage ? @"send" : @"receive"), 313 (showTimestamps ? [NSString stringWithFormat:@"<span class=\"timestamp\">%@</span> ", timestampStr] : @""), 314 shownSender, (autoResponse ? AILocalizedString(@" (Autoreply)", nil) : @"")]]]; 315 316 NSAttributedString *attributedMessage = [htmlDecoder decodeHTML:message]; 317 if (showEmoticons) { 318 attributedMessage = [[adium contentController] filterAttributedString:attributedMessage 319 usingFilterType:AIFilterMessageDisplay 320 direction:(sentMessage ? AIFilterOutgoing : AIFilterIncoming) 321 context:nil]; 322 } 323 [output appendAttributedString:attributedMessage]; 324 [output appendAttributedString:newlineAttributedString]; 325 305 326 state = XML_STATE_CHAT; 306 327 } … … 327 348 328 349 if([displayMessage length]) 329 [output append Format:@"<div class=\"status\">%@ (%@)</div>\n",330 displayMessage,331 [date descriptionWithCalendarFormat:[NSDateFormatter localizedDateFormatStringShowingSeconds:YES332 showingAMorPM:YES]333 timeZone:nil334 locale:nil]];350 [output appendAttributedString:[htmlDecoder decodeHTML:[NSString stringWithFormat:@"<div class=\"status\">%@ (%@)</div>\n", 351 displayMessage, 352 [date descriptionWithCalendarFormat:[NSDateFormatter localizedDateFormatStringShowingSeconds:YES 353 showingAMorPM:YES] 354 timeZone:nil 355 locale:nil]]]]; 335 356 state = XML_STATE_CHAT; 336 357 } … … 361 382 NSString *name = [NSString stringWithString:(NSString *)CFXMLNodeGetString(node)]; 362 383 const CFXMLElementInfo *info = CFXMLNodeGetInfoPtr(node); 363 [( GBChatlogHTMLConverter *)context startedElement:name info:info];384 [(AIXMLChatlogConverter *)context startedElement:name info:info]; 364 385 ret = (element *)malloc(sizeof(element)); 365 386 ret->name = [name retain]; … … 396 417 empty = ((element *)xmlType)->empty; 397 418 } 398 [( GBChatlogHTMLConverter *)context endedElement:name empty:empty];419 [(AIXMLChatlogConverter *)context endedElement:name empty:empty]; 399 420 if(xmlType != NULL) 400 421 {