From f4b4a8eab2aedf918e36545ee67129619264a6be Mon Sep 17 00:00:00 2001 From: zonble Date: Mon, 30 Mar 2020 00:42:53 +0800 Subject: [PATCH 01/12] Add a GitHub actions flow. --- .../workflows/continuous-integration-workflow.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/continuous-integration-workflow.yml diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml new file mode 100644 index 00000000..dcf53039 --- /dev/null +++ b/.github/workflows/continuous-integration-workflow.yml @@ -0,0 +1,15 @@ +name: Build +on: [push] + +jobs: + build: + name: Build + runs-on: macOS-latest + env: + DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + steps: + - uses: actions/checkout@v1 + - name: Clean + run: xcodebuild -target McBopomofo -configuration Release clean + - name: Build + run: xcodebuild -target McBopomofo -configuration Release From f5d4b04e1b56a8fbf072bd33040b617589087b7b Mon Sep 17 00:00:00 2001 From: zonble Date: Mon, 30 Mar 2020 01:26:34 +0800 Subject: [PATCH 02/12] Update the plist file. --- Source/McBopomofo-Info.plist | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Source/McBopomofo-Info.plist b/Source/McBopomofo-Info.plist index c0d29f7a..9224bd47 100644 --- a/Source/McBopomofo-Info.plist +++ b/Source/McBopomofo-Info.plist @@ -28,6 +28,8 @@ org.openvanilla.inputmethod.McBopomofo.Bopomofo + TISDoubleSpaceSubstitution + tsInputModeAlternateMenuIconFileKey Bopomofo.tiff tsInputModeDefaultStateKey @@ -41,10 +43,21 @@ tsInputModePrimaryInScriptKey tsInputModeScriptKey - smUnicodeScript + smTradChinese + TISIntendedLanguage + zh-Hant + tsInputModeCharacterRepertoireKey + + Hant + Han + + tsInputModeKeyEquivalentModifiersKey + 4608 org.openvanilla.inputmethod.McBopomofo.PlainBopomofo + TISDoubleSpaceSubstitution + tsInputModeAlternateMenuIconFileKey PlainBopomofo.tiff tsInputModeDefaultStateKey @@ -58,7 +71,16 @@ tsInputModePrimaryInScriptKey tsInputModeScriptKey - smUnicodeScript + smTradChinese + TISIntendedLanguage + zh-Hant + tsInputModeCharacterRepertoireKey + + Hant + Han + + tsInputModeKeyEquivalentModifiersKey + 4608 tsVisibleInputModeOrderedArrayKey @@ -89,10 +111,14 @@ MainMenu NSPrincipalClass NSApplication + TICapsLockLanguageSwitchCapable + TISInputSourceID org.openvanilla.inputmethod.McBopomofo TISIntendedLanguage zh-Hant + TISParticipatesInTouchBar + UpdateInfoEndpoint https://mcbopomofo.openvanilla.org/updates/Info.plist UpdateInfoSite From aa8f36b92fc80109318fd4afc9d55b35b1edefd6 Mon Sep 17 00:00:00 2001 From: zonble Date: Mon, 21 Dec 2020 00:34:25 +0800 Subject: [PATCH 03/12] Updates CI settings. --- .github/workflows/continuous-integration-workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index dcf53039..065fb076 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -6,7 +6,7 @@ jobs: name: Build runs-on: macOS-latest env: - DEVELOPER_DIR: /Applications/Xcode_11.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_12.app/Contents/Developer steps: - uses: actions/checkout@v1 - name: Clean From 0f05e245a5d1c3413abbcbd718f9d6522db86963 Mon Sep 17 00:00:00 2001 From: zonble Date: Sun, 28 Feb 2021 21:30:10 +0800 Subject: [PATCH 04/12] Coverts to Objective-C ARC. --- McBopomofo.xcodeproj/project.pbxproj | 2 + .../xcschemes/McBopomofo.xcscheme | 78 +++++++++++++++++++ Source/AppDelegate.h | 3 +- Source/AppDelegate.m | 16 +--- Source/CandidateUI/VTCandidateController.h | 2 +- Source/CandidateUI/VTCandidateController.m | 14 ++-- .../VTHorizontalCandidateController.m | 9 +-- .../CandidateUI/VTHorizontalCandidateView.h | 2 +- .../CandidateUI/VTHorizontalCandidateView.m | 51 +++++------- .../VTVerticalCandidateController.m | 16 +--- .../CandidateUI/VTVerticalKeyLabelStripView.m | 7 +- Source/InputMethodController.mm | 21 +++-- Source/OVInputSourceHelper.m | 18 ++--- Source/OVNonModalAlertWindowController.h | 10 +-- Source/PreferencesWindowController.h | 8 +- Source/PreferencesWindowController.m | 6 +- Source/main.m | 12 +-- 17 files changed, 154 insertions(+), 121 deletions(-) create mode 100644 McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofo.xcscheme diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index 72c1d809..bd16df99 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -821,6 +821,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_IMPLICIT_SIGN_CONVERSION = NO; @@ -872,6 +873,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_IMPLICIT_SIGN_CONVERSION = NO; diff --git a/McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofo.xcscheme b/McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofo.xcscheme new file mode 100644 index 00000000..56d01ed8 --- /dev/null +++ b/McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofo.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/AppDelegate.h b/Source/AppDelegate.h index 56778c6d..96ee6e0c 100644 --- a/Source/AppDelegate.h +++ b/Source/AppDelegate.h @@ -39,7 +39,6 @@ @interface AppDelegate : NSObject { @private - NSWindow *_window; NSURLConnection *_updateCheckConnection; BOOL _currentUpdateCheckIsForced; NSMutableData *_receivingData; @@ -51,5 +50,5 @@ - (void)checkForUpdateForced:(BOOL)forced; - (void)showPreferences; -@property (assign, nonatomic) IBOutlet NSWindow *window; +@property (weak, nonatomic) IBOutlet NSWindow *window; @end diff --git a/Source/AppDelegate.m b/Source/AppDelegate.m index 409d9d84..cc6b896c 100644 --- a/Source/AppDelegate.m +++ b/Source/AppDelegate.m @@ -53,9 +53,8 @@ static const NSTimeInterval kTimeoutInterval = 60.0; - (void)dealloc { - [_preferencesWindowController release]; - [_updateCheckConnection release]; - [super dealloc]; + _preferencesWindowController = nil; + _updateCheckConnection = nil; } - (void)applicationDidFinishLaunching:(NSNotification *)inNotification @@ -124,7 +123,6 @@ static const NSTimeInterval kTimeoutInterval = 60.0; #endif if (_receivingData) { - [_receivingData release]; _receivingData = nil; } @@ -147,9 +145,7 @@ static const NSTimeInterval kTimeoutInterval = 60.0; { BOOL isForcedCheck = _currentUpdateCheckIsForced; - [_receivingData release]; _receivingData = nil; - [_updateCheckConnection release]; _updateCheckConnection = nil; _currentUpdateCheckIsForced = NO; @@ -172,9 +168,7 @@ static const NSTimeInterval kTimeoutInterval = 60.0; BOOL isForcedCheck = _currentUpdateCheckIsForced; - [_receivingData release]; _receivingData = nil; - [_updateCheckConnection release]; _updateCheckConnection = nil; _currentUpdateCheckIsForced = NO; @@ -226,9 +220,7 @@ static const NSTimeInterval kTimeoutInterval = 60.0; } return; } - [_updateNextStepURL release]; - _updateNextStepURL = nil; - _updateNextStepURL = [siteInfoURL retain]; + _updateNextStepURL = siteInfoURL; NSDictionary *versionDescriptions = [plist objectForKey:@"Description"]; NSString *versionDescription = @""; @@ -268,13 +260,11 @@ static const NSTimeInterval kTimeoutInterval = 60.0; [[NSWorkspace sharedWorkspace] openURL:_updateNextStepURL]; } - [_updateNextStepURL release]; _updateNextStepURL = nil; } - (void)nonModalAlertWindowControllerDidCancel:(OVNonModalAlertWindowController *)controller { - [_updateNextStepURL release]; _updateNextStepURL = nil; } diff --git a/Source/CandidateUI/VTCandidateController.h b/Source/CandidateUI/VTCandidateController.h index 2518f1bb..41e36a5c 100644 --- a/Source/CandidateUI/VTCandidateController.h +++ b/Source/CandidateUI/VTCandidateController.h @@ -56,7 +56,7 @@ - (NSUInteger)candidateIndexAtKeyLabelIndex:(NSUInteger)index; -@property (assign, weak, nonatomic) id delegate; +@property (weak, nonatomic) id delegate; @property (assign, nonatomic) NSUInteger selectedCandidateIndex; @property (assign, nonatomic) BOOL visible; diff --git a/Source/CandidateUI/VTCandidateController.m b/Source/CandidateUI/VTCandidateController.m index c7db63d9..5605ff71 100644 --- a/Source/CandidateUI/VTCandidateController.m +++ b/Source/CandidateUI/VTCandidateController.m @@ -36,10 +36,9 @@ - (void)dealloc { - [_keyLabels release]; - [_keyLabelFont release]; - [_candidateFont release]; - [super dealloc]; + _keyLabels = nil; + _keyLabelFont = nil; + _candidateFont = nil; } - (id)initWithWindow:(NSWindow *)window @@ -47,11 +46,10 @@ self = [super initWithWindow:window]; if (self) { // populate the default values - _keyLabels = [[NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", nil] retain]; - _keyLabelFont = [[NSFont systemFontOfSize:14.0] retain]; - _candidateFont = [[NSFont systemFontOfSize:18.0] retain]; + _keyLabels = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9"]; + _keyLabelFont = [NSFont systemFontOfSize:14.0]; + _candidateFont = [NSFont systemFontOfSize:18.0]; } - return self; } diff --git a/Source/CandidateUI/VTHorizontalCandidateController.m b/Source/CandidateUI/VTHorizontalCandidateController.m index f69affdd..4cc8795b 100644 --- a/Source/CandidateUI/VTHorizontalCandidateController.m +++ b/Source/CandidateUI/VTHorizontalCandidateController.m @@ -40,10 +40,9 @@ - (void)dealloc { - [_candidateView release]; - [_prevPageButton release]; - [_nextPageButton release]; - [super dealloc]; + _candidateView = nil; + _prevPageButton = nil; + _nextPageButton = nil; } - (id)init @@ -51,7 +50,7 @@ NSRect contentRect = NSMakeRect(128.0, 128.0, 0.0, 0.0); NSUInteger styleMask = NSBorderlessWindowMask | NSNonactivatingPanelMask; - NSPanel *panel = [[[NSPanel alloc] initWithContentRect:contentRect styleMask:styleMask backing:NSBackingStoreBuffered defer:NO] autorelease]; + NSPanel *panel = [[NSPanel alloc] initWithContentRect:contentRect styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; [panel setLevel:kCGPopUpMenuWindowLevel]; [panel setHasShadow:YES]; diff --git a/Source/CandidateUI/VTHorizontalCandidateView.h b/Source/CandidateUI/VTHorizontalCandidateView.h index c5295503..492b7c5c 100644 --- a/Source/CandidateUI/VTHorizontalCandidateView.h +++ b/Source/CandidateUI/VTHorizontalCandidateView.h @@ -50,5 +50,5 @@ @property (readonly, nonatomic) NSSize sizeForView; @property (assign, nonatomic) NSUInteger highlightedIndex; @property (assign, nonatomic) SEL action; -@property (weak, assign, nonatomic) id target; +@property (weak, nonatomic) id target; @end diff --git a/Source/CandidateUI/VTHorizontalCandidateView.m b/Source/CandidateUI/VTHorizontalCandidateView.m index 461ecc10..d24122f5 100644 --- a/Source/CandidateUI/VTHorizontalCandidateView.m +++ b/Source/CandidateUI/VTHorizontalCandidateView.m @@ -39,26 +39,18 @@ NS_INLINE CGFloat max(CGFloat a, CGFloat b) { return a > b ? a : b; } - (void)dealloc { - [_keyLabels release]; - [_displayedCandidates release]; - [_keyLabelAttrDict release]; - [_candidateAttrDict release]; - [_elementWidths release]; - [super dealloc]; + _keyLabels = nil; + _displayedCandidates = nil; + _keyLabelAttrDict = nil; + _candidateAttrDict = nil; + _elementWidths = nil; } - (void)setKeyLabels:(NSArray *)labels displayedCandidates:(NSArray *)candidates { NSUInteger count = min([labels count], [candidates count]); - id tmp; - - tmp = _keyLabels; - _keyLabels = [[labels subarrayWithRange:NSMakeRange(0, count)] retain]; - [tmp release]; - - tmp = _displayedCandidates; - _displayedCandidates = [[candidates subarrayWithRange:NSMakeRange(0, count)] retain]; - [tmp release]; + _keyLabels = [labels subarrayWithRange:NSMakeRange(0, count)]; + _displayedCandidates = [candidates subarrayWithRange:NSMakeRange(0, count)]; NSMutableArray *newWidths = [NSMutableArray array]; @@ -71,33 +63,25 @@ NS_INLINE CGFloat max(CGFloat a, CGFloat b) { return a > b ? a : b; } CGFloat width = max(labelRect.size.width, candidateRect.size.width) + _cellPadding; [newWidths addObject:[NSNumber numberWithDouble:width]]; } - - tmp = _elementWidths; - _elementWidths = [newWidths retain]; - [tmp release]; + + _elementWidths = newWidths; } - (void)setKeyLabelFont:(NSFont *)labelFont candidateFont:(NSFont *)candidateFont { - NSMutableParagraphStyle *paraStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; + NSMutableParagraphStyle *paraStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [paraStyle setAlignment:NSCenterTextAlignment]; - - id tmp; - tmp = _keyLabelAttrDict; - _keyLabelAttrDict = [[NSDictionary dictionaryWithObjectsAndKeys: + + _keyLabelAttrDict = [NSDictionary dictionaryWithObjectsAndKeys: labelFont, NSFontAttributeName, paraStyle, NSParagraphStyleAttributeName, [NSColor blackColor], NSForegroundColorAttributeName, - nil] retain]; - [tmp release]; - - tmp = _candidateAttrDict; - _candidateAttrDict = [[NSDictionary dictionaryWithObjectsAndKeys: + nil]; + _candidateAttrDict = [NSDictionary dictionaryWithObjectsAndKeys: candidateFont, NSFontAttributeName, paraStyle, NSParagraphStyleAttributeName, [NSColor textColor], NSForegroundColorAttributeName, - nil] retain]; - [tmp release]; + nil]; CGFloat labelFontSize = [labelFont pointSize]; CGFloat candidateFontSize = [candidateFont pointSize]; @@ -165,7 +149,7 @@ NS_INLINE CGFloat max(CGFloat a, CGFloat b) { return a > b ? a : b; } if (index == _highlightedIndex) { [[NSColor selectedTextBackgroundColor] setFill]; - activeCandidateAttr = [[_candidateAttrDict mutableCopy] autorelease]; + activeCandidateAttr = [_candidateAttrDict mutableCopy]; [(NSMutableDictionary *)activeCandidateAttr setObject:[NSColor selectedTextColor] forKey:NSForegroundColorAttributeName]; } else { @@ -230,9 +214,12 @@ NS_INLINE CGFloat max(CGFloat a, CGFloat b) { return a > b ? a : b; } _trackingHighlightedIndex = 0; [self setNeedsDisplay:YES]; +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Warc-performSelector-leaks" if (triggerAction && _target && _action) { [_target performSelector:_action withObject:self]; } +# pragma clang diagnostic pop } @end diff --git a/Source/CandidateUI/VTVerticalCandidateController.m b/Source/CandidateUI/VTVerticalCandidateController.m index 03e555cf..7150d45b 100644 --- a/Source/CandidateUI/VTVerticalCandidateController.m +++ b/Source/CandidateUI/VTVerticalCandidateController.m @@ -57,21 +57,13 @@ static const CGFloat kCandidateTextLeftMarginWithMandatedTableViewPadding = 0.0; CGFloat _candidateTextLeftMargin; } -- (void)dealloc -{ - [_candidateTextParagraphStyle release]; - [_keyLabelStripView release]; - [_scrollView release]; - [_tableView release]; - [super dealloc]; -} - (id)init { NSRect contentRect = NSMakeRect(128.0, 128.0, 0.0, 0.0); NSUInteger styleMask = NSBorderlessWindowMask | NSNonactivatingPanelMask; - NSPanel *panel = [[[NSPanel alloc] initWithContentRect:contentRect styleMask:styleMask backing:NSBackingStoreBuffered defer:NO] autorelease]; + NSPanel *panel = [[NSPanel alloc] initWithContentRect:contentRect styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; [panel setLevel:kCGPopUpMenuWindowLevel]; [panel setHasShadow:YES]; @@ -100,8 +92,8 @@ static const CGFloat kCandidateTextLeftMarginWithMandatedTableViewPadding = 0.0; [_tableView setDataSource:self]; [_tableView setDelegate:self]; - NSTableColumn *column = [[[NSTableColumn alloc] initWithIdentifier:@"candidate"] autorelease]; - [column setDataCell:[[[NSTextFieldCell alloc] init] autorelease]]; + NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:@"candidate"]; + [column setDataCell:[[NSTextFieldCell alloc] init]]; [column setEditable:NO]; _candidateTextPadding = kCandidateTextPadding; @@ -238,7 +230,7 @@ static const CGFloat kCandidateTextLeftMarginWithMandatedTableViewPadding = 0.0; candidate = [_delegate candidateController:self candidateAtIndex:row]; } - NSAttributedString *attrString = [[[NSAttributedString alloc] initWithString:candidate attributes:[NSDictionary dictionaryWithObjectsAndKeys:_candidateFont, NSFontAttributeName, _candidateTextParagraphStyle, NSParagraphStyleAttributeName, nil]] autorelease]; + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:candidate attributes:[NSDictionary dictionaryWithObjectsAndKeys:_candidateFont, NSFontAttributeName, _candidateTextParagraphStyle, NSParagraphStyleAttributeName, nil]]; // we do more work than what this method is expected to; normally not a good practice, but for the amount of data (9 to 10 rows max), we can afford the overhead diff --git a/Source/CandidateUI/VTVerticalKeyLabelStripView.m b/Source/CandidateUI/VTVerticalKeyLabelStripView.m index b6514421..1a7d2a19 100644 --- a/Source/CandidateUI/VTVerticalKeyLabelStripView.m +++ b/Source/CandidateUI/VTVerticalKeyLabelStripView.m @@ -35,9 +35,8 @@ - (void)dealloc { - [_keyLabelFont release]; - [_keyLabels release]; - [super dealloc]; + _keyLabelFont = nil; + _keyLabels = nil; } - (id)initWithFrame:(NSRect)frameRect @@ -71,7 +70,7 @@ NSColor *darkGray = [NSColor colorWithDeviceWhite:0.7 alpha:1.0]; NSColor *lightGray = [NSColor colorWithDeviceWhite:0.8 alpha:1.0]; - NSMutableParagraphStyle *style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; + NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [style setAlignment:NSCenterTextAlignment]; NSDictionary *textAttr = [NSDictionary dictionaryWithObjectsAndKeys: diff --git a/Source/InputMethodController.mm b/Source/InputMethodController.mm index de92a3b5..052ff8b0 100644 --- a/Source/InputMethodController.mm +++ b/Source/InputMethodController.mm @@ -160,14 +160,11 @@ public: delete _builder; } - [_composingBuffer release]; - [_candidates release]; // the two client pointers are weak pointers (i.e. we don't retain them) // therefore we don't do anything about it - [super dealloc]; } - (id)initWithServer:(IMKServer *)server delegate:(id)delegate client:(id)client @@ -206,8 +203,8 @@ public: - (NSMenu *)menu { // a menu instance (autoreleased) is requested every time the user click on the input menu - NSMenu *menu = [[[NSMenu alloc] initWithTitle:LocalizationNotNeeded(@"Input Method Menu")] autorelease]; - NSMenuItem *preferenceMenuItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"McBopomofo Preferences", @"") action:@selector(showPreferences:) keyEquivalent:@""] autorelease]; + NSMenu *menu = [[NSMenu alloc] initWithTitle:LocalizationNotNeeded(@"Input Method Menu")]; + NSMenuItem *preferenceMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"McBopomofo Preferences", @"") action:@selector(showPreferences:) keyEquivalent:@""]; [menu addItem:preferenceMenuItem]; // If Option key is pressed, show the learning-related menu @@ -218,7 +215,7 @@ public: BOOL learningEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:kDisableUserCandidateSelectionLearning]; - NSMenuItem *learnMenuItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Enable Selection Learning", @"") action:@selector(toggleLearning:) keyEquivalent:@""] autorelease]; + NSMenuItem *learnMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Enable Selection Learning", @"") action:@selector(toggleLearning:) keyEquivalent:@""]; if (learningEnabled) { [learnMenuItem setState:NSOnState]; } @@ -230,20 +227,20 @@ public: if (learningEnabled) { NSString *clearMenuItemTitle = [NSString stringWithFormat:NSLocalizedString(@"Clear Learning Dictionary (%ju Items)", @""), (uintmax_t)[gCandidateLearningDictionary count]]; - NSMenuItem *clearMenuItem = [[[NSMenuItem alloc] initWithTitle:clearMenuItemTitle action:@selector(clearLearningDictionary:) keyEquivalent:@""] autorelease]; + NSMenuItem *clearMenuItem = [[NSMenuItem alloc] initWithTitle:clearMenuItemTitle action:@selector(clearLearningDictionary:) keyEquivalent:@""]; [menu addItem:clearMenuItem]; - NSMenuItem *dumpMenuItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Dump Learning Data to Console", @"") action:@selector(dumpLearningDictionary:) keyEquivalent:@""] autorelease]; + NSMenuItem *dumpMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Dump Learning Data to Console", @"") action:@selector(dumpLearningDictionary:) keyEquivalent:@""]; [menu addItem:dumpMenuItem]; } } #endif //DEBUG - NSMenuItem *updateCheckItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Check for Updates…", @"") action:@selector(checkForUpdate:) keyEquivalent:@""] autorelease]; + NSMenuItem *updateCheckItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Check for Updates…", @"") action:@selector(checkForUpdate:) keyEquivalent:@""]; [menu addItem:updateCheckItem]; - NSMenuItem *aboutMenuItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"About McBopomofo…", @"") action:@selector(showAbout:) keyEquivalent:@""] autorelease]; + NSMenuItem *aboutMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"About McBopomofo…", @"") action:@selector(showAbout:) keyEquivalent:@""]; [menu addItem:aboutMenuItem]; return menu; @@ -464,7 +461,7 @@ public: NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:NSUnderlineStyleSingle], NSUnderlineStyleAttributeName, [NSNumber numberWithInt:0], NSMarkedClauseSegmentAttributeName, nil]; - NSMutableAttributedString *attrString = [[[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict] autorelease]; + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict]; // the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound, // i.e. the client app needs to take care of where to put ths composing buffer @@ -1540,7 +1537,7 @@ void LTLoadLanguageModel() // TODO: Change this NSString *userDictFile = [userDictPath stringByAppendingPathComponent:@"UserCandidatesCache.plist"]; - gUserCandidatesDictionaryPath = [userDictFile retain]; + gUserCandidatesDictionaryPath = userDictFile; exists = [[NSFileManager defaultManager] fileExistsAtPath:userDictFile isDirectory:&isDir]; if (exists && !isDir) { diff --git a/Source/OVInputSourceHelper.m b/Source/OVInputSourceHelper.m index 33ffe703..d9815879 100644 --- a/Source/OVInputSourceHelper.m +++ b/Source/OVInputSourceHelper.m @@ -31,7 +31,8 @@ + (NSArray *)allInstalledInputSources { CFArrayRef list = TISCreateInputSourceList(NULL, true); - return [NSMakeCollectable(list) autorelease]; + return (__bridge NSArray *)list; +// return [NSMakeCollectable(list) autorelease]; } + (TISInputSourceRef)inputSourceForProperty:(CFStringRef)inPropertyKey stringValue:(NSString *)inValue @@ -39,16 +40,15 @@ CFTypeID stringID = CFStringGetTypeID(); for (id source in [self allInstalledInputSources]) { - CFTypeRef property = TISGetInputSourceProperty((TISInputSourceRef)source, inPropertyKey); + CFTypeRef property = TISGetInputSourceProperty((__bridge TISInputSourceRef)source, inPropertyKey); if (!property || CFGetTypeID(property) != stringID) { continue; } - if (inValue && [inValue compare:(NSString *)property] == NSOrderedSame) { - return (TISInputSourceRef)source; + if (inValue && [inValue compare:(__bridge NSString *)property] == NSOrderedSame) { + return (__bridge TISInputSourceRef)source; } } - return NULL; } @@ -74,9 +74,9 @@ BOOL enabled = NO; for (id source in [self allInstalledInputSources]) { - TISInputSourceRef inputSource = (TISInputSourceRef)source; - NSString *bundleID = (NSString *)TISGetInputSourceProperty(inputSource, kTISPropertyBundleID); - NSString *mode = (NSString *)TISGetInputSourceProperty(inputSource, kTISPropertyInputModeID); + TISInputSourceRef inputSource = (__bridge TISInputSourceRef)source; + NSString *bundleID = (__bridge NSString *)TISGetInputSourceProperty(inputSource, kTISPropertyBundleID); + NSString *mode = (NSString *)CFBridgingRelease(TISGetInputSourceProperty(inputSource, kTISPropertyInputModeID)); if (mode && [bundleID isEqualToString:inID]) { BOOL modeEnabled = [self enableInputSource:inputSource]; if (!modeEnabled) { @@ -98,7 +98,7 @@ + (BOOL)registerInputSource:(NSURL *)inBundleURL { - OSStatus status = TISRegisterInputSource((CFURLRef)inBundleURL); + OSStatus status = TISRegisterInputSource((__bridge CFURLRef)inBundleURL); return status == noErr; } @end diff --git a/Source/OVNonModalAlertWindowController.h b/Source/OVNonModalAlertWindowController.h index 6ca4902b..91453cb8 100644 --- a/Source/OVNonModalAlertWindowController.h +++ b/Source/OVNonModalAlertWindowController.h @@ -20,11 +20,11 @@ @interface OVNonModalAlertWindowController : NSWindowController { @private - NSTextField *_titleTextField; - NSTextField *_contentTextField; - NSButton *_confirmButton; - NSButton *_cancelButton; - id _delegate; +// NSTextField *_titleTextField; +// NSTextField *_contentTextField; +// NSButton *_confirmButton; +// NSButton *_cancelButton; +// id _delegate; } + (OVNonModalAlertWindowController *)sharedInstance; diff --git a/Source/PreferencesWindowController.h b/Source/PreferencesWindowController.h index 7ca3afd7..345ea254 100644 --- a/Source/PreferencesWindowController.h +++ b/Source/PreferencesWindowController.h @@ -36,10 +36,10 @@ @interface PreferencesWindowController : NSWindowController { @private - NSPopUpButton *_fontSizePopUpButton; - NSPopUpButton *_basisKeyboardLayoutButton; + NSPopUpButton *__weak _fontSizePopUpButton; + NSPopUpButton *__weak _basisKeyboardLayoutButton; } - (IBAction)updateBasisKeyboardLayoutAction:(id)sender; -@property (assign, nonatomic) IBOutlet NSPopUpButton *fontSizePopUpButton; -@property (assign, nonatomic) IBOutlet NSPopUpButton *basisKeyboardLayoutButton; +@property (weak, nonatomic) IBOutlet NSPopUpButton *fontSizePopUpButton; +@property (weak, nonatomic) IBOutlet NSPopUpButton *basisKeyboardLayoutButton; @end diff --git a/Source/PreferencesWindowController.m b/Source/PreferencesWindowController.m index 8fc7a134..668bfb54 100644 --- a/Source/PreferencesWindowController.m +++ b/Source/PreferencesWindowController.m @@ -68,10 +68,10 @@ static NSString *const kBasisKeyboardLayoutPreferenceKey = @"BasisKeyboardLayout continue; } - NSString *sourceID = (NSString *)TISGetInputSourceProperty(source, kTISPropertyInputSourceID); - NSString *localizedName = (NSString *)TISGetInputSourceProperty(source, kTISPropertyLocalizedName); + NSString *sourceID = (__bridge NSString *)TISGetInputSourceProperty(source, kTISPropertyInputSourceID); + NSString *localizedName = (__bridge NSString *)TISGetInputSourceProperty(source, kTISPropertyLocalizedName); - NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease]; + NSMenuItem *item = [[NSMenuItem alloc] init]; [item setTitle:localizedName]; [item setRepresentedObject:sourceID]; diff --git a/Source/main.m b/Source/main.m index 3920834f..bca49bd0 100644 --- a/Source/main.m +++ b/Source/main.m @@ -39,7 +39,7 @@ static NSString *const kConnectionName = @"McBopomofo_1_Connection"; int main(int argc, char *argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + @autoreleasepool { // register and enable the input source (along with all its input modes) if (argc > 1 && !strcmp(argv[1], "install")) { @@ -64,7 +64,6 @@ int main(int argc, char *argv[]) if (!status) { NSLog(@"Fatal error: Cannot register input source %@ at %@.", bundleID, [bundleURL absoluteString]); - [pool drain]; return -1; } @@ -72,7 +71,6 @@ int main(int argc, char *argv[]) // if it still doesn't register successfully, bail. if (!inputSource) { NSLog(@"Fatal error: Cannot find input source %@ after registration.", bundleID); - [pool drain]; return -1; } } @@ -84,12 +82,10 @@ int main(int argc, char *argv[]) if (!status) { NSLog(@"Fatal error: Cannot enable input source %@.", bundleID); - [pool drain]; return -1; } if (![OVInputSourceHelper inputSourceEnabled:inputSource]){ NSLog(@"Fatal error: Cannot enable input source %@.", bundleID); - [pool drain]; return -1; } } @@ -110,26 +106,22 @@ int main(int argc, char *argv[]) NSString *mainNibName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"NSMainNibFile"]; if (!mainNibName) { NSLog(@"Fatal error: NSMainNibFile key not defined in Info.plist."); - [pool drain]; return -1; } BOOL loadResult = [[NSBundle mainBundle] loadNibNamed:mainNibName owner:[NSApplication sharedApplication] topLevelObjects:NULL]; if (!loadResult) { NSLog(@"Fatal error: Cannot load %@.", mainNibName); - [pool drain]; return -1; } IMKServer *server = [[IMKServer alloc] initWithName:kConnectionName bundleIdentifier:[[NSBundle mainBundle] bundleIdentifier]]; if (!server) { NSLog(@"Fatal error: Cannot initialize input method server with connection %@.", kConnectionName); - [pool drain]; return -1; } [[NSApplication sharedApplication] run]; - [server release]; - [pool drain]; + } return 0; } From 6341270696e2361f5860bd5851fab07c2c86ab2c Mon Sep 17 00:00:00 2001 From: zonble Date: Sun, 28 Feb 2021 21:38:59 +0800 Subject: [PATCH 05/12] Coverts to Objective-C ARC. --- McBopomofo.xcodeproj/project.pbxproj | 2 + .../xcschemes/McBopomofoInstaller.xcscheme | 78 +++++++++++++++++++ Source/Installer/AppDelegate.h | 20 ++--- Source/Installer/AppDelegate.m | 17 +--- Source/Installer/ArchiveUtil.m | 12 +-- 5 files changed, 98 insertions(+), 31 deletions(-) create mode 100644 McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofoInstaller.xcscheme diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index bd16df99..f80b6d62 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -975,6 +975,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -1012,6 +1013,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; diff --git a/McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofoInstaller.xcscheme b/McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofoInstaller.xcscheme new file mode 100644 index 00000000..e47539ec --- /dev/null +++ b/McBopomofo.xcodeproj/xcshareddata/xcschemes/McBopomofoInstaller.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Installer/AppDelegate.h b/Source/Installer/AppDelegate.h index ebcf8b69..32b4936f 100644 --- a/Source/Installer/AppDelegate.h +++ b/Source/Installer/AppDelegate.h @@ -34,20 +34,20 @@ ArchiveUtil *_archiveUtil; NSString *_installingVersion; BOOL _upgrading; - NSButton *_installButton; - NSButton *_cancelButton; - NSTextView *_textView; - NSWindow *_progressSheet; - NSProgressIndicator *_progressIndicator; + NSButton *__weak _installButton; + NSButton *__weak _cancelButton; + NSTextView *__unsafe_unretained _textView; + NSWindow *__weak _progressSheet; + NSProgressIndicator *__weak _progressIndicator; NSDate *_translocationRemovalStartTime; NSInteger _currentVersionNumber; } - (IBAction)agreeAndInstallAction:(id)sender; - (IBAction)cancelAction:(id)sender; -@property (assign) IBOutlet NSButton *installButton; -@property (assign) IBOutlet NSButton *cancelButton; -@property (assign) IBOutlet NSTextView *textView; -@property (assign) IBOutlet NSWindow *progressSheet; -@property (assign) IBOutlet NSProgressIndicator *progressIndicator; +@property (weak) IBOutlet NSButton *installButton; +@property (weak) IBOutlet NSButton *cancelButton; +@property (unsafe_unretained) IBOutlet NSTextView *textView; +@property (weak) IBOutlet NSWindow *progressSheet; +@property (weak) IBOutlet NSProgressIndicator *progressIndicator; @end diff --git a/Source/Installer/AppDelegate.m b/Source/Installer/AppDelegate.m index 34887222..435e2c37 100644 --- a/Source/Installer/AppDelegate.m +++ b/Source/Installer/AppDelegate.m @@ -46,7 +46,6 @@ void RunAlertPanel(NSString *title, NSString *message, NSString *buttonTitle) { [alert setInformativeText:message]; [alert addButtonWithTitle:buttonTitle]; [alert runModal]; - [alert autorelease]; } @implementation AppDelegate @@ -56,17 +55,10 @@ void RunAlertPanel(NSString *title, NSString *message, NSString *buttonTitle) { @synthesize progressSheet = _progressSheet; @synthesize progressIndicator = _progressIndicator; -- (void)dealloc -{ - [_archiveUtil release]; - [_installingVersion release]; - [_translocationRemovalStartTime release]; - [super dealloc]; -} - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - _installingVersion = [[[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleVersionKey] retain]; + _installingVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleVersionKey]; NSString *versionString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; _archiveUtil = [[ArchiveUtil alloc] initWithAppName:kTargetBin targetAppBundleName:kTargetBundle]; @@ -76,9 +68,9 @@ void RunAlertPanel(NSString *title, NSString *message, NSString *buttonTitle) { [self.installButton setNextKeyView:self.cancelButton]; [[self window] setDefaultButtonCell:[self.installButton cell]]; - NSAttributedString *attrStr = [[[NSAttributedString alloc] initWithRTF:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"License" ofType:@"rtf"]] documentAttributes:NULL] autorelease]; + NSAttributedString *attrStr = [[NSAttributedString alloc] initWithRTF:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"License" ofType:@"rtf"]] documentAttributes:NULL]; - NSMutableAttributedString *mutableAttrStr = [[attrStr mutableCopy] autorelease]; + NSMutableAttributedString *mutableAttrStr = [attrStr mutableCopy]; [mutableAttrStr addAttribute:NSForegroundColorAttributeName value:[NSColor controlTextColor] range:NSMakeRange(0, [mutableAttrStr length])]; [[self.textView textStorage] setAttributedString:mutableAttrStr]; [self.textView setSelectedRange:NSMakeRange(0, 0)]; @@ -145,8 +137,7 @@ void RunAlertPanel(NSString *title, NSString *message, NSString *buttonTitle) { }); }]; - [_translocationRemovalStartTime release]; - _translocationRemovalStartTime = [[NSDate date] retain]; + _translocationRemovalStartTime = [NSDate date]; [NSTimer scheduledTimerWithTimeInterval:kTranslocationRemovalTickInterval target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; return; } diff --git a/Source/Installer/ArchiveUtil.m b/Source/Installer/ArchiveUtil.m index 2cd15003..90d47e35 100644 --- a/Source/Installer/ArchiveUtil.m +++ b/Source/Installer/ArchiveUtil.m @@ -28,16 +28,15 @@ targetAppBundleName:(NSString *)targetAppBundleName { self = [super init]; if (self) { - _appName = [name retain]; - _targetAppBundleName = [targetAppBundleName retain]; + _appName = name; + _targetAppBundleName = targetAppBundleName; } return self; } - (void)delloc { - [_appName release]; - [_targetAppBundleName release]; - [super dealloc]; + _appName = nil; + _targetAppBundleName = nil; } - (BOOL)validateIfNotarizedArchiveExists { @@ -67,7 +66,6 @@ devModeAppBundleExists]]; [alert addButtonWithTitle:@"Terminate"]; [alert runModal]; - [alert autorelease]; [[NSApplication sharedApplication] terminate:nil]; } else { @@ -84,8 +82,6 @@ devModeAppBundlePath]]; [alert addButtonWithTitle:@"Terminate"]; [alert runModal]; - [alert autorelease]; - [[NSApplication sharedApplication] terminate:nil]; } From 4e27b5ecfa5946e723a079f8abcf867eca172735 Mon Sep 17 00:00:00 2001 From: zonble Date: Sun, 28 Feb 2021 22:45:36 +0800 Subject: [PATCH 06/12] Adopts modern Objective-C syntax. --- .gitignore | 1 + Source/InputMethodController.mm | 13 ++----- Source/OVNonModalAlertWindowController.m | 48 ++++++++++++------------ Source/PreferencesWindowController.m | 8 ++-- 4 files changed, 32 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 9ee091e3..3160b584 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ Credits.rtf # the executable we used to count the occurance of a string in a file # that can be built by make -C Source/Data/bin/C_Version # C_count.occ.exe +.idea diff --git a/Source/InputMethodController.mm b/Source/InputMethodController.mm index 052ff8b0..b224ebab 100644 --- a/Source/InputMethodController.mm +++ b/Source/InputMethodController.mm @@ -216,13 +216,7 @@ public: BOOL learningEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:kDisableUserCandidateSelectionLearning]; NSMenuItem *learnMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Enable Selection Learning", @"") action:@selector(toggleLearning:) keyEquivalent:@""]; - if (learningEnabled) { - [learnMenuItem setState:NSOnState]; - } - else { - [learnMenuItem setState:NSOffState]; - } - + learnMenuItem.state = learningEnabled ? NSControlStateValueOn : NSControlStateValueOff; [menu addItem:learnMenuItem]; if (learningEnabled) { @@ -458,9 +452,8 @@ public: // we must use NSAttributedString so that the cursor is visible -- // can't just use NSString - NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:NSUnderlineStyleSingle], NSUnderlineStyleAttributeName, - [NSNumber numberWithInt:0], NSMarkedClauseSegmentAttributeName, nil]; + NSDictionary *attrDict = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle), + NSMarkedClauseSegmentAttributeName: @0}; NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict]; // the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound, diff --git a/Source/OVNonModalAlertWindowController.m b/Source/OVNonModalAlertWindowController.m index 25ce7a24..48302d68 100644 --- a/Source/OVNonModalAlertWindowController.m +++ b/Source/OVNonModalAlertWindowController.m @@ -30,10 +30,10 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wgnu-statement-expression" -- (void)showWithTitle:(NSString *)title content:(NSString *)content confirmButtonTitle:(NSString *)confirmTitle cancelButtonTitle:(NSString *)cancelButtonTitle cancelAsDefault:(BOOL)cancelAsDefault delegate:(id)delegate; +- (void)showWithTitle:(NSString *)title content:(NSString *)content confirmButtonTitle:(NSString *)confirmTitle cancelButtonTitle:(NSString *)cancelButtonTitle cancelAsDefault:(BOOL)cancelAsDefault delegate:(id )delegate; { // cancel previous alert - if ([[self window] isVisible]) { + if (self.window.visible) { if ([_delegate respondsToSelector:@selector(nonModalAlertWindowControllerDidCancel:)]) { [_delegate nonModalAlertWindowControllerDidCancel:self]; } @@ -41,11 +41,11 @@ _delegate = delegate; - NSRect oldFrame = [self.confirmButton frame]; + NSRect oldFrame = self.confirmButton.frame; [self.confirmButton setTitle:confirmTitle]; [self.confirmButton sizeToFit]; - NSRect newFrame = [self.confirmButton frame]; + NSRect newFrame = self.confirmButton.frame; newFrame.size.width = MAX(90.0, (newFrame.size.width + 10.0)); newFrame.origin.x += (oldFrame.size.width - newFrame.size.width); @@ -54,41 +54,41 @@ if (cancelButtonTitle) { [self.cancelButton setTitle:cancelButtonTitle]; [self.cancelButton sizeToFit]; - NSRect adjustedFrame = [self.cancelButton frame]; + NSRect adjustedFrame = self.cancelButton.frame; adjustedFrame.size.width = MAX(90.0, (adjustedFrame.size.width + 10.0)); adjustedFrame.origin.x = newFrame.origin.x - adjustedFrame.size.width; - [self.cancelButton setFrame:adjustedFrame]; - [self.cancelButton setHidden:NO]; + self.cancelButton.frame = adjustedFrame; + self.cancelButton.hidden = NO; } else { - [self.cancelButton setHidden:YES]; + self.cancelButton.hidden = YES; } - [self.cancelButton setNextKeyView:self.confirmButton]; - [self.confirmButton setNextKeyView:self.cancelButton]; + self.cancelButton.nextKeyView = self.confirmButton; + self.confirmButton.nextKeyView = self.cancelButton; if (cancelButtonTitle) { if (cancelAsDefault) { - [[self window] setDefaultButtonCell:[self.cancelButton cell]]; + [self.window setDefaultButtonCell:self.cancelButton.cell]; } else { - [self.cancelButton setKeyEquivalent:@" "]; - [[self window] setDefaultButtonCell:[self.confirmButton cell]]; + self.cancelButton.keyEquivalent = @" "; + [self.window setDefaultButtonCell:self.confirmButton.cell]; } } else { - [[self window] setDefaultButtonCell:[self.confirmButton cell]]; + [[self window] setDefaultButtonCell:self.confirmButton.cell]; } - [self.titleTextField setStringValue:title]; + self.titleTextField.stringValue = title; oldFrame = [self.contentTextField frame]; - [self.contentTextField setStringValue:content]; + self.contentTextField.stringValue = content; NSRect infiniteHeightFrame = oldFrame; infiniteHeightFrame.size.width -= 4.0; infiniteHeightFrame.size.height = 10240; - newFrame = [content boundingRectWithSize:infiniteHeightFrame.size options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:[self.contentTextField font], NSFontAttributeName, nil]]; + newFrame = [content boundingRectWithSize:infiniteHeightFrame.size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.contentTextField.font}]; newFrame.size.width = MAX(newFrame.size.width, oldFrame.size.width); newFrame.size.height += 4.0; newFrame.origin = oldFrame.origin; @@ -98,18 +98,19 @@ NSRect windowFrame = [[self window] frame]; windowFrame.size.height += (newFrame.size.height - oldFrame.size.height); - [[self window] setLevel:CGShieldingWindowLevel() + 1]; - [[self window] setFrame:windowFrame display:YES]; - [[self window] center]; - [[self window] makeKeyAndOrderFront:self]; + self.window.level = CGShieldingWindowLevel() + 1; + [self.window setFrame:windowFrame display:YES]; + [self.window center]; + [self.window makeKeyAndOrderFront:self]; [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; } + #pragma GCC diagnostic pop - (IBAction)confirmButtonAction:(id)sender { [_delegate nonModalAlertWindowControllerDidConfirm:self]; - [[self window] orderOut:self]; + [self.window orderOut:self]; } - (IBAction)cancelButtonAction:(id)sender @@ -124,8 +125,7 @@ } _delegate = nil; - - [[self window] orderOut:self]; + [self.window orderOut:self]; } @end diff --git a/Source/PreferencesWindowController.m b/Source/PreferencesWindowController.m index 668bfb54..bbcb408d 100644 --- a/Source/PreferencesWindowController.m +++ b/Source/PreferencesWindowController.m @@ -46,7 +46,7 @@ static NSString *const kBasisKeyboardLayoutPreferenceKey = @"BasisKeyboardLayout NSMenuItem *usKeyboardLayoutItem = nil; NSMenuItem *chosenItem = nil; - [[self.basisKeyboardLayoutButton menu] removeAllItems]; + [self.basisKeyboardLayoutButton.menu removeAllItems]; NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey]; @@ -72,8 +72,8 @@ static NSString *const kBasisKeyboardLayoutPreferenceKey = @"BasisKeyboardLayout NSString *localizedName = (__bridge NSString *)TISGetInputSourceProperty(source, kTISPropertyLocalizedName); NSMenuItem *item = [[NSMenuItem alloc] init]; - [item setTitle:localizedName]; - [item setRepresentedObject:sourceID]; + item.title = localizedName; + item.representedObject = sourceID; if ([sourceID isEqualToString:@"com.apple.keylayout.US"]) { usKeyboardLayoutItem = item; @@ -84,7 +84,7 @@ static NSString *const kBasisKeyboardLayoutPreferenceKey = @"BasisKeyboardLayout chosenItem = item; } - [[self.basisKeyboardLayoutButton menu] addItem:item]; + [self.basisKeyboardLayoutButton.menu addItem:item]; } [self.basisKeyboardLayoutButton selectItem:(chosenItem ? chosenItem : usKeyboardLayoutItem)]; From f6c36fe3258a1bad3e595ead6bac007215887288 Mon Sep 17 00:00:00 2001 From: zonble Date: Mon, 1 Mar 2021 22:43:02 +0800 Subject: [PATCH 07/12] Bridges SwiftyOpenCC to create a simple Chinese convertion function. --- McBopomofo.xcodeproj/project.pbxproj | 83 +++++++++++++++++++++++++++- Source/InputMethodController.h | 3 + Source/InputMethodController.mm | 27 +++++++-- Source/McBopomofo-Bridging-Header.h | 4 ++ Source/OpenCCBridge.swift | 29 ++++++++++ 5 files changed, 140 insertions(+), 6 deletions(-) create mode 100644 Source/McBopomofo-Bridging-Header.h create mode 100644 Source/OpenCCBridge.swift diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index f80b6d62..b56ae8b2 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -47,6 +47,9 @@ 6AE210B315FC63CC003659FE /* PlainBopomofo@2x.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 6AE210B115FC63CC003659FE /* PlainBopomofo@2x.tiff */; }; 6AFF97F2253B299E007F1C49 /* OVNonModalAlertWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6AFF97F0253B299E007F1C49 /* OVNonModalAlertWindowController.xib */; }; 6AFF97F3253B299E007F1C49 /* OVNonModalAlertWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */; }; + D427A9C125ED28CC005D43E0 /* OpenCCBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */; }; + D48550A325EBE689006A204C /* OpenCC in Frameworks */ = {isa = PBXBuildFile; productRef = D48550A225EBE689006A204C /* OpenCC */; }; + D48550C325EC0EF2006A204C /* OpenCCDictionary.bundle in Embed PlugIns */ = {isa = PBXBuildFile; fileRef = D48550A625EBF2CF006A204C /* OpenCCDictionary.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -66,6 +69,20 @@ }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + D48550BE25EC0D97006A204C /* Embed PlugIns */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + D48550C325EC0EF2006A204C /* OpenCCDictionary.bundle in Embed PlugIns */, + ); + name = "Embed PlugIns"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 6A0421A615FEF3F50061ED63 /* FastLM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastLM.cpp; sourceTree = ""; }; 6A0421A715FEF3F50061ED63 /* FastLM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastLM.h; sourceTree = ""; }; @@ -208,6 +225,9 @@ 6AFF97EF253B299E007F1C49 /* OVNonModalAlertWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVNonModalAlertWindowController.h; sourceTree = ""; }; 6AFF97F0253B299E007F1C49 /* OVNonModalAlertWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OVNonModalAlertWindowController.xib; sourceTree = ""; }; 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OVNonModalAlertWindowController.m; sourceTree = ""; }; + D427A9BF25ED28CC005D43E0 /* McBopomofo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "McBopomofo-Bridging-Header.h"; sourceTree = ""; }; + D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenCCBridge.swift; sourceTree = ""; }; + D48550A625EBF2CF006A204C /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../Library/Developer/Xcode/DerivedData/McBopomofo-czkkfmaoaedhszarcriztoynjmen/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -217,6 +237,7 @@ files = ( 6A38BC2A15FC161000A8A51F /* Carbon.framework in Frameworks */, 6A38BC2815FC158A00A8A51F /* InputMethodKit.framework in Frameworks */, + D48550A325EBE689006A204C /* OpenCC in Frameworks */, 6A0D4EA715FC0D2D00ABF4B3 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -256,6 +277,7 @@ 6A0D4EA915FC0D2D00ABF4B3 /* AppKit.framework */, 6A38BC2915FC161000A8A51F /* Carbon.framework */, 6A0D4EA615FC0D2D00ABF4B3 /* Cocoa.framework */, + D48550A625EBF2CF006A204C /* OpenCCDictionary.bundle */, 6A0D4EAB15FC0D2D00ABF4B3 /* Foundation.framework */, 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */, ); @@ -282,6 +304,8 @@ 6A0D4ECA15FC0D6400ABF4B3 /* OVInputSourceHelper.m */, 6A0D4ECB15FC0D6400ABF4B3 /* PreferencesWindowController.h */, 6A0D4ECC15FC0D6400ABF4B3 /* PreferencesWindowController.m */, + D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */, + D427A9BF25ED28CC005D43E0 /* McBopomofo-Bridging-Header.h */, ); path = Source; sourceTree = ""; @@ -502,6 +526,7 @@ 6A0D4E9E15FC0D2D00ABF4B3 /* Sources */, 6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */, 6A0D4EA015FC0D2D00ABF4B3 /* Resources */, + D48550BE25EC0D97006A204C /* Embed PlugIns */, ); buildRules = ( ); @@ -509,6 +534,9 @@ 6A38BC2615FC131100A8A51F /* PBXTargetDependency */, ); name = McBopomofo; + packageProductDependencies = ( + D48550A225EBE689006A204C /* OpenCC */, + ); productName = McBopomofo; productReference = 6A0D4EA215FC0D2D00ABF4B3 /* McBopomofo.app */; productType = "com.apple.product-type.application"; @@ -539,6 +567,11 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1220; + TargetAttributes = { + 6A0D4EA115FC0D2D00ABF4B3 = { + LastSwiftMigration = 1240; + }; + }; }; buildConfigurationList = 6A0D4E9715FC0CFA00ABF4B3 /* Build configuration list for PBXProject "McBopomofo" */; compatibilityVersion = "Xcode 3.2"; @@ -550,6 +583,9 @@ Base, ); mainGroup = 6A0D4E9215FC0CFA00ABF4B3; + packageReferences = ( + D48550A125EBE689006A204C /* XCRemoteSwiftPackageReference "SwiftyOpenCC" */, + ); productRefGroup = 6A0D4EA315FC0D2D00ABF4B3 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -634,6 +670,7 @@ 6A0D4F0115FC0DA600ABF4B3 /* VTVerticalCandidateController.m in Sources */, 6A0D4F0215FC0DA600ABF4B3 /* VTVerticalCandidateTableView.m in Sources */, 6A0D4F0315FC0DA600ABF4B3 /* VTVerticalKeyLabelStripView.m in Sources */, + D427A9C125ED28CC005D43E0 /* OpenCCBridge.swift in Sources */, 6A0D4F4515FC0EB100ABF4B3 /* Mandarin.cpp in Sources */, 6A0421A815FEF3F50061ED63 /* FastLM.cpp in Sources */, ); @@ -751,6 +788,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_MODULES = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -779,6 +817,10 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fcxx-modules", + ); }; name = Debug; }; @@ -786,6 +828,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_MODULES = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -812,6 +855,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-fcxx-modules", + ); }; name = Release; }; @@ -821,6 +868,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; @@ -858,11 +906,18 @@ GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = "Source/McBopomofo-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.openvanilla.inputmethod.McBopomofo; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SWIFT_OBJC_BRIDGING_HEADER = "Source/McBopomofo-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; WRAPPER_EXTENSION = app; }; name = Debug; @@ -873,6 +928,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; @@ -904,10 +960,16 @@ GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = "Source/McBopomofo-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_BUNDLE_IDENTIFIER = org.openvanilla.inputmethod.McBopomofo; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SWIFT_OBJC_BRIDGING_HEADER = "Source/McBopomofo-Bridging-Header.h"; + SWIFT_VERSION = 5.0; WRAPPER_EXTENSION = app; }; name = Release; @@ -1078,6 +1140,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + D48550A125EBE689006A204C /* XCRemoteSwiftPackageReference "SwiftyOpenCC" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ddddxxx/SwiftyOpenCC.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.0.1; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + D48550A225EBE689006A204C /* OpenCC */ = { + isa = XCSwiftPackageProductDependency; + package = D48550A125EBE689006A204C /* XCRemoteSwiftPackageReference "SwiftyOpenCC" */; + productName = OpenCC; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */; } diff --git a/Source/InputMethodController.h b/Source/InputMethodController.h index 00aca989..e8b91760 100644 --- a/Source/InputMethodController.h +++ b/Source/InputMethodController.h @@ -68,6 +68,9 @@ // current input mode NSString *_inputMode; + + BOOL _chineseConvertionEnabled; + } @end diff --git a/Source/InputMethodController.mm b/Source/InputMethodController.mm index b224ebab..081a5647 100644 --- a/Source/InputMethodController.mm +++ b/Source/InputMethodController.mm @@ -41,6 +41,9 @@ #import "AppDelegate.h" #import "VTHorizontalCandidateController.h" #import "VTVerticalCandidateController.h" +#import "McBopomofo-Swift.h" + +//@import SwiftUI; // C++ namespace usages using namespace std; @@ -75,6 +78,7 @@ static NSString *const kUseHorizontalCandidateListPreferenceKey = @"UseHorizonta static NSString *const kComposingBufferSizePreferenceKey = @"ComposingBufferSize"; static NSString *const kDisableUserCandidateSelectionLearning = @"DisableUserCandidateSelectionLearning"; static NSString *const kChooseCandidateUsingSpaceKey = @"ChooseCandidateUsingSpaceKey"; +static NSString *const kChineseConvertionEnanledKey = @"ChineseConvertionEnanledKey"; // advanced (usually optional) settings static NSString *const kCandidateTextFontName = @"CandidateTextFontName"; @@ -159,12 +163,8 @@ public: if (_builder) { delete _builder; } - - - // the two client pointers are weak pointers (i.e. we don't retain them) // therefore we don't do anything about it - } - (id)initWithServer:(IMKServer *)server delegate:(id)delegate client:(id)client @@ -195,6 +195,7 @@ public: } _inputMode = kBopomofoModeIdentifier; + _chineseConvertionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kChineseConvertionEnanledKey]; } return self; @@ -231,6 +232,11 @@ public: } #endif //DEBUG + NSMenuItem *chineseConvertionMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Chinese Convertion", @"") action:@selector(toggleChineseConverter:) keyEquivalent:@"G"]; + chineseConvertionMenuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl; + chineseConvertionMenuItem.state = _chineseConvertionEnabled ? NSControlStateValueOn : NSControlStateValueOff; + [menu addItem:chineseConvertionMenuItem]; + NSMenuItem *updateCheckItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Check for Updates…", @"") action:@selector(checkForUpdate:) keyEquivalent:@""]; [menu addItem:updateCheckItem]; @@ -388,8 +394,13 @@ public: return; } + NSString *buffer = _composingBuffer; + if (_chineseConvertionEnabled) { + buffer = [OpenCCBridge convert:_composingBuffer]; + } + // commit the text, clear the state - [client insertText:_composingBuffer replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; + [client insertText:buffer replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; _builder->clear(); _walkedNodes.clear(); [_composingBuffer setString:@""]; @@ -1428,6 +1439,12 @@ public: [[NSUserDefaults standardUserDefaults] setBool:toggle forKey:kDisableUserCandidateSelectionLearning]; } +- (void)toggleChineseConverter:(id)sender +{ + _chineseConvertionEnabled = !_chineseConvertionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:_chineseConvertionEnabled forKey:kChineseConvertionEnanledKey]; +} + - (void)clearLearningDictionary:(id)sender { [gCandidateLearningDictionary removeAllObjects]; diff --git a/Source/McBopomofo-Bridging-Header.h b/Source/McBopomofo-Bridging-Header.h new file mode 100644 index 00000000..1b2cb5d6 --- /dev/null +++ b/Source/McBopomofo-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/Source/OpenCCBridge.swift b/Source/OpenCCBridge.swift new file mode 100644 index 00000000..e67cfa9b --- /dev/null +++ b/Source/OpenCCBridge.swift @@ -0,0 +1,29 @@ +import Foundation +import OpenCC + +// Since SwiftyOpenCC only provide Swift classes, we create an NSObject subclass +// in Swift in order to bridge the Swift classes into our Objective-C++ project. +class OpenCCBridge : NSObject { + private static let shared = OpenCCBridge() + private var conveter: ChineseConverter? + + override init() { + let mainBundle = Bundle.main + let dictionaryBundleUrl = mainBundle.bundleURL + .appendingPathComponent("Contents", isDirectory: true) + .appendingPathComponent("Plugins", isDirectory: true) + .appendingPathComponent("OpenCCDictionary.bundle") + if let dictionaryBundle = Bundle(url:dictionaryBundleUrl) { + try? conveter = ChineseConverter(bundle: dictionaryBundle, option: .simplify) + } + super.init() + } + + @objc static func convert(_ string:String) -> String? { + return shared.conveter?.convert(string) + } + + private func convert(_ string:String) -> String? { + return conveter?.convert(string) + } +} From c8bad0913b63e04dfe6b8bcb00702f20daf00182 Mon Sep 17 00:00:00 2001 From: zonble Date: Mon, 1 Mar 2021 22:48:46 +0800 Subject: [PATCH 08/12] Removes unused code. --- Source/InputMethodController.h | 2 +- Source/OVNonModalAlertWindowController.h | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Source/InputMethodController.h b/Source/InputMethodController.h index e8b91760..e3f3e57b 100644 --- a/Source/InputMethodController.h +++ b/Source/InputMethodController.h @@ -69,8 +69,8 @@ // current input mode NSString *_inputMode; + // if Chinese convertion is enabled BOOL _chineseConvertionEnabled; - } @end diff --git a/Source/OVNonModalAlertWindowController.h b/Source/OVNonModalAlertWindowController.h index 91453cb8..e0eea1e2 100644 --- a/Source/OVNonModalAlertWindowController.h +++ b/Source/OVNonModalAlertWindowController.h @@ -18,14 +18,6 @@ @end @interface OVNonModalAlertWindowController : NSWindowController -{ -@private -// NSTextField *_titleTextField; -// NSTextField *_contentTextField; -// NSButton *_confirmButton; -// NSButton *_cancelButton; -// id _delegate; -} + (OVNonModalAlertWindowController *)sharedInstance; - (void)showWithTitle:(NSString *)title content:(NSString *)content confirmButtonTitle:(NSString *)confirmTitle cancelButtonTitle:(NSString *)cancelButtonTitle cancelAsDefault:(BOOL)cancelAsDefault delegate:(id)delegate; From 64dd47f0900152f0e0d86398c9a1a83cecdbd89f Mon Sep 17 00:00:00 2001 From: Superbil Date: Sat, 17 Apr 2021 07:21:30 +0800 Subject: [PATCH 09/12] Fix wrong path about OpenCCDictionary.bundle --- McBopomofo.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index b56ae8b2..cf55529d 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -49,7 +49,7 @@ 6AFF97F3253B299E007F1C49 /* OVNonModalAlertWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */; }; D427A9C125ED28CC005D43E0 /* OpenCCBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */; }; D48550A325EBE689006A204C /* OpenCC in Frameworks */ = {isa = PBXBuildFile; productRef = D48550A225EBE689006A204C /* OpenCC */; }; - D48550C325EC0EF2006A204C /* OpenCCDictionary.bundle in Embed PlugIns */ = {isa = PBXBuildFile; fileRef = D48550A625EBF2CF006A204C /* OpenCCDictionary.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E7582E69262A528E0003B31B /* OpenCCDictionary.bundle in Embed PlugIns */ = {isa = PBXBuildFile; fileRef = E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -76,7 +76,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - D48550C325EC0EF2006A204C /* OpenCCDictionary.bundle in Embed PlugIns */, + E7582E69262A528E0003B31B /* OpenCCDictionary.bundle in Embed PlugIns */, ); name = "Embed PlugIns"; runOnlyForDeploymentPostprocessing = 0; @@ -227,7 +227,7 @@ 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OVNonModalAlertWindowController.m; sourceTree = ""; }; D427A9BF25ED28CC005D43E0 /* McBopomofo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "McBopomofo-Bridging-Header.h"; sourceTree = ""; }; D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenCCBridge.swift; sourceTree = ""; }; - D48550A625EBF2CF006A204C /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../Library/Developer/Xcode/DerivedData/McBopomofo-czkkfmaoaedhszarcriztoynjmen/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; + E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../../Library/Developer/Xcode/DerivedData/McBopomofo-cqkraatnslbuvlhcaetfahesllst/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -277,7 +277,7 @@ 6A0D4EA915FC0D2D00ABF4B3 /* AppKit.framework */, 6A38BC2915FC161000A8A51F /* Carbon.framework */, 6A0D4EA615FC0D2D00ABF4B3 /* Cocoa.framework */, - D48550A625EBF2CF006A204C /* OpenCCDictionary.bundle */, + E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */, 6A0D4EAB15FC0D2D00ABF4B3 /* Foundation.framework */, 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */, ); From 1f8cd8d06fb93073c5ea7d839a012f08b69ef704 Mon Sep 17 00:00:00 2001 From: zonble Date: Wed, 10 Nov 2021 21:38:04 +0800 Subject: [PATCH 10/12] Updates SwiftOpenCC. --- McBopomofo.xcodeproj/project.pbxproj | 22 ++++------------------ Source/OpenCCBridge.swift | 9 +-------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index cf55529d..52765b70 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -49,7 +49,6 @@ 6AFF97F3253B299E007F1C49 /* OVNonModalAlertWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */; }; D427A9C125ED28CC005D43E0 /* OpenCCBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */; }; D48550A325EBE689006A204C /* OpenCC in Frameworks */ = {isa = PBXBuildFile; productRef = D48550A225EBE689006A204C /* OpenCC */; }; - E7582E69262A528E0003B31B /* OpenCCDictionary.bundle in Embed PlugIns */ = {isa = PBXBuildFile; fileRef = E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -69,20 +68,6 @@ }; /* End PBXContainerItemProxy section */ -/* Begin PBXCopyFilesBuildPhase section */ - D48550BE25EC0D97006A204C /* Embed PlugIns */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - E7582E69262A528E0003B31B /* OpenCCDictionary.bundle in Embed PlugIns */, - ); - name = "Embed PlugIns"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 6A0421A615FEF3F50061ED63 /* FastLM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastLM.cpp; sourceTree = ""; }; 6A0421A715FEF3F50061ED63 /* FastLM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastLM.h; sourceTree = ""; }; @@ -227,6 +212,7 @@ 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OVNonModalAlertWindowController.m; sourceTree = ""; }; D427A9BF25ED28CC005D43E0 /* McBopomofo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "McBopomofo-Bridging-Header.h"; sourceTree = ""; }; D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenCCBridge.swift; sourceTree = ""; }; + D47412EF273BFBFB0036C336 /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../Library/Developer/Xcode/DerivedData/McBopomofo-czkkfmaoaedhszarcriztoynjmen/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../../Library/Developer/Xcode/DerivedData/McBopomofo-cqkraatnslbuvlhcaetfahesllst/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -274,6 +260,7 @@ 6A0D4EA515FC0D2D00ABF4B3 /* Frameworks */ = { isa = PBXGroup; children = ( + D47412EF273BFBFB0036C336 /* OpenCCDictionary.bundle */, 6A0D4EA915FC0D2D00ABF4B3 /* AppKit.framework */, 6A38BC2915FC161000A8A51F /* Carbon.framework */, 6A0D4EA615FC0D2D00ABF4B3 /* Cocoa.framework */, @@ -526,7 +513,6 @@ 6A0D4E9E15FC0D2D00ABF4B3 /* Sources */, 6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */, 6A0D4EA015FC0D2D00ABF4B3 /* Resources */, - D48550BE25EC0D97006A204C /* Embed PlugIns */, ); buildRules = ( ); @@ -1146,8 +1132,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/ddddxxx/SwiftyOpenCC.git"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.0.1; + kind = revision; + revision = 1d8105a0f7199c90af722bff62728050c858e777; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Source/OpenCCBridge.swift b/Source/OpenCCBridge.swift index e67cfa9b..a9c63989 100644 --- a/Source/OpenCCBridge.swift +++ b/Source/OpenCCBridge.swift @@ -8,14 +8,7 @@ class OpenCCBridge : NSObject { private var conveter: ChineseConverter? override init() { - let mainBundle = Bundle.main - let dictionaryBundleUrl = mainBundle.bundleURL - .appendingPathComponent("Contents", isDirectory: true) - .appendingPathComponent("Plugins", isDirectory: true) - .appendingPathComponent("OpenCCDictionary.bundle") - if let dictionaryBundle = Bundle(url:dictionaryBundleUrl) { - try? conveter = ChineseConverter(bundle: dictionaryBundle, option: .simplify) - } + try? conveter = ChineseConverter(options: .simplify) super.init() } From 36a5eee37f53c1a7cc2fbccef1df698255b52e1d Mon Sep 17 00:00:00 2001 From: zonble Date: Wed, 10 Nov 2021 21:57:45 +0800 Subject: [PATCH 11/12] Updates CI settings. --- .github/workflows/continuous-integration-workflow.yml | 4 ++-- McBopomofo.xcodeproj/project.pbxproj | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 065fb076..c8a87cdc 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -10,6 +10,6 @@ jobs: steps: - uses: actions/checkout@v1 - name: Clean - run: xcodebuild -target McBopomofo -configuration Release clean + run: xcodebuild -scheme McBopomofo -configuration Release clean - name: Build - run: xcodebuild -target McBopomofo -configuration Release + run: xcodebuild -scheme McBopomofo -configuration Release diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index 52765b70..9187542d 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ 6A2E40F9253A6AA000D1AE1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; }; 6A38BC1515FC117A00A8A51F /* data.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6A38BBF615FC117A00A8A51F /* data.txt */; }; 6A38BC2815FC158A00A8A51F /* InputMethodKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */; }; - 6A38BC2A15FC161000A8A51F /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A38BC2915FC161000A8A51F /* Carbon.framework */; }; 6ACA41CD15FC1D7500935EF6 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A0D4EA615FC0D2D00ABF4B3 /* Cocoa.framework */; }; 6ACA41F915FC1D9000935EF6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ACA41E915FC1D9000935EF6 /* AppDelegate.m */; }; 6ACA41FA15FC1D9000935EF6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6ACA41EA15FC1D9000935EF6 /* InfoPlist.strings */; }; @@ -190,7 +189,6 @@ 6A38BBFC15FC117A00A8A51F /* PhraseFreq.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PhraseFreq.txt; sourceTree = ""; }; 6A38BBFD15FC117A00A8A51F /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = InputMethodKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/InputMethodKit.framework; sourceTree = DEVELOPER_DIR; }; - 6A38BC2915FC161000A8A51F /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; }; 6ACA41CB15FC1D7500935EF6 /* McBopomofoInstaller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = McBopomofoInstaller.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6ACA41E815FC1D9000935EF6 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Source/Installer/AppDelegate.h; sourceTree = SOURCE_ROOT; }; 6ACA41E915FC1D9000935EF6 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Source/Installer/AppDelegate.m; sourceTree = SOURCE_ROOT; }; @@ -212,8 +210,6 @@ 6AFF97F1253B299E007F1C49 /* OVNonModalAlertWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OVNonModalAlertWindowController.m; sourceTree = ""; }; D427A9BF25ED28CC005D43E0 /* McBopomofo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "McBopomofo-Bridging-Header.h"; sourceTree = ""; }; D427A9C025ED28CC005D43E0 /* OpenCCBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenCCBridge.swift; sourceTree = ""; }; - D47412EF273BFBFB0036C336 /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../Library/Developer/Xcode/DerivedData/McBopomofo-czkkfmaoaedhszarcriztoynjmen/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; - E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = OpenCCDictionary.bundle; path = "../../../Library/Developer/Xcode/DerivedData/McBopomofo-cqkraatnslbuvlhcaetfahesllst/SourcePackages/checkouts/SwiftyOpenCC/OpenCCDictionary.bundle"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -221,7 +217,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6A38BC2A15FC161000A8A51F /* Carbon.framework in Frameworks */, 6A38BC2815FC158A00A8A51F /* InputMethodKit.framework in Frameworks */, D48550A325EBE689006A204C /* OpenCC in Frameworks */, 6A0D4EA715FC0D2D00ABF4B3 /* Cocoa.framework in Frameworks */, @@ -260,11 +255,8 @@ 6A0D4EA515FC0D2D00ABF4B3 /* Frameworks */ = { isa = PBXGroup; children = ( - D47412EF273BFBFB0036C336 /* OpenCCDictionary.bundle */, 6A0D4EA915FC0D2D00ABF4B3 /* AppKit.framework */, - 6A38BC2915FC161000A8A51F /* Carbon.framework */, 6A0D4EA615FC0D2D00ABF4B3 /* Cocoa.framework */, - E7582E68262A528E0003B31B /* OpenCCDictionary.bundle */, 6A0D4EAB15FC0D2D00ABF4B3 /* Foundation.framework */, 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */, ); From 723a8402ab209e881d2e7fac91d3da54096a83f8 Mon Sep 17 00:00:00 2001 From: zonble Date: Thu, 11 Nov 2021 00:14:49 +0800 Subject: [PATCH 12/12] Fixes typos. --- Source/InputMethodController.h | 4 ++-- Source/InputMethodController.mm | 18 +++++++++--------- Source/en.lproj/Localizable.strings | 2 ++ Source/zh-Hant.lproj/Localizable.strings | 2 ++ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Source/InputMethodController.h b/Source/InputMethodController.h index e3f3e57b..8741cbed 100644 --- a/Source/InputMethodController.h +++ b/Source/InputMethodController.h @@ -69,8 +69,8 @@ // current input mode NSString *_inputMode; - // if Chinese convertion is enabled - BOOL _chineseConvertionEnabled; + // if Chinese conversion is enabled + BOOL _chineseConversionEnabled; } @end diff --git a/Source/InputMethodController.mm b/Source/InputMethodController.mm index 081a5647..7d664553 100644 --- a/Source/InputMethodController.mm +++ b/Source/InputMethodController.mm @@ -78,7 +78,7 @@ static NSString *const kUseHorizontalCandidateListPreferenceKey = @"UseHorizonta static NSString *const kComposingBufferSizePreferenceKey = @"ComposingBufferSize"; static NSString *const kDisableUserCandidateSelectionLearning = @"DisableUserCandidateSelectionLearning"; static NSString *const kChooseCandidateUsingSpaceKey = @"ChooseCandidateUsingSpaceKey"; -static NSString *const kChineseConvertionEnanledKey = @"ChineseConvertionEnanledKey"; +static NSString *const kChineseConversionEnabledKey = @"ChineseConversionEnabledKey"; // advanced (usually optional) settings static NSString *const kCandidateTextFontName = @"CandidateTextFontName"; @@ -195,7 +195,7 @@ public: } _inputMode = kBopomofoModeIdentifier; - _chineseConvertionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kChineseConvertionEnanledKey]; + _chineseConversionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kChineseConversionEnabledKey]; } return self; @@ -232,10 +232,10 @@ public: } #endif //DEBUG - NSMenuItem *chineseConvertionMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Chinese Convertion", @"") action:@selector(toggleChineseConverter:) keyEquivalent:@"G"]; - chineseConvertionMenuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl; - chineseConvertionMenuItem.state = _chineseConvertionEnabled ? NSControlStateValueOn : NSControlStateValueOff; - [menu addItem:chineseConvertionMenuItem]; + NSMenuItem *chineseConversionMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Chinese Conversion", @"") action:@selector(toggleChineseConverter:) keyEquivalent:@"G"]; + chineseConversionMenuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl; + chineseConversionMenuItem.state = _chineseConversionEnabled ? NSControlStateValueOn : NSControlStateValueOff; + [menu addItem:chineseConversionMenuItem]; NSMenuItem *updateCheckItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Check for Updates…", @"") action:@selector(checkForUpdate:) keyEquivalent:@""]; [menu addItem:updateCheckItem]; @@ -395,7 +395,7 @@ public: } NSString *buffer = _composingBuffer; - if (_chineseConvertionEnabled) { + if (_chineseConversionEnabled) { buffer = [OpenCCBridge convert:_composingBuffer]; } @@ -1441,8 +1441,8 @@ public: - (void)toggleChineseConverter:(id)sender { - _chineseConvertionEnabled = !_chineseConvertionEnabled; - [[NSUserDefaults standardUserDefaults] setBool:_chineseConvertionEnabled forKey:kChineseConvertionEnanledKey]; + _chineseConversionEnabled = !_chineseConversionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:_chineseConversionEnabled forKey:kChineseConversionEnabledKey]; } - (void)clearLearningDictionary:(id)sender diff --git a/Source/en.lproj/Localizable.strings b/Source/en.lproj/Localizable.strings index ed0452a5..0acd9b67 100644 --- a/Source/en.lproj/Localizable.strings +++ b/Source/en.lproj/Localizable.strings @@ -48,3 +48,5 @@ /* No comment provided by engineer. */ "You're currently using McBopomofo %@ (%@), a new version %@ (%@) is now available. Do you want to visit McBopomofo's website to download the version?%@" = "You're currently using McBopomofo %@ (%@), a new version %@ (%@) is now available. Do you want to visit McBopomofo's website to download the version?%@"; + +"Chinese Conversion" = "Chinese Conversion"; diff --git a/Source/zh-Hant.lproj/Localizable.strings b/Source/zh-Hant.lproj/Localizable.strings index 791d39d1..4ac965ae 100644 --- a/Source/zh-Hant.lproj/Localizable.strings +++ b/Source/zh-Hant.lproj/Localizable.strings @@ -48,3 +48,5 @@ /* No comment provided by engineer. */ "You're currently using McBopomofo %@ (%@), a new version %@ (%@) is now available. Do you want to visit McBopomofo's website to download the version?%@" = "目前使用的小麥注音版本是 %1$@ (%2$@),網路上有更新版本 %3$@ (%4$@) 可供下載。是否要前往小麥注音網站下載新版來安裝?%5$@"; + +"Chinese Conversion" = "簡繁轉換";