1
1
#include " qtcommon.h"
2
2
#include " devtools.h"
3
+ #include < QFileDialog>
4
+ #include < QMouseEvent>
3
5
#include < ShlObj.h>
4
6
5
7
extern const wchar_t * TRANSLATION_ERROR;
6
- extern Synchronized<std::wstring> translateTo, translateFrom;
7
- extern QFormLayout* display;
8
- extern Settings settings;
9
-
10
- const char * TRANSLATION_PROVIDER = " DevTools DeepL Translate" ;
11
- const char * GET_API_KEY_FROM = nullptr ;
12
- bool translateSelectedOnly = true , rateLimitAll = false , rateLimitSelected = false , useCache = true ;
13
- int tokenCount = 30 , tokenRestoreDelay = 60000 , maxSentenceSize = 2500 ;
14
-
15
8
extern const char * CHROME_LOCATION;
16
9
extern const char * START_DEVTOOLS;
17
10
extern const char * STOP_DEVTOOLS;
@@ -20,9 +13,18 @@ extern const char* DEVTOOLS_STATUS;
20
13
extern const char * AUTO_START;
21
14
extern const wchar_t * ERROR_START_CHROME;
22
15
16
+ extern Synchronized<std::wstring> translateTo, translateFrom;
17
+ extern QFormLayout* display;
18
+ extern Settings settings;
19
+
20
+ const char * TRANSLATION_PROVIDER = " DevTools DeepL Translate" ;
21
+ const char * GET_API_KEY_FROM = nullptr ;
22
+ bool translateSelectedOnly = true , rateLimitAll = false , rateLimitSelected = false , useCache = true , useFilter = true ;
23
+ int tokenCount = 30 , tokenRestoreDelay = 60000 , maxSentenceSize = 2500 ;
24
+
23
25
QStringList languages
24
26
{
25
- " Chinese (simplified) : zh" ,
27
+ " Chinese: zh" ,
26
28
" Dutch: nl" ,
27
29
" English: en" ,
28
30
" French: fr" ,
@@ -51,14 +53,27 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
51
53
if (std::filesystem::exists (programFiles)) chromePath = S (programFiles);
52
54
}
53
55
auto chromePathEdit = new QLineEdit (chromePath);
56
+ static struct : QObject
57
+ {
58
+ bool eventFilter (QObject* object, QEvent* event)
59
+ {
60
+ if (auto mouseEvent = dynamic_cast <QMouseEvent*>(event))
61
+ if (mouseEvent->button () == Qt::LeftButton)
62
+ if (QString chromePath = QFileDialog::getOpenFileName (nullptr , TRANSLATION_PROVIDER, " /" , " Chrome (*.exe)" ); !chromePath.isEmpty ())
63
+ ((QLineEdit*)object)->setText (chromePath);
64
+ return false ;
65
+ }
66
+ } chromeSelector;
67
+ chromePathEdit->installEventFilter (&chromeSelector);
54
68
QObject::connect (chromePathEdit, &QLineEdit::textChanged, [chromePathEdit](QString path) { settings.setValue (CHROME_LOCATION, path); });
55
69
display->addRow (CHROME_LOCATION, chromePathEdit);
56
70
auto statusLabel = new QLabel (" Stopped" );
57
71
auto startButton = new QPushButton (START_DEVTOOLS), stopButton = new QPushButton (STOP_DEVTOOLS);
58
72
auto headlessCheck = new QCheckBox ();
59
73
headlessCheck->setChecked (settings.value (HEADLESS_MODE, true ).toBool ());
60
74
QObject::connect (headlessCheck, &QCheckBox::clicked, [](bool headless) { settings.setValue (HEADLESS_MODE, headless); });
61
- QObject::connect (startButton, &QPushButton::clicked, [statusLabel, chromePathEdit, headlessCheck] {
75
+ QObject::connect (startButton, &QPushButton::clicked, [statusLabel, chromePathEdit, headlessCheck]
76
+ {
62
77
DevTools::Start (
63
78
S (chromePathEdit->text ()),
64
79
[statusLabel](QString status)
@@ -79,8 +94,10 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
79
94
})
80
95
if (auto userAgent = Copy (JSON::Parse (httpRequest.response )[L" User-Agent" ].String ()))
81
96
if (userAgent->find (L" Headless" ) != std::string::npos)
82
- DevTools::SendRequest (L" Network.setUserAgentOverride" ,
83
- FormatString (LR"( {"userAgent":"%s"})" , userAgent->replace (userAgent->find (L" Headless" ), 8 , L" " )));
97
+ DevTools::SendRequest (
98
+ " Network.setUserAgentOverride" ,
99
+ FormatString (LR"( {"userAgent":"%s"})" , userAgent->replace (userAgent->find (L" Headless" ), 8 , L" " ))
100
+ );
84
101
}).detach ();
85
102
},
86
103
headlessCheck->isChecked ()
@@ -91,14 +108,14 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
91
108
buttons->addWidget (startButton);
92
109
buttons->addWidget (stopButton);
93
110
display->addRow (HEADLESS_MODE, headlessCheck);
94
- auto autoStartButton = new QCheckBox ();
95
- autoStartButton ->setChecked (settings.value (AUTO_START, false ).toBool ());
96
- QObject::connect (autoStartButton , &QCheckBox::clicked, [](bool autoStart) { settings.setValue (AUTO_START, autoStart); });
97
- display->addRow (AUTO_START, autoStartButton );
111
+ auto autoStartCheck = new QCheckBox ();
112
+ autoStartCheck ->setChecked (settings.value (AUTO_START, false ).toBool ());
113
+ QObject::connect (autoStartCheck , &QCheckBox::clicked, [](bool autoStart) { settings.setValue (AUTO_START, autoStart); });
114
+ display->addRow (AUTO_START, autoStartCheck );
98
115
display->addRow (buttons);
99
116
statusLabel->setFrameStyle (QFrame::Panel | QFrame::Sunken);
100
117
display->addRow (DEVTOOLS_STATUS, statusLabel);
101
- if (autoStartButton ->isChecked ()) QMetaObject::invokeMethod (startButton, &QPushButton::click, Qt::QueuedConnection);
118
+ if (autoStartCheck ->isChecked ()) QMetaObject::invokeMethod (startButton, &QPushButton::click, Qt::QueuedConnection);
102
119
}
103
120
break ;
104
121
case DLL_PROCESS_DETACH:
@@ -116,16 +133,20 @@ std::pair<bool, std::wstring> Translate(const std::wstring& text)
116
133
// DevTools can't handle concurrent translations yet
117
134
static std::mutex translationMutex;
118
135
std::scoped_lock lock (translationMutex);
119
- DevTools::SendRequest (L" Page.navigate" , FormatString (LR"( {"url":"https://www.deepl.com/translator#%s/%s/%s"})" , translateFrom.Copy (), translateTo.Copy (), Escape (text)));
136
+ DevTools::SendRequest (" Page.navigate" , FormatString (LR"( {"url":"https://www.deepl.com/translator#any/%s/%s"})" , translateTo.Copy (), Escape (text)));
137
+
138
+ if (translateFrom.Copy () != autoDetectLanguage)
139
+ DevTools::SendRequest (" Runtime.evaluate" , FormatString (LR"( {"expression":"
140
+ document.querySelector('.lmt__language_select--source').querySelector('button').click(),
141
+ document.evaluate(`//button[contains(text(),'%s')]`,document.querySelector('.lmt__language_select__menu'),null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue.click()
142
+ "})" , S (std::find_if (languages.begin (), languages.end (), [end = S (translateFrom.Copy ())](const QString& language) { return language.endsWith (end); })->split (" :" )[0 ])));
143
+
120
144
for (int retry = 0 ; ++retry < 100 ; Sleep (100 ))
121
- if (auto translation = Copy (
122
- DevTools::SendRequest (L" Runtime.evaluate" , LR"( {"expression":"document.querySelector('#target-dummydiv').innerHTML","returnByValue":true})" )[L" result" ][L" value" ].String ()
123
- )) if (!translation->empty ()) return { true , translation.value () };
124
- if (auto errorMessage = Copy (
125
- DevTools::SendRequest (
126
- L" Runtime.evaluate" ,
127
- LR"( {"expression":"document.querySelector('div.lmt__system_notification').innerHTML","returnByValue":true})"
128
- )[L" result" ][L" value" ].String ()
129
- )) return { false , FormatString (L" %s: %s" , TRANSLATION_ERROR, errorMessage.value ()) };
145
+ if (auto translation = Copy (DevTools::SendRequest (" Runtime.evaluate" ,
146
+ LR"( {"expression":"document.querySelector('#target-dummydiv').innerHTML.trim() ","returnByValue":true})"
147
+ )[L" result" ][L" value" ].String ())) if (!translation->empty ()) return { true , translation.value () };
148
+ if (auto errorMessage = Copy (DevTools::SendRequest (" Runtime.evaluate" ,
149
+ LR"( {"expression":"document.querySelector('div.lmt__system_notification').innerHTML","returnByValue":true})"
150
+ )[L" result" ][L" value" ].String ())) return { false , FormatString (L" %s: %s" , TRANSLATION_ERROR, errorMessage.value ()) };
130
151
return { false , TRANSLATION_ERROR };
131
152
}
0 commit comments