From 60550d5ee027a17390e22442449e66f6acbe679a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <1173718158@qq.com> Date: Wed, 20 Nov 2024 20:53:01 +0800 Subject: [PATCH] . --- cpp/version.cmake | 2 +- cpp/winsharedutils/webview2_extra.cpp | 102 ++++++++++++++++++++++++++ py/LunaTranslator/gui/showword.py | 20 ++++- py/LunaTranslator/gui/usefulwidget.py | 23 ++++++ py/LunaTranslator/winsharedutils.py | 6 ++ py/files/lang/ar.json | 3 +- py/files/lang/cht.json | 3 +- py/files/lang/cs.json | 3 +- py/files/lang/de.json | 3 +- py/files/lang/en.json | 3 +- py/files/lang/es.json | 3 +- py/files/lang/fr.json | 3 +- py/files/lang/it.json | 3 +- py/files/lang/ja.json | 3 +- py/files/lang/ko.json | 3 +- py/files/lang/nl.json | 3 +- py/files/lang/pl.json | 3 +- py/files/lang/pt.json | 3 +- py/files/lang/ru.json | 3 +- py/files/lang/sv.json | 3 +- py/files/lang/th.json | 3 +- py/files/lang/tr.json | 3 +- py/files/lang/uk.json | 3 +- py/files/lang/vi.json | 3 +- py/files/lang/zh.json | 3 +- 25 files changed, 188 insertions(+), 25 deletions(-) diff --git a/cpp/version.cmake b/cpp/version.cmake index 60df77d9..6c685ee0 100644 --- a/cpp/version.cmake +++ b/cpp/version.cmake @@ -1,7 +1,7 @@ set(VERSION_MAJOR 6) set(VERSION_MINOR 5) -set(VERSION_PATCH 1) +set(VERSION_PATCH 2) set(VERSION_REVISION 0) set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") add_library(VERSION_DEF INTERFACE) diff --git a/cpp/winsharedutils/webview2_extra.cpp b/cpp/winsharedutils/webview2_extra.cpp index 2a353e86..33af0078 100644 --- a/cpp/winsharedutils/webview2_extra.cpp +++ b/cpp/winsharedutils/webview2_extra.cpp @@ -187,3 +187,105 @@ DECLARE_API void *add_WebMessageReceived(void *m_host, void (*callback)(const wc return NULL; #endif } +struct contextcallbackdatas +{ + EventRegistrationToken contextMenuRequestedToken; + std::wstring label; +}; +// https://learn.microsoft.com/zh-cn/microsoft-edge/webview2/how-to/context-menus?tabs=cpp +// https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2_11?view=webview2-1.0.2849.39 +DECLARE_API void *add_ContextMenuRequested(void *m_host, int index, const wchar_t *label, void (*callback)(const wchar_t *)) +{ +#ifndef WINXP + contextcallbackdatas *data = new contextcallbackdatas; + data->label = label; // 持久化 + [=]() + { + wil::com_ptr m_controller(reinterpret_cast(m_host)); + wil::com_ptr m_webView; + CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); + auto m_webView2_11 = m_webView.try_query(); + if (!m_webView2_11) + return S_OK; + m_webView2_11->add_ContextMenuRequested( + Callback( + [=]( + ICoreWebView2 *sender, + ICoreWebView2ContextMenuRequestedEventArgs *args) + { + wil::com_ptr target; + CHECK_FAILURE(args->get_ContextMenuTarget(&target)); + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND targetKind; + BOOL hasselection; + CHECK_FAILURE(target->get_Kind(&targetKind)); + CHECK_FAILURE(target->get_HasSelection(&hasselection)); + if (!(hasselection && (targetKind == + COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_SELECTED_TEXT))) + return S_OK; + wil::com_ptr m_webView2_11; + CHECK_FAILURE(sender->QueryInterface(IID_PPV_ARGS(&m_webView2_11))); + + wil::com_ptr webviewEnvironment; + CHECK_FAILURE(m_webView2_11->get_Environment(&webviewEnvironment)); + auto webviewEnvironment_5 = webviewEnvironment.try_query(); + if (!webviewEnvironment_5) + return S_OK; + wil::com_ptr items; + CHECK_FAILURE(args->get_MenuItems(&items)); + UINT32 itemsCount; + CHECK_FAILURE(items->get_Count(&itemsCount)); + // Adding a custom context menu item for the page that will display the page's URI. + wil::com_ptr newMenuItem; + CHECK_FAILURE(webviewEnvironment_5->CreateContextMenuItem( + data->label.c_str(), + nullptr, + COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_COMMAND, &newMenuItem)); + newMenuItem->add_CustomItemSelected( + Callback( + [=]( + ICoreWebView2ContextMenuItem *sender, + IUnknown *args) + { + LPWSTR selecttext; + CHECK_FAILURE(target->get_SelectionText(&selecttext)); + callback(selecttext); + // 不需要free,free反而会崩溃 + return S_OK; + }) + .Get(), + nullptr); + UINT idx; + if (index == -1) + idx = itemsCount; + else + idx = index; + CHECK_FAILURE(items->InsertValueAtIndex(idx, newMenuItem.get())); + return S_OK; + }) + .Get(), + &data->contextMenuRequestedToken); + return S_OK; + }(); + return data; +#else + return NULL; +#endif +} +DECLARE_API void remove_ContextMenuRequested(void *m_host, void *data) +{ +#ifndef WINXP + auto token = reinterpret_cast(data); + wil::com_ptr m_controller(reinterpret_cast(m_host)); + wil::com_ptr m_webView; + [&]() + { + CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); + auto m_webView2_11 = m_webView.try_query(); + if (!m_webView2_11) + return S_OK; + CHECK_FAILURE(m_webView2_11->remove_ContextMenuRequested(token->contextMenuRequestedToken)); + return S_OK; + }(); + delete token; +#endif +} \ No newline at end of file diff --git a/py/LunaTranslator/gui/showword.py b/py/LunaTranslator/gui/showword.py index 4138e304..2fac1be3 100644 --- a/py/LunaTranslator/gui/showword.py +++ b/py/LunaTranslator/gui/showword.py @@ -5,7 +5,7 @@ from traceback import print_exc import qtawesome, requests, gobject, windows, winsharedutils import myutils.ankiconnect as anki from myutils.hwnd import grabwindow -from myutils.config import globalconfig, static_data +from myutils.config import globalconfig, static_data, _TR from myutils.utils import ( loopbackrecorder, parsekeystringtomodvkcode, @@ -238,7 +238,7 @@ class AnkiWindow(QWidget): collect = [] for hira in self.example.hiras: if hira["orig"] == word or hira.get("origorig", None) == word: - collect.append('{}'.format(hira["orig"])) + collect.append("{}".format(hira["orig"])) else: collect.append(hira["orig"]) example = "".join(collect) @@ -976,11 +976,13 @@ class showdiction(LMainWindow): class searchwordW(closeashidewindow): search_word = pyqtSignal(str, bool) show_dict_result = pyqtSignal(float, str, str) + search_word_in_new_window = pyqtSignal(str) def __init__(self, parent): super(searchwordW, self).__init__(parent, globalconfig["sw_geo"]) # self.setWindowFlags(self.windowFlags()&~Qt.WindowMinimizeButtonHint) self.search_word.connect(self.__click_word_search_function) + self.search_word_in_new_window.connect(self.searchwinnewwindow) self.show_dict_result.connect(self.__show_dict_result_function) self.state = 0 @@ -1033,8 +1035,7 @@ class searchwordW(closeashidewindow): return self.textOutput.setHtml(html) - def _createnewwindowsearch(self, _): - word = self.searchtext.text() + def searchwinnewwindow(self, word): class searchwordWx(searchwordW): def closeEvent(self1, event: QCloseEvent): @@ -1042,10 +1043,15 @@ class searchwordW(closeashidewindow): super(saveposwindow, self1).closeEvent(event) _ = searchwordWx(self.parent()) + _.move(_.pos() + QPoint(20, 20)) _.show() _.searchtext.setText(word) _.__search_by_click_search_btn() + def _createnewwindowsearch(self, _): + word = self.searchtext.text() + self.searchwinnewwindow(word) + def showmenu_auto_sound(self, _): menu = QMenu(self) @@ -1133,6 +1139,12 @@ class searchwordW(closeashidewindow): self.tabks = [] self.setCentralWidget(ww) self.textOutput = auto_select_webview(self, True) + self.textOutput.add_menu( + 0, _TR("查词"), lambda w: self.search_word.emit(w, False) + ) + self.textOutput.add_menu( + 1, _TR("在新窗口中查词"), threader(self.search_word_in_new_window.emit) + ) self.textOutput.set_zoom(globalconfig["ZoomFactor"]) self.textOutput.on_ZoomFactorChanged.connect( functools.partial(globalconfig.__setitem__, "ZoomFactor") diff --git a/py/LunaTranslator/gui/usefulwidget.py b/py/LunaTranslator/gui/usefulwidget.py index 2246c72f..8cb0410d 100644 --- a/py/LunaTranslator/gui/usefulwidget.py +++ b/py/LunaTranslator/gui/usefulwidget.py @@ -1163,6 +1163,9 @@ class abstractwebview(QWidget): def navigate(self, url): pass + def add_menu(self, index, label, callback): + pass + # def parsehtml(self, html): pass @@ -1245,6 +1248,8 @@ class WebivewWidget(abstractwebview): winsharedutils.remove_WebMessageReceived( self.get_controller(), self.m_webMessageReceivedToken ) + for m in self.addmenu_infos: + winsharedutils.remove_ContextMenuRequested(self.get_controller(), m) def bind(self, fname, func): self.webview.bind(fname, func) @@ -1262,9 +1267,20 @@ class WebivewWidget(abstractwebview): webview_native_handle_kind_t.WEBVIEW_NATIVE_HANDLE_KIND_UI_WIDGET ) + def add_menu(self, index, label, callback): + __ = winsharedutils.add_ContextMenuRequested_cb(callback) + self.callbacks.append(__) + self.addmenu_infos.append( + winsharedutils.add_ContextMenuRequested( + self.get_controller(), index, label, __ + ) + ) + def __init__(self, parent=None, debug=True, usedarklight=True) -> None: super().__init__(parent) self.webview = None + self.callbacks = [] + self.addmenu_infos = [] self.webview = Webview(debug=debug, window=int(self.winId())) self.m_webMessageReceivedToken = None self.zoomfunc = winsharedutils.add_ZoomFactorChanged_CALLBACK( @@ -1511,6 +1527,10 @@ class auto_select_webview(QWidget): on_load = pyqtSignal(str) on_ZoomFactorChanged = pyqtSignal(float) + def add_menu(self, index, label, callback): + self.addmenuinfo.append((index, label, callback)) + self.internal.add_menu(index, label, callback) + def clear(self): self.lastaction = None self.internal.clear() @@ -1541,6 +1561,7 @@ class auto_select_webview(QWidget): def __init__(self, parent, dyna=False) -> None: super().__init__(parent) + self.addmenuinfo = [] self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.internal = None layout = QHBoxLayout() @@ -1575,6 +1596,8 @@ class auto_select_webview(QWidget): self.navigate(arg) elif action == 1: self.setHtml(arg) + for _ in self.addmenuinfo: + self.internal.add_menu(*_) def _createwebview(self): contex = globalconfig["usewebview"] diff --git a/py/LunaTranslator/winsharedutils.py b/py/LunaTranslator/winsharedutils.py index 17125292..bb9fffd5 100644 --- a/py/LunaTranslator/winsharedutils.py +++ b/py/LunaTranslator/winsharedutils.py @@ -341,6 +341,12 @@ add_WebMessageReceived.argtypes = (c_void_p, add_WebMessageReceived_cb) add_WebMessageReceived.restype = c_void_p remove_WebMessageReceived = utilsdll.remove_WebMessageReceived remove_WebMessageReceived.argtypes = c_void_p, c_void_p +add_ContextMenuRequested_cb = CFUNCTYPE(c_void_p, c_wchar_p) +add_ContextMenuRequested = utilsdll.add_ContextMenuRequested +add_ContextMenuRequested.argtypes = c_void_p, c_int, c_wchar_p, add_ContextMenuRequested_cb +add_ContextMenuRequested.restype = c_void_p +remove_ContextMenuRequested = utilsdll.remove_ContextMenuRequested +remove_ContextMenuRequested.argtypes = c_void_p, c_void_p clipboard_callback = utilsdll.clipboard_callback clipboard_callback.argtypes = (c_void_p,) clipboard_callback.restype = HWND diff --git a/py/files/lang/ar.json b/py/files/lang/ar.json index 95d84590..2011228c 100644 --- a/py/files/lang/ar.json +++ b/py/files/lang/ar.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "win32 وظيفة رسم النص هوك", "Win32字符串函数钩子": "win32 سلسلة هوك", "额外的钩子": "خطاف إضافية", - "自动前进": "التلقائي إلى الأمام" + "自动前进": "التلقائي إلى الأمام", + "在新窗口中查词": "البحث عن الكلمات في نافذة جديدة" } \ No newline at end of file diff --git a/py/files/lang/cht.json b/py/files/lang/cht.json index f0e29842..56ef5c9b 100644 --- a/py/files/lang/cht.json +++ b/py/files/lang/cht.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32文字繪製函數鉤子", "Win32字符串函数钩子": "Win32字串函數鉤子", "额外的钩子": "額外的鉤子", - "自动前进": "自動前進" + "自动前进": "自動前進", + "在新窗口中查词": "在新窗口中查詞" } \ No newline at end of file diff --git a/py/files/lang/cs.json b/py/files/lang/cs.json index 918155cb..538ae164 100644 --- a/py/files/lang/cs.json +++ b/py/files/lang/cs.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 funkce kreslení textu", "Win32字符串函数钩子": "Win32 řetězcový funkční hák", "额外的钩子": "Extra háčky", - "自动前进": "Automaticky dopředu" + "自动前进": "Automaticky dopředu", + "在新窗口中查词": "Vyhledávání slov v novém okně" } \ No newline at end of file diff --git a/py/files/lang/de.json b/py/files/lang/de.json index c8478c55..49cb06cb 100644 --- a/py/files/lang/de.json +++ b/py/files/lang/de.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 Text Zeichenfunktion Hook", "Win32字符串函数钩子": "Win32 String Function Hook", "额外的钩子": "Zusätzliche Haken", - "自动前进": "Automatisch vorwärts" + "自动前进": "Automatisch vorwärts", + "在新窗口中查词": "Suche nach Wörtern in einem neuen Fenster" } \ No newline at end of file diff --git a/py/files/lang/en.json b/py/files/lang/en.json index cbe34bbd..06ef5209 100644 --- a/py/files/lang/en.json +++ b/py/files/lang/en.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 text drawing function hook", "Win32字符串函数钩子": "Win32 string function hook", "额外的钩子": "Extra hooks", - "自动前进": "Automatic Forward" + "自动前进": "Automatic Forward", + "在新窗口中查词": "Search for words in a new window" } \ No newline at end of file diff --git a/py/files/lang/es.json b/py/files/lang/es.json index 927cfe38..7793d2d1 100644 --- a/py/files/lang/es.json +++ b/py/files/lang/es.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Gancho de función de dibujo de texto Win32", "Win32字符串函数钩子": "Gancho de función de cadena Win32", "额外的钩子": "Ganchos adicionales", - "自动前进": "Avance automático" + "自动前进": "Avance automático", + "在新窗口中查词": "Buscar palabras en una nueva ventana" } \ No newline at end of file diff --git a/py/files/lang/fr.json b/py/files/lang/fr.json index dd94b3da..ea256b7f 100644 --- a/py/files/lang/fr.json +++ b/py/files/lang/fr.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 crochet de fonction de dessin de texte", "Win32字符串函数钩子": "Crochet de fonction de chaîne Win32", "额外的钩子": "Crochets supplémentaires", - "自动前进": "Avance automatique" + "自动前进": "Avance automatique", + "在新窗口中查词": "Rechercher des mots dans une nouvelle fenêtre" } \ No newline at end of file diff --git a/py/files/lang/it.json b/py/files/lang/it.json index 9a56fb92..099a6a09 100644 --- a/py/files/lang/it.json +++ b/py/files/lang/it.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Gancio della funzione di disegno del testo Win32", "Win32字符串函数钩子": "Aggancio della funzione stringa Win32", "额外的钩子": "Ganci supplementari", - "自动前进": "Avanti automatico" + "自动前进": "Avanti automatico", + "在新窗口中查词": "Cerca parole in una nuova finestra" } \ No newline at end of file diff --git a/py/files/lang/ja.json b/py/files/lang/ja.json index 6ea9e98a..d1626420 100644 --- a/py/files/lang/ja.json +++ b/py/files/lang/ja.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win 32文字描画関数フック", "Win32字符串函数钩子": "Win 32文字列関数フック", "额外的钩子": "エクストラフック", - "自动前进": "自動前進" + "自动前进": "自動前進", + "在新窗口中查词": "新しいウィンドウで単語を調べる" } \ No newline at end of file diff --git a/py/files/lang/ko.json b/py/files/lang/ko.json index 6475b94b..3ab6a3ce 100644 --- a/py/files/lang/ko.json +++ b/py/files/lang/ko.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 텍스트 그리기 함수 갈고리", "Win32字符串函数钩子": "Win32 문자열 함수 후크", "额外的钩子": "추가 갈고리", - "自动前进": "자동 전진" + "自动前进": "자동 전진", + "在新窗口中查词": "새 창에서 단어 찾기" } \ No newline at end of file diff --git a/py/files/lang/nl.json b/py/files/lang/nl.json index 89ca62e9..46f794d8 100644 --- a/py/files/lang/nl.json +++ b/py/files/lang/nl.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 teksttekenfunctiehook", "Win32字符串函数钩子": "Win32 tekenfunctiehook", "额外的钩子": "Extra haken", - "自动前进": "Automatisch voorwaarts" + "自动前进": "Automatisch voorwaarts", + "在新窗口中查词": "Zoeken naar woorden in een nieuw venster" } \ No newline at end of file diff --git a/py/files/lang/pl.json b/py/files/lang/pl.json index a5a9404d..d73770fa 100644 --- a/py/files/lang/pl.json +++ b/py/files/lang/pl.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Hook funkcji rysowania tekstu Win32", "Win32字符串函数钩子": "Hook funkcji ciągów Win32", "额外的钩子": "Dodatkowe haki", - "自动前进": "Automatyczne naprzód" + "自动前进": "Automatyczne naprzód", + "在新窗口中查词": "Wyszukiwanie słów w nowym oknie" } \ No newline at end of file diff --git a/py/files/lang/pt.json b/py/files/lang/pt.json index 5cda5f67..d5f88304 100644 --- a/py/files/lang/pt.json +++ b/py/files/lang/pt.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Gancho de função de desenho de texto Win32", "Win32字符串函数钩子": "Gancho de função de cadeia Win32", "额外的钩子": "Ganchos extra", - "自动前进": "Avançar Automático" + "自动前进": "Avançar Automático", + "在新窗口中查词": "Procurar palavras numa nova janela" } \ No newline at end of file diff --git a/py/files/lang/ru.json b/py/files/lang/ru.json index 11820999..2db43d78 100644 --- a/py/files/lang/ru.json +++ b/py/files/lang/ru.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 Графический крюк", "Win32字符串函数钩子": "Win32 Строчный крюк", "额外的钩子": "Дополнительный крюк", - "自动前进": "Автоматическое продвижение вперед" + "自动前进": "Автоматическое продвижение вперед", + "在新窗口中查词": "Проверка слов в новом окне" } \ No newline at end of file diff --git a/py/files/lang/sv.json b/py/files/lang/sv.json index 9ba3c366..464a813f 100644 --- a/py/files/lang/sv.json +++ b/py/files/lang/sv.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 textritfunktionskrok", "Win32字符串函数钩子": "Win32 strängfunktionskrok", "额外的钩子": "Extra krokar", - "自动前进": "Automatisk framåt" + "自动前进": "Automatisk framåt", + "在新窗口中查词": "Sök efter ord i ett nytt fönster" } \ No newline at end of file diff --git a/py/files/lang/th.json b/py/files/lang/th.json index 3afbf8ff..bc6f7a4e 100644 --- a/py/files/lang/th.json +++ b/py/files/lang/th.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 วาดคำฟังก์ชันตะขอ", "Win32字符串函数钩子": "Win32 ฟังก์ชั่นสตริงตะขอ", "额外的钩子": "ตะขอเพิ่มเติม", - "自动前进": "เดินหน้าอัตโนมัติ" + "自动前进": "เดินหน้าอัตโนมัติ", + "在新窗口中查词": "ค้นหาคำในหน้าต่างใหม่" } \ No newline at end of file diff --git a/py/files/lang/tr.json b/py/files/lang/tr.json index 42ed55a1..84532306 100644 --- a/py/files/lang/tr.json +++ b/py/files/lang/tr.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 metin çizim fonksiyonu çubuğu", "Win32字符串函数钩子": "Win32 string fonksiyonu", "额外的钩子": "Ekstra hücreler", - "自动前进": "Otomatik İleri" + "自动前进": "Otomatik İleri", + "在新窗口中查词": "Yeni pencerede kelimeler arayın" } \ No newline at end of file diff --git a/py/files/lang/uk.json b/py/files/lang/uk.json index e235aa8a..91afb377 100644 --- a/py/files/lang/uk.json +++ b/py/files/lang/uk.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Хук функції малювання тексту Win32", "Win32字符串函数钩子": "Хук функції рядка Win32", "额外的钩子": "Додаткові хаки", - "自动前进": "Автоматично вперед" + "自动前进": "Автоматично вперед", + "在新窗口中查词": "Пошук слів у новому вікні" } \ No newline at end of file diff --git a/py/files/lang/vi.json b/py/files/lang/vi.json index 87104d02..25150953 100644 --- a/py/files/lang/vi.json +++ b/py/files/lang/vi.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "Win32 Chức năng vẽ văn bản Hook", "Win32字符串函数钩子": "Win32 Chuỗi chức năng Hook", "额外的钩子": "Thêm móc", - "自动前进": "Tự động chuyển tiếp" + "自动前进": "Tự động chuyển tiếp", + "在新窗口中查词": "Tra từ trong cửa sổ mới" } \ No newline at end of file diff --git a/py/files/lang/zh.json b/py/files/lang/zh.json index d9c1e0a2..771b1ffe 100644 --- a/py/files/lang/zh.json +++ b/py/files/lang/zh.json @@ -793,5 +793,6 @@ "Win32文字绘制函数钩子": "", "Win32字符串函数钩子": "", "额外的钩子": "", - "自动前进": "" + "自动前进": "", + "在新窗口中查词": "" } \ No newline at end of file