From 2b00b9386f2bc4cb0ff9eb0e0f1f34c67c338244 Mon Sep 17 00:00:00 2001 From: Yam Liu <1056803+yam-liu@users.noreply.github.com> Date: Sun, 4 Feb 2024 11:52:33 +0800 Subject: [PATCH] feat(Select Translate): keep previous result if selected text is empty when open Select Translate (#375) * feat(Select Translate): keep previous result if selected text is empty when open Select Translate * feat(Select Translate): make auto select query text behavior when window got activated a standalone option * feat(Select Translate): Update Chinese value for key "select_query_text_when_window_activate" in Localizable.xcstrings Co-authored-by: Tisfeng --------- Co-authored-by: Tisfeng --- Easydict/App/Localizable.xcstrings | 67 ++++++++++++++----- .../Feature/Configuration/Configuration.swift | 6 ++ .../Feature/Configuration/EZConfiguration.h | 1 + .../Feature/Configuration/EZConfiguration.m | 10 +++ .../EZSettingViewController.m | 48 ++++++++++--- .../EZBaseQueryViewController.m | 3 + .../Window/WindowManager/EZWindowManager.m | 9 ++- .../Configuration+Defaults.swift | 2 + .../View/SettingView/Tabs/GeneralTab.swift | 4 ++ 9 files changed, 122 insertions(+), 28 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 6e2c2cf10..257c47129 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -635,22 +635,6 @@ } } }, - "clear_input" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Clear Input:" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "清空查询内容:" - } - } - } - }, "clear_input_when_translating" : { "localizations" : { "en" : { @@ -1548,6 +1532,40 @@ } } }, + "keep_prev_result_when_selected_text_is_empty" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Keep previous result when selected text is empty" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "划词翻译未选中文本时,保留上次结果" + } + } + } + }, + "keep_result" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Keep Result:" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "保留结果:" + } + } + } + }, "language_detect_optimize" : { "localizations" : { "en" : { @@ -2347,6 +2365,23 @@ } } }, + "select_query_text_when_window_activate" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select query text when window activate" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "打开窗口时自动选中查询文本" + } + } + } + }, "select_translate" : { "localizations" : { "en" : { diff --git a/Easydict/Feature/Configuration/Configuration.swift b/Easydict/Feature/Configuration/Configuration.swift index 7f7c6dc53..774f4a193 100644 --- a/Easydict/Feature/Configuration/Configuration.swift +++ b/Easydict/Feature/Configuration/Configuration.swift @@ -141,6 +141,12 @@ let kHideMenuBarIconKey = "EZConfiguration_kHideMenuBarIconKey" @DefaultsWrapper(.clearInput) var clearInput: Bool + @DefaultsWrapper(.keepPrevResultWhenEmpty) + var keepPrevResultWhenEmpty: Bool + + @DefaultsWrapper(.selectQueryTextWhenWindowActivate) + var selectQueryTextWhenWindowActivate: Bool + var disabledAutoSelect: Bool = false var isRecordingSelectTextShortcutKey: Bool = false diff --git a/Easydict/Feature/Configuration/EZConfiguration.h b/Easydict/Feature/Configuration/EZConfiguration.h index 266797563..5cf592d6c 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.h +++ b/Easydict/Feature/Configuration/EZConfiguration.h @@ -73,6 +73,7 @@ typedef NS_ENUM(NSUInteger, EZAppearenceType) { @property (nonatomic, assign) BOOL allowCrashLog; @property (nonatomic, assign) BOOL allowAnalytics; @property (nonatomic, assign) BOOL clearInput; +@property (nonatomic, assign) BOOL keepPrevResult; // TODO: Need to move them. These are read/write properties only and will not be stored locally, only for external use. /// Only use when showing NSOpenPanel to select disabled apps. diff --git a/Easydict/Feature/Configuration/EZConfiguration.m b/Easydict/Feature/Configuration/EZConfiguration.m index a3104745a..407f9883c 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.m +++ b/Easydict/Feature/Configuration/EZConfiguration.m @@ -52,6 +52,7 @@ static NSString *const kAllowCrashLogKey = @"EZConfiguration_kAllowCrashLogKey"; static NSString *const kAllowAnalyticsKey = @"EZConfiguration_kAllowAnalyticsKey"; static NSString *const kClearInputKey = @"EZConfiguration_kClearInputKey"; +static NSString *const kKeepPrevResultKey = @"EZConfiguration_kKeepPrevResultKey"; static NSString *const kTranslationControllerFontKey = @"EZConfiguration_kTranslationControllerFontKey"; static NSString *const kApperanceKey = @"EZConfiguration_kApperanceKey"; @@ -126,6 +127,7 @@ - (void)setup { self.allowCrashLog = [NSUserDefaults mm_readBool:kAllowCrashLogKey defaultValue:YES]; self.allowAnalytics = [NSUserDefaults mm_readBool:kAllowAnalyticsKey defaultValue:YES]; self.clearInput = [NSUserDefaults mm_readBool:kClearInputKey defaultValue:NO]; + self.keepPrevResult = [NSUserDefaults mm_readBool:kKeepPrevResultKey defaultValue:YES]; self.fontSizes = @[@(1), @(1.1), @(1.2), @(1.3), @(1.4)]; [[NSUserDefaults standardUserDefaults]registerDefaults:@{kTranslationControllerFontKey: @(0)}]; @@ -432,6 +434,14 @@ - (void)setClearInput:(BOOL)clearInput { [self logSettings:@{@"clear_input" : @(clearInput)}]; } +- (void)setKeepPrevResult:(BOOL)keepPrevResult { + _keepPrevResult = keepPrevResult; + + [NSUserDefaults mm_write:@(keepPrevResult) forKey:kKeepPrevResultKey]; + + [self logSettings:@{@"keep_prev_result": @(keepPrevResult)}]; +} + - (void)setFontSizeIndex:(NSInteger)fontSizeIndex { NSInteger targetIndex = MIN(_fontSizes.count-1, MAX(fontSizeIndex, 0)); diff --git a/Easydict/Feature/PerferenceWindow/EZSettingViewController.m b/Easydict/Feature/PerferenceWindow/EZSettingViewController.m index 8715ec11e..a2d28b21e 100644 --- a/Easydict/Feature/PerferenceWindow/EZSettingViewController.m +++ b/Easydict/Feature/PerferenceWindow/EZSettingViewController.m @@ -74,8 +74,10 @@ @interface EZSettingViewController () @property (nonatomic, strong) NSTextField *playAudioLabel; @property (nonatomic, strong) NSButton *autoPlayAudioButton; -@property (nonatomic, strong) NSTextField *clearInputLabel; +@property (nonatomic, strong) NSTextField *inputFieldLabel; @property (nonatomic, strong) NSButton *clearInputButton; +@property (nonatomic, strong) NSButton *keepPrevResultButton; +@property (nonatomic, strong) NSButton *selectQueryTextWhenWindowActivateButton; @property (nonatomic, strong) NSTextField *autoQueryLabel; @property (nonatomic, strong) NSButton *autoQueryOCRTextButton; @@ -395,14 +397,23 @@ - (void)setupUI { self.autoPlayAudioButton = [NSButton checkboxWithTitle:autoPlayAudioTitle target:self action:@selector(autoPlayAudioButtonClicked:)]; [self.contentView addSubview:self.autoPlayAudioButton]; - NSTextField *clearInputLabel = [NSTextField labelWithString:NSLocalizedString(@"clear_input", nil)]; - clearInputLabel.font = font; - [self.contentView addSubview:clearInputLabel]; - self.clearInputLabel = clearInputLabel; + NSString *inputFieldLabelTitle = [NSString stringWithFormat:@"%@:", NSLocalizedString(@"setting.general.input.header", nil)]; + NSTextField *inputFieldLabel = [NSTextField labelWithString:inputFieldLabelTitle]; + inputFieldLabel.font = font; + [self.contentView addSubview:inputFieldLabel]; + self.inputFieldLabel = inputFieldLabel; NSString *clearInputTitle = NSLocalizedString(@"clear_input_when_translating", nil); self.clearInputButton = [NSButton checkboxWithTitle:clearInputTitle target:self action:@selector(clearInputButtonClicked:)]; [self.contentView addSubview:self.clearInputButton]; + + NSString *keepPrevResultTitle = NSLocalizedString(@"keep_prev_result_when_selected_text_is_empty", nil); + self.keepPrevResultButton = [NSButton checkboxWithTitle:keepPrevResultTitle target:self action:@selector(keepPrevResultButtonClicked:)]; + [self.contentView addSubview:self.keepPrevResultButton]; + + NSString *selectQueryTextWhenWindowActivateTitle = NSLocalizedString(@"select_query_text_when_window_activate", nil); + self.selectQueryTextWhenWindowActivateButton = [NSButton checkboxWithTitle:selectQueryTextWhenWindowActivateTitle target:self action:@selector(selectQueryTextWhenWindowActivateButtonClicked:)]; + [self.contentView addSubview:self.selectQueryTextWhenWindowActivateButton]; NSTextField *autoQueryLabel = [NSTextField labelWithString:NSLocalizedString(@"auto_query", nil)]; autoQueryLabel.font = font; @@ -546,6 +557,8 @@ - (void)setupUI { self.autoPlayAudioButton.mm_isOn = self.config.autoPlayAudio; self.clearInputButton.mm_isOn = self.config.clearInput; + self.keepPrevResultButton.mm_isOn = self.config.keepPrevResultWhenEmpty; + self.selectQueryTextWhenWindowActivateButton.mm_isOn = self.config.selectQueryTextWhenWindowActivate; self.launchAtStartupButton.mm_isOn = self.config.launchAtStartup; self.hideMainWindowButton.mm_isOn = self.config.hideMainWindow; self.autoQueryOCRTextButton.mm_isOn = self.config.autoQueryOCRText; @@ -747,19 +760,26 @@ - (void)updateViewConstraints { }]; - [self.clearInputLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + [self.inputFieldLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.autoPlayAudioButton.mas_bottom).offset(self.verticalPadding); }]; [self.clearInputButton mas_remakeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.clearInputLabel.mas_right).offset(self.horizontalPadding); - make.centerY.equalTo(self.clearInputLabel); + make.left.equalTo(self.inputFieldLabel.mas_right).offset(self.horizontalPadding); + make.centerY.equalTo(self.inputFieldLabel); + }]; + [self.keepPrevResultButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.clearInputButton); + make.top.equalTo(self.clearInputButton.mas_bottom).offset(self.verticalPadding); + }]; + [self.selectQueryTextWhenWindowActivateButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.clearInputButton); + make.top.equalTo(self.keepPrevResultButton.mas_bottom).offset(self.verticalPadding); }]; - [self.autoQueryLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); - make.top.equalTo(self.clearInputButton.mas_bottom).offset(self.verticalPadding); + make.top.equalTo(self.selectQueryTextWhenWindowActivateButton.mas_bottom).offset(self.verticalPadding); }]; [self.autoQueryOCRTextButton mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.autoQueryLabel.mas_right).offset(self.horizontalPadding); @@ -967,6 +987,14 @@ - (void)clearInputButtonClicked:(NSButton *)sender { self.config.clearInput = sender.mm_isOn; } +- (void)keepPrevResultButtonClicked:(NSButton *)sender { + self.config.keepPrevResultWhenEmpty = sender.mm_isOn; +} + +- (void)selectQueryTextWhenWindowActivateButtonClicked:(NSButton *)sender { + self.config.selectQueryTextWhenWindowActivate = sender.mm_isOn; +} + - (void)autoCopySelectedTextButtonClicked:(NSButton *)sender { self.config.autoCopySelectedText = sender.mm_isOn; } diff --git a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index c1bb5cc13..44a5a5e5b 100644 --- a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -527,6 +527,9 @@ - (void)focusInputTextView { [NSApp activateIgnoringOtherApps:YES]; [self.baseQueryWindow makeFirstResponder:self.queryView.textView]; + if (Configuration.shared.selectQueryTextWhenWindowActivate) { + self.queryView.textView.selectedRange = NSMakeRange(0, self.inputText.length); + } } } diff --git a/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m b/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m index dd2c18664..05df14104 100644 --- a/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m +++ b/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m @@ -694,9 +694,14 @@ - (void)selectTextTranslate { NSLog(@"selectTextTranslate windowType: %@", @(windowType)); self.eventMonitor.actionType = EZActionTypeShortcutQuery; [self.eventMonitor getSelectedText:^(NSString *_Nullable text) { - // If text is nil, currently, we choose to clear input. - self.selectedText = [text trim] ?: @""; self.actionType = self.eventMonitor.actionType; + + // Clear query if text is nil and user don't want to keep the last result. + if (!text && !Configuration.shared.keepPrevResultWhenEmpty) { + text = @""; + } + self.selectedText = [text trim]; + [self showFloatingWindowType:windowType queryText:self.selectedText]; }]; } diff --git a/Easydict/NewApp/Configuration/Configuration+Defaults.swift b/Easydict/NewApp/Configuration/Configuration+Defaults.swift index 6b529ec6b..3b3305739 100644 --- a/Easydict/NewApp/Configuration/Configuration+Defaults.swift +++ b/Easydict/NewApp/Configuration/Configuration+Defaults.swift @@ -47,6 +47,8 @@ extension Defaults.Keys { static let allowCrashLog = Key("EZConfiguration_kAllowCrashLogKey", default: true) static let allowAnalytics = Key("EZConfiguration_kAllowAnalyticsKey", default: true) static let clearInput = Key("EZConfiguration_kClearInputKey", default: true) + static let keepPrevResultWhenEmpty = Key("EZConfiguration_kKeepPrevResultKey", default: true) + static let selectQueryTextWhenWindowActivate = Key("EZConfiguration_kSelectQueryTextWhenWindowActivate", default: false) static let enableBetaNewApp = Key("EZConfiguration_kEnableBetaNewAppKey", default: false) static let enableBetaFeature = Key("EZBetaFeatureKey", default: false) diff --git a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift index a1e59e04e..cfbf2f2dd 100644 --- a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift +++ b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift @@ -78,6 +78,8 @@ struct GeneralTab: View { Section { Toggle("clear_input_when_translating", isOn: $clearInput) + Toggle("keep_prev_result_when_selected_text_is_empty", isOn: $keepPrevResultWhenEmpty) + Toggle("select_query_text_when_window_activate", isOn: $selectQueryTextWhenWindowActivate) } header: { Text("setting.general.input.header") } @@ -161,6 +163,8 @@ struct GeneralTab: View { @Default(.adjustPopButtonOrigin) private var adjustPopButtonOrigin @Default(.clearInput) private var clearInput + @Default(.keepPrevResultWhenEmpty) private var keepPrevResultWhenEmpty + @Default(.selectQueryTextWhenWindowActivate) private var selectQueryTextWhenWindowActivate @Default(.disableEmptyCopyBeep) private var disableEmptyCopyBeep @Default(.autoPlayAudio) private var autoPlayAudio