#import "LFApp.h"
static NSMutableArray *khash;
+static NSMutableArray *check_at_save;
static LFApp *app;
static NSString *roman[] = {@"I", @"II", @"III", @"IV", @"V", @"VI", @"VII", @"VIII", @"IX", @"X"};
static NSString *dep[] = {@"ミリ", @"キロ", @"センチ", @"メートル", @"グラム", @"トン", @"アール", @"ヘクタール",
@"I",@"II",@"III",@"IV",@"V"};
static NSString *symbols = @"㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㍾㍽㍼㍻№㏍℡㊤㊥㊦㊧㊨㈱㈲㈹∑";
-static NSStringEncoding LF_Encoding_ISO2022JP = kCFStringEncodingISO_2022_JP;
-static NSStringEncoding LF_Encoding_Auto = -1;
+static unsigned long long LF_Encoding_ISO2022JP = NSISO2022JPStringEncoding;
+static unsigned long long LF_Encoding_Auto = 0;
void swizzlingMethod(Class aClass, SEL aSelector, SEL nSelector, IMP nImplement) {
Method orig_method, alt_method;
//NSLog(@"Swizzling Method: Success.");
}
+static void backendSetPreferredEncoding(id backend, unsigned long long encoding)
+{
+ Ivar ivar = object_getInstanceVariable(backend, "_flags", NULL);
+ _LF_flags *_flags = (_LF_flags *)((char *)backend + ivar_getOffset(ivar));
+ _flags->encodingHint = encoding;
+
+ //[backend setPreferredEncoding:LF_Encoding_ISO2022JP];
+}
+
+static unsigned long long backendGetPreferredEncoding(id backend)
+{
+ Ivar ivar = object_getInstanceVariable(backend, "_flags", NULL);
+ _LF_flags *_flags = (_LF_flags *)((char *)backend + ivar_getOffset(ivar));
+ return _flags->encodingHint; //FIXME: [backend _encodingHint] return wrong value?
+
+ //return [backend preferredEncoding];
+}
+
int fixTextNode(DOMText *node, DOMRange *range, BOOL isCheck, BOOL isOpen)
{
int replaced = 0;
replaced++;
if (isOpen) { // 編集開始時
if ([app isOsDependentFix] == YES) {
- if (([app ver] == LF_Leopard || [app ver] == LF_MountainLion || [app ver] == LF_Mavericks) &&
- (loc = [dayOfWeek rangeOfString:us].location) != NSNotFound) {
+ if ((loc = [dayOfWeek rangeOfString:us].location) != NSNotFound) {
if ([app parenSymbolFix] == YES) {
if (((loc == 11)||(loc == 13)||(loc == 16)) &&
([app someParenSymbolNotFix] == YES)) {
NSString *us = [substr substringWithRange:NSMakeRange(i, 1)];
unichar uc = [us characterAtIndex:0];
switch (uc) {
- case 0x2014: // —
- case 0x301c: // 〜
- case 0x2016: // ‖
- case 0x2212: // −
- case 0x00a2: // ¢
- case 0x00a3: // £
- case 0x00ac: // ¬
- if ([app ver] >= LF_SnowLeopard) return TRUE;
- break;
case 0x2015: // ―
case 0xff5e: // ~
case 0x2225: // ∥
for (i = 0; i < [substr length]; i++) {
NSString *us = [substr substringWithRange:NSMakeRange(i, 1)];
if ([us canBeConvertedToEncoding:NSISO2022JPStringEncoding] != YES) {
- if ((([app ver] == LF_Leopard)||([app ver] == LF_MountainLion)||([app ver] == LF_Mavericks)) &&
- ([app isOsDependentFix] == YES) && ([app parenSymbolFix] == YES) &&
+ if (([app isOsDependentFix] == YES) && ([app parenSymbolFix] == YES) &&
((loc = [dayOfWeek rangeOfString:us].location) != NSNotFound) &&
([app someParenSymbolNotFix] == NO || (loc != 11 && loc != 13 && loc != 16))) {
return TRUE;
}
}
- }
+ }
return FALSE;
}
break;
default:
if ([us canBeConvertedToEncoding:NSISO2022JPStringEncoding] != YES) {
- if ((([app ver] == LF_Leopard)||([app ver] == LF_MountainLion)||([app ver] == LF_Mavericks)) &&
- ([app isOsDependentFix] == YES) && ([app parenSymbolFix] == YES) &&
+ if (([app isOsDependentFix] == YES) && ([app parenSymbolFix] == YES) &&
((loc = [dayOfWeek rangeOfString:us].location) != NSNotFound) &&
([app someParenSymbolNotFix] == NO || (loc != 11 && loc != 13 && loc != 16))) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1)
+ [substr replaceCharactersInRange:NSMakeRange(i, 1)
withString:[circledNumbers substringWithRange:NSMakeRange(loc, 1)]];
}
}
id headers = [self headersEditor];
NSTextField *subjectField = nil;
- if ([app ver] == LF_Leopard || [app ver] == LF_SnowLeopard) {
- object_getInstanceVariable(headers, "subjectField", (void **)&subjectField);
- } else if ([app ver] == LF_Lion || [app ver] == LF_MountainLion ||([app ver] == LF_Mavericks)) {
- object_getInstanceVariable(headers, "_subjectField", (void **)&subjectField);
- }
+ object_getInstanceVariable(headers, "_subjectField", (void **)&subjectField);
if (subjectField != nil)
[subjectField setStringValue:substr];
}
NSInteger loc;
switch (uc) {
- case 0x2015: // ―
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"—"];
- break;
- }
+ case 0x2015: // ―
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"—"];
+ break;
case 0xff5e: // ~
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"〜"];
- break;
- }
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"〜"];
+ break;
case 0xff0d: // -
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"−"];
- break;
- }
- case 0x2014: // —
- case 0x301c: // 〜
- case 0x2212: // −
- if ([app ver] >= LF_SnowLeopard)[substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"-"];
- break;
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"−"];
+ break;
case 0x2225: // ∥
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"‖"];
- break;
- }
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"‖"];
+ break;
case 0xffe0: // ¢
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"¢"];
- break;
- }
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"¢"];
+ break;
case 0xffe1: // £
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"£"];
- break;
- }
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"£"];
+ break;
case 0xffe2: // ¬
- if ([app ver] == LF_Leopard) {
- [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"¬"];
- break;
- }
- case 0x2016: // ‖
- case 0x00a2: // ¢
- case 0x00a3: // £
- case 0x00ac: // ¬
- if ([app ver] >= LF_SnowLeopard)[substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"〓"];
- break;
+ [substr replaceCharactersInRange:NSMakeRange(i, 1) withString:@"¬"];
+ break;
default:
if ([us canBeConvertedToEncoding:NSISO2022JPStringEncoding] != YES) {
if ((0x2460 <= uc && uc <= 0x2473) && ([app isOsDependentFix]==YES)) { // ①〜⑳ -> (1)〜(20)
id headers = [self headersEditor];
NSTextField *subjectField = nil;
- if ([app ver] == LF_Leopard || [app ver] == LF_SnowLeopard) {
- object_getInstanceVariable(headers, "subjectField", (void **)&subjectField);
- } else if ([app ver] == LF_Lion || [app ver] == LF_MountainLion||[app ver] == LF_Mavericks) {
- object_getInstanceVariable(headers, "_subjectField", (void **)&subjectField);
- }
+ object_getInstanceVariable(headers, "_subjectField", (void **)&subjectField);
if (subjectField != nil)
[subjectField setStringValue:substr];
}
return result;
}
- id backend = [self backEnd];
- if ([app changeEncode]==YES)
- [backend setPreferredEncoding:LF_Encoding_ISO2022JP];
+ //id backend = [self backEnd];
+ //backendSetPreferredEncoding(backend, LF_Encoding_ISO2022JP);
[khash addObject:self];
-
+
switch ([self messageType]) {
case 1: // 返信
case 2: // 全員に返信
NSLog(@"Unknown MessageType: %d", [self messageType]);
return result;
}
-
+
if (0 < fixLetter(self, [self webView], TRUE, TRUE) || checkSubjectOnLoad(self)) {
if ([app operationAtOpen] == 0) {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:@"変換しない"];
[alert setShowsSuppressionButton:TRUE];
[alert setMessageText:@"編集前にメッセージを変換しますか?"];
- [alert setInformativeText:@"このメッセージには ISO 2022-JP に変換できない文字が含まれています。"
- @"変換しない場合、エンコーディングを「自動」に設定します。"];
+ [alert setInformativeText:@"このメッセージには ISO 2022-JP に変換できない文字が含まれています。"];
[alert setAlertStyle:NSInformationalAlertStyle];
- [alert beginSheetModalForWindow:[self window] modalDelegate:self
- didEndSelector:@selector(_LF_alert0DidEnd:returnCode:contextInfo:)
+ [alert beginSheetModalForWindow:[self window] modalDelegate:self
+ didEndSelector:@selector(_LF_alert0DidEnd:returnCode:contextInfo:)
contextInfo:nil];
} else if ([app operationAtOpen] == 1) {
fixSubjectOnLoad(self);
fixLetter(self, [self webView], FALSE, TRUE);
//[[self backEnd] setHasChanges:FALSE];
} else if (returnCode == NSAlertSecondButtonReturn) {
- if (0 < fixLetter(self, [self webView], TRUE, TRUE))
- [[self backEnd] setPreferredEncoding:LF_Encoding_Auto];
}
if ([[alert suppressionButton] state] == NSOnState) {
if (returnCode == NSAlertFirstButtonReturn) {
void _LF_IMP_send_(id self, SEL _cmd, id arg1)
{
- if (([app isActive] != NO) && (0 < fixLetter(self, [self webView], TRUE, FALSE))) {
+ if ([app isActive] == NO) {
+ [self _LF_send: arg1];
+ return;
+ }
+
+ backendSetPreferredEncoding([self backEnd], LF_Encoding_ISO2022JP);
+ if (0 < fixLetter(self, [self webView], TRUE, FALSE)) {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:@"変換して送信"];
[alert addButtonWithTitle:@"キャンセル"];
[alert addButtonWithTitle:@"変換せずに送信"];
[alert addButtonWithTitle:@"変換のみ"];
[alert setMessageText:@"メッセージを変換して送信しますか?"];
- [alert setInformativeText:@"送信しようとしているメッセージには ISO 2022-JP に変換できない文字が含まれています。"
- @"ISO 2022-JP で送信するためには、これらの文字を変換可能なものに置き換える必要があります。\n"
- @"変換せずに送信する場合、エンコーディング設定を「自動」に設定の上送信します。"];
+ [alert setInformativeText:@"送信しようとしているメッセージには ISO 2022-JP に変換できない文字が含まれています。"];
[alert setAlertStyle:NSInformationalAlertStyle];
- [alert beginSheetModalForWindow:[self window]
- modalDelegate:self
- didEndSelector:@selector(_LF_alert1DidEnd:returnCode:contextInfo:)
+ [alert beginSheetModalForWindow:[self window]
+ modalDelegate:self
+ didEndSelector:@selector(_LF_alert1DidEnd:returnCode:contextInfo:)
contextInfo:arg1];
- } else if (([app isActive] != NO) && ([app isCheckSubject] != NO) && checkSubject(self)) {
+ } else if (([app isCheckSubject] != NO) && checkSubject(self)) {
_LF_alertSubject(self, _cmd, arg1);
} else {
[self _LF_send: arg1];
[alert addButtonWithTitle:@"変換せずに送信"];
[alert addButtonWithTitle:@"変換のみ"];
[alert setMessageText:@"件名に ISO 2022-JP に変換できない文字が含まれています"];
- [alert setInformativeText:@"送信するメッセージの件名に ISO 2022-JP に変換できない文字が含まれています。\n"
- @"なお Mail.app のバグにより、件名に本来は ISO 2022-JP に変換可能な一部の文字(—―−-〜~‖∥¢¢££¬¬)が含まれていると、"
- @"件名を UTF-8 の MIMEエンコードで送信します。そのため、これらの文字も置き換えて送信します。"];
+ [alert setInformativeText:@"送信するメッセージの件名に ISO 2022-JP に変換できない文字が含まれています。"];
[alert setAlertStyle:NSInformationalAlertStyle];
- [alert beginSheetModalForWindow:[self window]
- modalDelegate:self
+ [alert beginSheetModalForWindow:[self window]
+ modalDelegate:self
didEndSelector:@selector(_LF_alert3DidEnd:returnCode:contextInfo:)
contextInfo:arg1];
}
{
if (returnCode == NSAlertFirstButtonReturn) {
fixLetter(self, [self webView], FALSE, FALSE);
- if ([[self backEnd] preferredEncoding] != LF_Encoding_ISO2022JP) [[self backEnd] setPreferredEncoding:LF_Encoding_ISO2022JP];
+ if (backendGetPreferredEncoding([self backEnd]) != LF_Encoding_ISO2022JP) backendSetPreferredEncoding([self backEnd], LF_Encoding_ISO2022JP);
[[alert window] orderOut:arg1];
if (([app isCheckSubject] != NO) && checkSubject(self)) _LF_alertSubject(self, _cmd, arg1);
else [self _LF_send: arg1];
} else if (returnCode == NSAlertSecondButtonReturn) {
// Cancel
- } else if (returnCode == NSAlertThirdButtonReturn) {
- if ([[self backEnd] preferredEncoding] == LF_Encoding_ISO2022JP) [[self backEnd] setPreferredEncoding:LF_Encoding_Auto];
+ } else if (returnCode == NSAlertThirdButtonReturn) { // 変換せずに送信
+ if (backendGetPreferredEncoding([self backEnd]) == LF_Encoding_ISO2022JP) {
+ backendSetPreferredEncoding([self backEnd], LF_Encoding_Auto); // ISO2022JPのままだとISO2022JP-2とかで送ってしまう
+ }
[[alert window] orderOut:arg1];
[self _LF_send: arg1];
- } else if (returnCode == (NSAlertThirdButtonReturn + 1)) {
+ } else if (returnCode == (NSAlertThirdButtonReturn + 1)) { // 変換のみ
fixLetter(self, [self webView], FALSE, FALSE);
- if ([[self backEnd] preferredEncoding] != LF_Encoding_ISO2022JP) [[self backEnd] setPreferredEncoding:LF_Encoding_ISO2022JP];
+ if (backendGetPreferredEncoding([self backEnd]) != LF_Encoding_ISO2022JP) backendSetPreferredEncoding([self backEnd], LF_Encoding_ISO2022JP);
}
}
void _LF_IMP_saveDocument_(id self, SEL _cmd, id arg1)
{
- if (([app isActive] != NO) && (0 < fixLetter(self, [self webView], TRUE, FALSE)) && ([[self backEnd] preferredEncoding] == LF_Encoding_ISO2022JP)) {
+ if (([app isActive] != NO) && ([check_at_save containsObject:self]==NO) &&(0 < fixLetter(self, [self webView], TRUE, FALSE)) && (backendGetPreferredEncoding([self backEnd]) == LF_Encoding_ISO2022JP)) {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:@"変換"];
[alert addButtonWithTitle:@"変換しない"];
[alert setMessageText:@"保存前にメッセージを変換しますか?"];
- [alert setInformativeText:@"このメッセージには ISO 2022-JP エンコーディングに変換できない文字が含まれています。"
- @"ISO 2022-JP で保存するためには、これらの文字を変換可能なものに置き換える必要があります。\n"
- @"変換しない場合、保存のためエンコーディングの設定を「自動」に変更します。"];
+ [alert setInformativeText:@"このメッセージには ISO 2022-JP エンコーディングに変換できない文字が含まれています。\n"
+ @"変換しないを選択した場合、メールの送信またはウインドウを開き直すまでエンコーディングの確認を行いません。"];
[alert setAlertStyle:NSWarningAlertStyle];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(_LF_alert2DidEnd:returnCode:contextInfo:) contextInfo:arg1];
} else {
if (returnCode == NSAlertFirstButtonReturn) {
fixLetter(self, [self webView], FALSE, FALSE);
} else if (returnCode == NSAlertSecondButtonReturn) {
- [[self backEnd] setPreferredEncoding:LF_Encoding_Auto];
+ [check_at_save addObject:self];
}
[[alert window] orderOut:arg1];
[self _LF_saveDocument: (id)arg1];
}
-void _LF_IMP_closeConfirmSheetDidEnd_returnCode_forSave_(id self, SEL _cmd, id arg1, NSInteger arg2, void *arg3)
-{
- if (([app isActive] != NO) && (0 < fixLetter(self, [self webView], TRUE, FALSE)) && ([[self backEnd] preferredEncoding] == LF_Encoding_ISO2022JP) &&
- ((arg2 == NSAlertFirstButtonReturn)||(arg2 == NSAlertDefaultReturn))) {
- [[self backEnd] setPreferredEncoding:LF_Encoding_Auto]; // 保存の場合文字コードを自動に
- }
- [self _LF_closeConfirmSheetDidEnd:arg1 returnCode:arg2 forSave:arg3];
-}
-
void _LF_IMP_animationCompleted(id self, SEL _cmd)
{
[self performSelector:@selector(isLoaded) withObject:nil afterDelay:0.5];
[self _LF_animationCompleted];
}
-BOOL _LF_IMP_BackEnd_saveMessage(id self, SEL _cmd)
-{
- if (([app isActive] != NO) && ([self preferredEncoding] == LF_Encoding_ISO2022JP))
- [self setPreferredEncoding:LF_Encoding_Auto];
- return [self _LF_saveMessage];
-}
-
-#define MVMailBundle (NSClassFromString(@"MVMailBundle"))
+#define MVMailBundle (NSClassFromString(@"MVMailBundle"))
+#define LFDocumentEditor (NSClassFromString(@"DocumentEditor"))
@implementation LetterFix
+ (void) initialize
{
- Class LFDocumentEditor;
class_setSuperclass([self class], MVMailBundle); // depricated function 10.5対応のためこのワーニングだけは消せません
[super initialize];
[self registerBundle];
khash = [[NSMutableArray alloc] initWithCapacity:1];
+ check_at_save = [[NSMutableArray alloc] initWithCapacity:1];
app = [[LFApp alloc] init];
-
- if ([app ver] != LF_Mavericks) {
- LFDocumentEditor = NSClassFromString(@"MailDocumentEditor"); // hidden Mail.app class
- } else {
- LFDocumentEditor = NSClassFromString(@"DocumentEditor");
- LF_Encoding_ISO2022JP = 0x15;
- LF_Encoding_Auto = 0;
- }
+
//
// swizzling method
swizzlingMethod(LFDocumentEditor, @selector(isLoaded), @selector(_LF_isLoaded), (IMP)_LF_IMP_isLoaded);
swizzlingMethod(LFDocumentEditor, @selector(send:), @selector(_LF_send:), (IMP)_LF_IMP_send_);
swizzlingMethod(LFDocumentEditor, @selector(saveDocument:), @selector(_LF_saveDocument:), (IMP)_LF_IMP_saveDocument_);
- if ([app ver] == LF_Mavericks) {
- swizzlingMethod(NSClassFromString(@"ComposeBackEnd"), @selector(saveMessage), @selector(_LF_saveMessage), (IMP)_LF_IMP_BackEnd_saveMessage);
- } else {
- swizzlingMethod(LFDocumentEditor, @selector(closeConfirmSheetDidEnd:returnCode:forSave:),
- @selector(_LF_closeConfirmSheetDidEnd:returnCode:forSave:),
- (IMP)_LF_IMP_closeConfirmSheetDidEnd_returnCode_forSave_);
- }
- if (([app ver] == LF_Leopard)||([app ver] == LF_MountainLion)||([app ver] == LF_Mavericks)) {
- swizzlingMethod(LFDocumentEditor, @selector(_animationCompleted), @selector(_LF_animationCompleted), (IMP)_LF_IMP_animationCompleted);
- }
+ swizzlingMethod(LFDocumentEditor, @selector(_animationCompleted), @selector(_LF_animationCompleted), (IMP)_LF_IMP_animationCompleted);
class_addMethod(LFDocumentEditor, @selector(_LF_alert0DidEnd:returnCode:contextInfo:), (IMP)alert0DidEnd_returnCode_contextInfo_, "v@:@i^v");
class_addMethod(LFDocumentEditor, @selector(_LF_alert1DidEnd:returnCode:contextInfo:), (IMP)alert1DidEnd_returnCode_contextInfo_, "v@:@i^v");
class_addMethod(LFDocumentEditor, @selector(_LF_alert2DidEnd:returnCode:contextInfo:), (IMP)alert2DidEnd_returnCode_contextInfo_, "v@:@i^v");
// end of swizzling method
//
- NSLog(@"LetterFix Plugin (version %s/%lx) is registered.", LETTERFIX_VERSION, (unsigned long int)[app ver]);
+ NSLog(@"LetterFix Plugin (version %s/%ld) is registered.", LETTERFIX_VERSION, (unsigned long int)[app verm]);
}
@end
\ No newline at end of file