From ac4cec9708b3b07c1e0e9181227c06c94c424aee Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Mon, 16 Mar 2020 02:56:04 -0600 Subject: [PATCH] add gcp translator and add continous dialog for translators and update language lists and make extension dialogs uncloseable without properly removing the extension --- GUI/extenwindow.cpp | 95 +++++++++++----------- GUI/extenwindow.h | 6 -- GUI/mainwindow.cpp | 2 +- deploy.ps1 | 1 + extensions/CMakeLists.txt | 2 + extensions/bingtranslate.cpp | 47 ++++++++--- extensions/blockmarkup.h | 4 +- extensions/extrawindow.cpp | 2 +- extensions/googlecloudtranslate.cpp | 119 ++++++++++++++++++++++++++++ extensions/googletranslate.cpp | 61 ++++++++++++-- extensions/lua.cpp | 11 ++- extensions/network.cpp | 5 +- extensions/regexfilter.cpp | 3 +- extensions/regexfilter.ui | 86 ++++++++++---------- extensions/threadlinker.cpp | 11 ++- extensions/translatewrapper.cpp | 69 ++++++++-------- text.cpp | 35 ++++---- 17 files changed, 375 insertions(+), 184 deletions(-) create mode 100644 extensions/googlecloudtranslate.cpp diff --git a/GUI/extenwindow.cpp b/GUI/extenwindow.cpp index 0948b2a..60bce9c 100644 --- a/GUI/extenwindow.cpp +++ b/GUI/extenwindow.cpp @@ -15,18 +15,21 @@ extern const char* CONFIRM_EXTENSION_OVERWRITE; extern const char* EXTENSION_WRITE_ERROR; extern const char* EXTEN_WINDOW_INSTRUCTIONS; -constexpr auto DEFAULT_EXTENSIONS = u8"Remove Repeated Characters>Remove Repeated Phrases>Regex Filter>Copy to Clipboard>Bing Translate>Extra Window>Extra Newlines"; - namespace { + constexpr auto EXTEN_SAVE_FILE = u8"SavedExtensions.txt"; + constexpr auto DEFAULT_EXTENSIONS = u8"Remove Repeated Characters>Remove Repeated Phrases>Regex Filter>Copy to Clipboard>Bing Translate>Extra Window>Extra Newlines"; + struct Extension { std::wstring name; wchar_t* (*callback)(wchar_t*, const InfoForExtension*); }; + Ui::ExtenWindow ui; concurrency::reader_writer_lock extenMutex; std::vector extensions; + ExtenWindow* This = nullptr; bool Load(QString extenName) { @@ -62,6 +65,39 @@ namespace extensions.push_back(*std::find_if(::extensions.begin(), ::extensions.end(), [&](Extension extension) { return extension.name == S(extenName); })); ::extensions = extensions; } + + void Sync() + { + ui.extenList->clear(); + QTextFile extenSaveFile(EXTEN_SAVE_FILE, QIODevice::WriteOnly | QIODevice::Truncate); + concurrency::reader_writer_lock::scoped_lock_read readLock(extenMutex); + for (auto extension : extensions) + { + ui.extenList->addItem(S(extension.name)); + extenSaveFile.write((S(extension.name) + ">").toUtf8()); + } + } + + void Add(QFileInfo extenFile) + { + if (extenFile.suffix() == "dll") + { + if (extenFile.absolutePath() != QDir::currentPath()) + { + if (QFile::exists(extenFile.fileName()) && QMessageBox::question(This, EXTENSIONS, CONFIRM_EXTENSION_OVERWRITE) == QMessageBox::Yes) QFile::remove(extenFile.fileName()); + if (!QFile::copy(extenFile.absoluteFilePath(), extenFile.fileName())) QMessageBox::warning(This, EXTENSIONS, EXTENSION_WRITE_ERROR); + } + if (Load(extenFile.completeBaseName())) return Sync(); + } + QMessageBox::information(This, EXTENSIONS, QString(INVALID_EXTENSION).arg(extenFile.fileName())); + } + + void OpenMenu(QPoint point) + { + QAction addExtension(ADD_EXTENSION); + if (QMenu::exec({ &addExtension }, ui.extenList->mapToGlobal(point), nullptr, This)) + if (QString extenFile = QFileDialog::getOpenFileName(This, ADD_EXTENSION, ".", EXTENSIONS + QString(" (*.dll)")); !extenFile.isEmpty()) Add(extenFile); + } } bool DispatchSentenceToExtensions(std::wstring& sentence, const InfoForExtension* sentenceInfo) @@ -84,57 +120,22 @@ void CleanupExtensions() } ExtenWindow::ExtenWindow(QWidget* parent) : - QMainWindow(parent, Qt::WindowCloseButtonHint), - ui(new Ui::ExtenWindow) + QMainWindow(parent, Qt::WindowCloseButtonHint) { - ui->setupUi(this); - - connect(ui->extenList, &QListWidget::customContextMenuRequested, [this](QPoint point) - { - if (QMenu(this).exec({ std::make_unique(ADD_EXTENSION).get() }, ui->extenList->mapToGlobal(point))) - if (QString extenFile = QFileDialog::getOpenFileName(this, ADD_EXTENSION, ".", EXTENSIONS + QString(" (*.dll)")); !extenFile.isEmpty()) Add(extenFile); - }); - - ui->vboxLayout->addWidget(new QLabel(EXTEN_WINDOW_INSTRUCTIONS, this)); + This = this; + ui.setupUi(this); + ui.vboxLayout->addWidget(new QLabel(EXTEN_WINDOW_INSTRUCTIONS, this)); setWindowTitle(EXTENSIONS); - ui->extenList->installEventFilter(this); + connect(ui.extenList, &QListWidget::customContextMenuRequested, OpenMenu); + ui.extenList->installEventFilter(this); if (!QFile::exists(EXTEN_SAVE_FILE)) QTextFile(EXTEN_SAVE_FILE, QIODevice::WriteOnly).write(DEFAULT_EXTENSIONS); for (auto extenName : QString(QTextFile(EXTEN_SAVE_FILE, QIODevice::ReadOnly).readAll()).split(">")) Load(extenName); Sync(); } -ExtenWindow::~ExtenWindow() -{ - delete ui; -} - -void ExtenWindow::Add(QFileInfo extenFile) -{ - if (extenFile.suffix() == "dll") - { - if (extenFile.absolutePath() != QDir::currentPath()) - { - if (QFile::exists(extenFile.fileName()) && QMessageBox::question(this, EXTENSIONS, CONFIRM_EXTENSION_OVERWRITE) == QMessageBox::Yes) QFile::remove(extenFile.fileName()); - if (!QFile::copy(extenFile.absoluteFilePath(), extenFile.fileName())) QMessageBox::warning(this, EXTENSIONS, EXTENSION_WRITE_ERROR); - } - if (Load(extenFile.completeBaseName())) return Sync(); - } - QMessageBox::information(this, EXTENSIONS, QString(INVALID_EXTENSION).arg(extenFile.fileName())); -} - -void ExtenWindow::Sync() -{ - ui->extenList->clear(); - QTextFile extenSaveFile(EXTEN_SAVE_FILE, QIODevice::WriteOnly | QIODevice::Truncate); - concurrency::reader_writer_lock::scoped_lock_read readLock(extenMutex); - for (auto extension : extensions) - { - ui->extenList->addItem(S(extension.name)); - extenSaveFile.write((S(extension.name) + ">").toUtf8()); - } -} +ExtenWindow::~ExtenWindow() = default; bool ExtenWindow::eventFilter(QObject* target, QEvent* event) { @@ -142,7 +143,7 @@ bool ExtenWindow::eventFilter(QObject* target, QEvent* event) if (event->type() == QEvent::ChildRemoved) { QStringList extenNames; - for (int i = 0; i < ui->extenList->count(); ++i) extenNames.push_back(ui->extenList->item(i)->text()); + for (int i = 0; i < ui.extenList->count(); ++i) extenNames.push_back(ui.extenList->item(i)->text()); Reorder(extenNames); Sync(); } @@ -151,9 +152,9 @@ bool ExtenWindow::eventFilter(QObject* target, QEvent* event) void ExtenWindow::keyPressEvent(QKeyEvent* event) { - if (event->key() == Qt::Key_Delete && ui->extenList->currentItem()) + if (event->key() == Qt::Key_Delete && ui.extenList->currentItem()) { - Unload(ui->extenList->currentIndex().row()); + Unload(ui.extenList->currentIndex().row()); Sync(); } } diff --git a/GUI/extenwindow.h b/GUI/extenwindow.h index 67c8c38..eb52395 100644 --- a/GUI/extenwindow.h +++ b/GUI/extenwindow.h @@ -23,14 +23,8 @@ public: ~ExtenWindow(); private: - inline static constexpr auto EXTEN_SAVE_FILE = u8"SavedExtensions.txt"; - - void Add(QFileInfo extenFile); - void Sync(); bool eventFilter(QObject* target, QEvent* event) override; void keyPressEvent(QKeyEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; - - Ui::ExtenWindow* ui; }; diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 38c5779..19f2715 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -74,8 +74,8 @@ namespace enum LaunchWithJapaneseLocale { PROMPT, ALWAYS, NEVER }; + Ui::MainWindow ui; std::atomic selectedProcessId = 0; - Ui::MainWindow ui{}; ExtenWindow* extenWindow = nullptr; std::unordered_set alreadyAttached; bool autoAttach = false, autoAttachSavedOnly = true; diff --git a/deploy.ps1 b/deploy.ps1 index 936141f..617d74b 100644 --- a/deploy.ps1 +++ b/deploy.ps1 @@ -40,6 +40,7 @@ foreach ($language in @{ "Extra Newlines.dll", "Extra Window.dll", "Google Translate.dll", + "Google Cloud Translate.dll", "Lua.dll", "Regex Filter.dll", "Remove Repeated Characters.dll", diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 29e8652..6c1acd3 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(Copy\ to\ Clipboard MODULE copyclipboard.cpp extensionimpl.cpp) add_library(Extra\ Newlines MODULE extranewlines.cpp extensionimpl.cpp) add_library(Extra\ Window MODULE extrawindow.cpp extensionimpl.cpp) add_library(Google\ Translate MODULE googletranslate.cpp translatewrapper.cpp network.cpp extensionimpl.cpp) +add_library(Google\ Cloud\ Translate MODULE googlecloudtranslate.cpp translatewrapper.cpp network.cpp extensionimpl.cpp) add_library(Lua MODULE lua.cpp extensionimpl.cpp) add_library(Regex\ Filter MODULE regexfilter.cpp extensionimpl.cpp) add_library(Remove\ Repeated\ Characters MODULE removerepeatchar.cpp extensionimpl.cpp) @@ -21,6 +22,7 @@ add_library(Thread\ Linker MODULE threadlinker.cpp extensionimpl.cpp) target_link_libraries(Bing\ Translate winhttp Qt5::Widgets) target_link_libraries(Extra\ Window Qt5::Widgets) target_link_libraries(Google\ Translate winhttp Qt5::Widgets) +target_link_libraries(Google\ Cloud\ Translate winhttp Qt5::Widgets) target_link_libraries(Lua lua53 Qt5::Widgets) target_link_libraries(Regex\ Filter Qt5::Widgets) target_link_libraries(Thread\ Linker Qt5::Widgets) diff --git a/extensions/bingtranslate.cpp b/extensions/bingtranslate.cpp index 7a1b784..fe7fde3 100644 --- a/extensions/bingtranslate.cpp +++ b/extensions/bingtranslate.cpp @@ -6,54 +6,79 @@ extern const wchar_t* TRANSLATION_ERROR; extern Synchronized translateTo; -const char* TRANSLATION_PROVIDER = "Bing"; +const char* TRANSLATION_PROVIDER = "Bing Translate"; QStringList languages { + "Afrikaans: af", "Arabic: ar", - "Bosnian: bs-Latn", + "Bangla: bn", + "Bosnian: bs", "Bulgarian: bg", + "Cantonese (Traditional): yue", "Catalan: ca", - "Chinese(Simplified): zh-CHS", - "Chinese(Traditional): zh-CHT", + "Chinese (Simplified): zh-Hans", + "Chinese (Traditional): zh-Hant", "Croatian: hr", "Czech: cs", "Danish: da", "Dutch: nl", "English: en", "Estonian: et", + "Fijian: fj", + "Filipino: fil", "Finnish: fi", "French: fr", "German: de", "Greek: el", + "Haitian Creole: ht", "Hebrew: he", "Hindi: hi", + "Hmong Daw: mww", "Hungarian: hu", + "Icelandic: is", "Indonesian: id", + "Irish: ga", "Italian: it", "Japanese: ja", - "Klingon: tlh", + "Kannada: kn", + "Klingon (Latin): tlh-Latn", + "Klingon (pIqaD): tlh-Piqd", "Korean: ko", "Latvian: lv", "Lithuanian: lt", + "Malagasy: mg", "Malay: ms", + "Malayalam: ml", "Maltese: mt", - "Norwegian: no", + "Maori: mi", + "Norwegian: nb", "Persian: fa", "Polish: pl", - "Portuguese: pt", + "Portuguese (Brazil): pt", + "Portuguese (Portugal): pt-pt", + "Punjabi: pa", + "Querétaro Otomi: otq", "Romanian: ro", "Russian: ru", - "Serbian: sr-Cyrl", + "Samoan: sm", + "Serbian (Cyrillic): sr-Cyrl", + "Serbian (Latin): sr-Latn", "Slovak: sk", "Slovenian: sl", "Spanish: es", + "Swahili: sw", "Swedish: sv", + "Tahitian: ty", + "Tamil: ta", + "Telugu: te", "Thai: th", + "Tongan: to", "Turkish: tr", - "Ukranian: uk", + "Ukrainian: uk", "Urdu: ur", "Vietnamese: vi", - "Welsh: cy" + "Welsh: cy", + "Yucatec Maya: yua" }; std::pair Translate(const std::wstring& text) @@ -65,7 +90,7 @@ std::pair Translate(const std::wstring& text) FormatString(L"/ttranslatev3?fromLang=auto-detect&to=%s&text=%s", translateTo->c_str(), Escape(text)).c_str() }) // Response formatted as JSON: translation starts with text":" and ends with ","to - if (std::wsmatch results; std::regex_search(httpRequest.response, results, std::wregex(L"text\":\"(.+)\"\\,\"to"))) return { true, results[1] }; + if (std::wsmatch results; std::regex_search(httpRequest.response, results, std::wregex(L"text\":\"(.+)\",\"t"))) return { true, results[1] }; else return { false, TRANSLATION_ERROR }; else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) }; } diff --git a/extensions/blockmarkup.h b/extensions/blockmarkup.h index 05eb77a..132863f 100644 --- a/extensions/blockmarkup.h +++ b/extensions/blockmarkup.h @@ -7,8 +7,8 @@ template // class BlockMarkupIterator { public: - BlockMarkupIterator(const std::istream& it, const std::basic_string_view(&delimiters)[delimiterCount]) : - streambuf(*it.rdbuf()) + BlockMarkupIterator(const std::istream& stream, const std::basic_string_view(&delimiters)[delimiterCount]) : + streambuf(*stream.rdbuf()) { std::copy_n(delimiters, delimiterCount, this->delimiters.begin()); } diff --git a/extensions/extrawindow.cpp b/extensions/extrawindow.cpp index c88d28b..b1c75a4 100644 --- a/extensions/extrawindow.cpp +++ b/extensions/extrawindow.cpp @@ -444,7 +444,7 @@ private: QStringList currentInflectionsUsed = inflectionsUsed; currentInflectionsUsed.push_front(inflection.name); QString root = inflection.root; - for (int i = 0; i < root.size(); ++i) if (root[i].isDigit()) root.replace(i, 1, match.captured(root[i].unicode() - '0')); + for (int i = 0; i < root.size(); ++i) if (root[i].isDigit()) root.replace(i, 1, match.captured(root[i].digitValue())); for (const auto& definition : LookupDefinitions(root, foundDefinitions, currentInflectionsUsed)) results.push_back(definition); } return results; diff --git a/extensions/googlecloudtranslate.cpp b/extensions/googlecloudtranslate.cpp new file mode 100644 index 0000000..055e3da --- /dev/null +++ b/extensions/googlecloudtranslate.cpp @@ -0,0 +1,119 @@ +#include "qtcommon.h" +#include "extension.h" +#include "network.h" + +extern const wchar_t* TRANSLATION_ERROR; +extern const char* API_KEY; + +extern QFormLayout* display; +extern QSettings* settings; +extern Synchronized translateTo; + +const char* TRANSLATION_PROVIDER = "Google Cloud Translate"; +QStringList languages +{ + "Afrikaans: af", + "Arabic: ar", + "Albanian: sq", + "Belarusian: be", + "Bengali: bn", + "Bosnian: bs", + "Bulgarian: bg", + "Catalan: ca", + "Chinese(Simplified): zh-CH", + "Chinese(Traditional): zh-TW", + "Croatian: hr", + "Czech: cs", + "Danish: da", + "Dutch: nl", + "English: en", + "Esperanto: eo", + "Estonian: et", + "Filipino: tl", + "Finnish: fi", + "French: fr", + "Galician: gl", + "German: de", + "Greek: el", + "Hebrew: iw", + "Hindi: hi", + "Hungarian: hu", + "Icelandic: is", + "Indonesian: id", + "Irish: ga", + "Italian: it", + "Japanese: ja", + "Klingon: tlh", + "Korean: ko", + "Latin: la", + "Latvian: lv", + "Lithuanian: lt", + "Macedonian: mk", + "Malay: ms", + "Maltese: mt", + "Norwegian: no", + "Persian: fa", + "Polish: pl", + "Portuguese: pt", + "Romanian: ro", + "Russian: ru", + "Serbian: sr", + "Slovak: sk", + "Slovenian: sl", + "Somali: so", + "Spanish: es", + "Swahili: sw", + "Swedish: sv", + "Thai: th", + "Turkish: tr", + "Ukranian: uk", + "Urdu: ur", + "Vietnamese: vi", + "Welsh: cy", + "Yiddish: yi", + "Zulu: zu" +}; + +Synchronized key; + +BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + auto keyInput = new QLineEdit(settings->value(API_KEY).toString()); + key->assign(S(keyInput->text())); + QObject::connect(keyInput, &QLineEdit::textChanged, [](QString key) { settings->setValue(API_KEY, S(::key->assign(S(key)))); }); + display->addRow(API_KEY, keyInput); + auto googleCloudInfo = new QLabel( + "https://codelabs.developers.google.com/codelabs/cloud-translation-intro" + ); + googleCloudInfo->setOpenExternalLinks(true); + display->addRow(googleCloudInfo); + } + break; + case DLL_PROCESS_DETACH: + { + } + break; + } + return TRUE; +} + +std::pair Translate(const std::wstring& text) +{ + + if (HttpRequest httpRequest{ + L"Mozilla/5.0 Textractor", + L"translation.googleapis.com", + L"GET", + FormatString(L"/language/translate/v2?format=text&q=%s&target=%s&key=%s", Escape(text), translateTo->c_str(), key->c_str()).c_str() + }) + { + // Response formatted as JSON: starts with "translatedText": " and translation is enclosed in quotes followed by a comma + if (std::wsmatch results; std::regex_search(httpRequest.response, results, std::wregex(L"\"translatedText\": \"(.+?)\","))) return { true, results[1] }; + return { false, TRANSLATION_ERROR }; + } + else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) }; +} diff --git a/extensions/googletranslate.cpp b/extensions/googletranslate.cpp index 1722ace..e808ffd 100644 --- a/extensions/googletranslate.cpp +++ b/extensions/googletranslate.cpp @@ -7,19 +7,26 @@ extern const wchar_t* TRANSLATION_ERROR; extern Synchronized translateTo; -const char* TRANSLATION_PROVIDER = "Google"; +const char* TRANSLATION_PROVIDER = "Google Translate"; QStringList languages { "Afrikaans: af", - "Arabic: ar", "Albanian: sq", + "Amharic: am", + "Arabic: ar", + "Armenian: hy", + "Azerbaijani: az", + "Basque: eu", "Belarusian: be", "Bengali: bn", "Bosnian: bs", "Bulgarian: bg", "Catalan: ca", - "Chinese(Simplified): zh-CH", - "Chinese(Traditional): zh-TW", + "Cebuano: ceb", + "Chichewa: ny", + "Chinese (Simplified): zh", + "Chinese (Traditional): zh-TW", + "Corsican: co", "Croatian: hr", "Czech: cs", "Danish: da", @@ -30,45 +37,87 @@ QStringList languages "Filipino: tl", "Finnish: fi", "French: fr", + "Frisian: fy", "Galician: gl", + "Georgian: ka", "German: de", "Greek: el", + "Gujarati: gu", + "Haitian Creole: ht", + "Hausa: ha", + "Hawaiian: haw", "Hebrew: iw", "Hindi: hi", + "Hmong: hmn", "Hungarian: hu", "Icelandic: is", + "Igbo: ig", "Indonesian: id", "Irish: ga", "Italian: it", "Japanese: ja", - "Klingon: tlh", + "Javanese: jw", + "Kannada: kn", + "Kazakh: kk", + "Khmer: km", + "Kinyarwanda: rw", "Korean: ko", + "Kurdish (Kurmanji): ku", + "Kyrgyz: ky", + "Lao: lo", "Latin: la", "Latvian: lv", "Lithuanian: lt", + "Luxembourgish: lb", "Macedonian: mk", + "Malagasy: mg", "Malay: ms", + "Malayalam: ml", "Maltese: mt", + "Maori: mi", + "Marathi: mr", + "Mongolian: mn", + "Myanmar (Burmese): my", + "Nepali: ne", "Norwegian: no", + "Odia (Oriya): or", + "Pashto: ps", "Persian: fa", "Polish: pl", "Portuguese: pt", + "Punjabi: pa", "Romanian: ro", "Russian: ru", + "Samoan: sm", + "Scots Gaelic: gd", "Serbian: sr", + "Sesotho: st", + "Shona: sn", + "Sindhi: sd", + "Sinhala: si", "Slovak: sk", "Slovenian: sl", "Somali: so", "Spanish: es", + "Sundanese: su", "Swahili: sw", "Swedish: sv", + "Tajik: tg", + "Tamil: ta", + "Tatar: tt", + "Telugu: te", "Thai: th", "Turkish: tr", - "Ukranian: uk", + "Turkmen: tk", + "Ukrainian: uk", "Urdu: ur", + "Uyghur: ug", + "Uzbek: uz", "Vietnamese: vi", "Welsh: cy", + "Xhosa: xh", "Yiddish: yi", + "Yoruba: yo", "Zulu: zu" }; diff --git a/extensions/lua.cpp b/extensions/lua.cpp index f636b74..5af8012 100644 --- a/extensions/lua.cpp +++ b/extensions/lua.cpp @@ -41,10 +41,11 @@ bool logErrors = true; Synchronized script; std::atomic revCount = 0; -class Window : public QMainWindow +class Window : public QDialog { public: Window() + : QDialog(nullptr, Qt::WindowMinMaxButtonsHint) { connect(&loadButton, &QPushButton::clicked, this, &Window::LoadScript); @@ -53,7 +54,6 @@ public: layout.addWidget(&loadButton); resize(800, 600); - setCentralWidget(¢ralWidget); setWindowTitle("Lua"); QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection); } @@ -76,10 +76,9 @@ private: QTextFile(LUA_SAVE_FILE, QIODevice::WriteOnly | QIODevice::Truncate).write(scriptEditor.toPlainText().toUtf8()); } - QWidget centralWidget{ this }; - QHBoxLayout layout{ ¢ralWidget }; - QPlainTextEdit scriptEditor{ QTextFile(LUA_SAVE_FILE, QIODevice::ReadOnly).readAll(), ¢ralWidget }; - QPushButton loadButton{ LOAD_LUA_SCRIPT, ¢ralWidget }; + QHBoxLayout layout{ this }; + QPlainTextEdit scriptEditor{ QTextFile(LUA_SAVE_FILE, QIODevice::ReadOnly).readAll(), this }; + QPushButton loadButton{ LOAD_LUA_SCRIPT, this }; } window; bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) diff --git a/extensions/network.cpp b/extensions/network.cpp index fc7e9a9..e45fdac 100644 --- a/extensions/network.cpp +++ b/extensions/network.cpp @@ -56,11 +56,12 @@ void Unescape(std::wstring& text) { if (text[i] == L'\\') { - text[i] = 0x200b; - if (text[i + 1] == L'r') text[i + 1] = 0x200b; // for some reason \r gets displayed as a newline + text[i] = 0; + if (text[i + 1] == L'r') text[i + 1] = 0; // for some reason \r gets displayed as a newline if (text[i + 1] == L'n') text[i + 1] = L'\n'; if (text[i + 1] == L't') text[i + 1] = L'\t'; if (text[i + 1] == L'\\') ++i; } } + text.erase(std::remove(text.begin(), text.end(), 0), text.end()); } diff --git a/extensions/regexfilter.cpp b/extensions/regexfilter.cpp index 7a8f187..d8814a9 100644 --- a/extensions/regexfilter.cpp +++ b/extensions/regexfilter.cpp @@ -15,10 +15,11 @@ std::optional regex; std::shared_mutex m; DWORD (*GetSelectedProcessId)() = nullptr; -class Window : public QMainWindow +class Window : public QDialog { public: Window() + : QDialog(nullptr, Qt::WindowMinMaxButtonsHint) { ui.setupUi(this); diff --git a/extensions/regexfilter.ui b/extensions/regexfilter.ui index 4771596..5bdb297 100644 --- a/extensions/regexfilter.ui +++ b/extensions/regexfilter.ui @@ -1,7 +1,7 @@ FilterWindow - + 0 @@ -10,49 +10,47 @@ 105 - - - - - - - - - - - - Qt::AlignCenter - - - - - - - Save - - - - - - - <a href="https://regexr.com">regexr.com</a> - - - Qt::RichText - - - Qt::AlignCenter - - - true - - - Qt::TextBrowserInteraction - - - - - + + + + + + + + + + + Qt::AlignCenter + + + + + + + Save + + + + + + + <a href="https://regexr.com">regexr.com</a> + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + Qt::TextBrowserInteraction + + + + diff --git a/extensions/threadlinker.cpp b/extensions/threadlinker.cpp index d7ed82e..5ed95b1 100644 --- a/extensions/threadlinker.cpp +++ b/extensions/threadlinker.cpp @@ -11,17 +11,17 @@ extern const char* HEXADECIMAL; std::unordered_map> linkedTextHandles; std::shared_mutex m; -class Window : public QMainWindow +class Window : public QDialog { public: Window() + : QDialog(nullptr, Qt::WindowMinMaxButtonsHint) { connect(&linkButton, &QPushButton::clicked, this, &Window::Link); layout.addWidget(&linkList); layout.addWidget(&linkButton); - setCentralWidget(¢ralWidget); setWindowTitle(THREAD_LINKER); QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection); } @@ -51,10 +51,9 @@ private: } } - QWidget centralWidget{ this }; - QHBoxLayout layout{ ¢ralWidget }; - QListWidget linkList{ ¢ralWidget }; - QPushButton linkButton{ LINK, ¢ralWidget }; + QHBoxLayout layout{ this }; + QListWidget linkList{ this }; + QPushButton linkButton{ LINK, this }; } window; bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) diff --git a/extensions/translatewrapper.cpp b/extensions/translatewrapper.cpp index 8234a3b..06acaaa 100644 --- a/extensions/translatewrapper.cpp +++ b/extensions/translatewrapper.cpp @@ -4,12 +4,11 @@ #include "network.h" #include #include +#include #include extern const char* NATIVE_LANGUAGE; -extern const char* SELECT_LANGUAGE; -extern const char* SELECT_LANGUAGE_MESSAGE; -extern const char* LANGUAGE_SAVED; +extern const char* TRANSLATE_TO; extern const wchar_t* TOO_MANY_TRANS_REQUESTS; extern const char* TRANSLATION_PROVIDER; @@ -17,8 +16,10 @@ extern QStringList languages; std::pair Translate(const std::wstring& text); const char* LANGUAGE = u8"Language"; -const std::string TRANSLATION_CACHE_FILE = FormatString("%sCache.txt", TRANSLATION_PROVIDER); +const std::string TRANSLATION_CACHE_FILE = FormatString("%s Cache.txt", TRANSLATION_PROVIDER); +QFormLayout* display; +QSettings* settings; Synchronized translateTo = L"en"; Synchronized> translationCache; @@ -33,31 +34,30 @@ void SaveCache() savedSize = translationCache->size(); } -BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +class Window : public QDialog { - switch (ul_reason_for_call) +public: + Window() : + QDialog(nullptr, Qt::WindowMinMaxButtonsHint) { - case DLL_PROCESS_ATTACH: - { - static QSettings settings = openSettings(); + display = &layout; + ::settings = &settings; + + languageBox.addItems(languages); + settings.beginGroup(TRANSLATION_PROVIDER); - if (settings.contains(LANGUAGE)) translateTo->assign(S(settings.value(LANGUAGE).toString())); - else QTimer::singleShot(0, [] - { - QString language = QInputDialog::getItem( - nullptr, - SELECT_LANGUAGE, - QString(SELECT_LANGUAGE_MESSAGE).arg(TRANSLATION_PROVIDER), - languages, - std::find_if(languages.begin(), languages.end(), [](QString language) { return language.startsWith(NATIVE_LANGUAGE); }) - languages.begin(), - false, - nullptr, - Qt::WindowCloseButtonHint - ); - translateTo->assign(S(language.split(": ")[1])); - settings.setValue(LANGUAGE, S(translateTo->c_str())); - QMessageBox::information(nullptr, SELECT_LANGUAGE, QString(LANGUAGE_SAVED).arg(CONFIG_FILE)); - }); + int language = -1; + if (settings.contains(LANGUAGE)) language = languageBox.findText(settings.value(LANGUAGE).toString(), Qt::MatchEndsWith); + if (language < 0) language = languageBox.findText(NATIVE_LANGUAGE, Qt::MatchStartsWith); + if (language < 0) language = languageBox.findText("English", Qt::MatchStartsWith); + languageBox.setCurrentIndex(language); + saveLanguage(languageBox.currentText()); + connect(&languageBox, &QComboBox::currentTextChanged, this, &Window::saveLanguage); + + layout.addRow(TRANSLATE_TO, &languageBox); + + setWindowTitle(TRANSLATION_PROVIDER); + QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection); std::ifstream stream(TRANSLATION_CACHE_FILE, std::ios::binary); BlockMarkupIterator savedTranslations(stream, Array{ L"|SENTENCE|", L"|TRANSLATION|" }); @@ -69,15 +69,22 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved } savedSize = translationCache->size(); } - break; - case DLL_PROCESS_DETACH: + + ~Window() { SaveCache(); } - break; + +private: + void saveLanguage(QString language) + { + settings.setValue(LANGUAGE, S(translateTo->assign(S(language.split(": ")[1])))); } - return TRUE; -} + + QFormLayout layout{ this }; + QComboBox languageBox{ this }; + QSettings settings{ openSettings(this) }; +} window; bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) { diff --git a/text.cpp b/text.cpp index 0289ad3..3a23432 100644 --- a/text.cpp +++ b/text.cpp @@ -4,6 +4,18 @@ #define ARCH "x86" #endif +#if 0 +#define TURKISH +#define SPANISH +#define SIMPLIFIED_CHINESE +#define RUSSIAN +#define INDONESIAN +#define ITALIAN +#define THAI +#define PORTUGUESE +#define KOREAN +#endif + const char* NATIVE_LANGUAGE = "English"; const char* ATTACH = u8"Attach to game"; const char* LAUNCH = u8"Launch game"; @@ -117,11 +129,10 @@ const char* SEND_ERROR = u8"Textractor: Send ERROR (likely an unstable/incorrect const char* READ_ERROR = u8"Textractor: Reader ERROR (likely an incorrect R-code)"; const char* HIJACK_ERROR = u8"Textractor: Hijack ERROR"; const char* COULD_NOT_FIND = u8"Textractor: could not find text"; -const char* SELECT_LANGUAGE = u8"Select language"; -const char* SELECT_LANGUAGE_MESSAGE = u8"What language should %1 translate to?"; -const char* LANGUAGE_SAVED = u8"Translation language saved (you can delete it in the config file %1 then reopen Textractor to reselect)"; +const char* TRANSLATE_TO = u8"Translate to"; const wchar_t* TOO_MANY_TRANS_REQUESTS = L"Too many translation requests: refuse to make more"; const wchar_t* TRANSLATION_ERROR = L"Error while translating"; +const char* API_KEY = u8"API key"; const char* EXTRA_WINDOW_INFO = u8R"(Right click to change settings Click and drag on window edges to move, or the bottom right corner to resize)"; const char* SENTENCE_TOO_BIG = u8"Sentence too large to display"; @@ -278,8 +289,6 @@ Código fuente disponible bajo GPLv3 en la página del proyecto)"; READ_ERROR = u8"Textractor: Reader ERROR (probablemente un R-code incorrecto)"; HIJACK_ERROR = u8"Textractor: Hijack ERROR"; COULD_NOT_FIND = u8"Textractor: no se puede encontrar texto"; - SELECT_LANGUAGE = u8"Seleccionar lenguaje"; - SELECT_LANGUAGE_MESSAGE = u8"¿A qué idioma debe traducir %1?"; TOO_MANY_TRANS_REQUESTS = L"Demasiadas peticiones de traducción: no se puede hacer más"; TRANSLATION_ERROR = L"Error al traducir"; EXTRA_WINDOW_INFO = u8R"(Clic derecho para configurar @@ -293,7 +302,7 @@ Clic y arrastra los bordes de la ventana para moverla, o en la esquina inferior #endif // SPANISH #ifdef SIMPLIFIED_CHINESE - NATIVE_LANGUAGE = "Chinese(Simplified)"; + NATIVE_LANGUAGE = "Chinese (Simplified)"; ATTACH = u8"附加到游戏"; LAUNCH = u8"启动游戏"; DETACH = u8"从游戏分离"; @@ -343,8 +352,6 @@ Clic y arrastra los bordes de la ventana para moverla, o en la esquina inferior READ_ERROR = u8"Textractor: Reader 错误 (R码可能不正确)"; HIJACK_ERROR = u8"Textractor: Hijack 错误"; COULD_NOT_FIND = u8"Textractor: 无法找到文本"; - SELECT_LANGUAGE = u8"选择语言"; - SELECT_LANGUAGE_MESSAGE = u8"想要使用 %1 翻译到哪种语言?"; TOO_MANY_TRANS_REQUESTS = L"太多翻译请求: 拒绝生成更多"; TRANSLATION_ERROR = L"翻译时出错"; EXTRA_WINDOW_INFO = u8R"(右键修改设置 @@ -438,8 +445,6 @@ Clic y arrastra los bordes de la ventana para moverla, o en la esquina inferior READ_ERROR = u8"Textractor: Reader ERROR (вероятно неверный R-code)"; HIJACK_ERROR = u8"Textractor: Hijack ERROR"; COULD_NOT_FIND = u8"Textractor: невозможно найти текст"; - SELECT_LANGUAGE = u8"Выберете язык"; - SELECT_LANGUAGE_MESSAGE = u8"На какой язык переводить в %1?"; TOO_MANY_TRANS_REQUESTS = L"Слишком много запросов для перевода: отклонено"; TRANSLATION_ERROR = L"Ошибка при переводе"; EXTRA_WINDOW_INFO = u8R"(Правый клик для изменения настроек @@ -540,8 +545,6 @@ Jika kamu menyukai project ini, tolong sebarluaskan project ini :))"; READ_ERROR = u8"Textractor: Reader ERROR (Kemungkinan R-Code salah)"; HIJACK_ERROR = u8"Textractor: Hijack ERROR"; COULD_NOT_FIND = u8"Textractor: tidak dapat menemukan teks"; - SELECT_LANGUAGE = u8"Pilih bahasa"; - SELECT_LANGUAGE_MESSAGE = u8"Bahasa apakah yang %1 harus terjemahkan?"; TOO_MANY_TRANS_REQUESTS = L"Terlalu banyak permintaan terjemahan: menolak untuk menerjemahkan"; TRANSLATION_ERROR = L"Terjadi kesalahan ketika menerjemahkan"; EXTRA_WINDOW_INFO = u8R"(Klik kanan untuk merubah pengaturan @@ -646,8 +649,6 @@ esempio: Textractor -p4466 -p"My Game.exe" sta tentando di inniettare i processi READ_ERROR = u8"Textractor: Reader ERROR (probabilmente un R-code incorretto)"; HIJACK_ERROR = u8"Textractor: Hijack ERROR"; COULD_NOT_FIND = u8"Textractor: impossibile trovare il testo"; - SELECT_LANGUAGE = u8"Seleziona lingua"; - SELECT_LANGUAGE_MESSAGE = u8"In quale lingua dovrei %1 tradurlo?"; TOO_MANY_TRANS_REQUESTS = L"Troppe richieste di traduzione: rifiuta per farne altre"; TRANSLATION_ERROR = L"Errore durante la traduzione"; EXTRA_WINDOW_INFO = u8R"(Tasto destro per cambiare le impostazioni @@ -762,8 +763,6 @@ Se você gostou desse projeto, divulgue a todos :))"; SEND_ERROR = u8"Textractor: ERRO no envio (provavelmente um H-code incorreto)"; READ_ERROR = u8"Textractor: ERRO na leitura (provavelmente um R-code incorreto)"; COULD_NOT_FIND = u8"Textractor: não foi possível encontrar texto"; - SELECT_LANGUAGE = u8"Selecione a lingua"; - SELECT_LANGUAGE_MESSAGE = u8"Qual lingua deve o/a %1 traduzir para?"; TOO_MANY_TRANS_REQUESTS = L"Foram feitos pedidos de tradução demais: recusa na feitura de mais pedidos"; TRANSLATION_ERROR = L"Erro enquanto traduzindo"; EXTRA_WINDOW_INFO = u8R"(Clique com o botão direito para mudar as opções @@ -839,8 +838,6 @@ Source code สามารถหาได้จากส่วนของ GPLv READ_ERROR = u8"Textractor: Reader ERROR (คาดว่าเป็นความผิดพลาดของ R-Code)"; HIJACK_ERROR = u8"Textractor: Hijack ERROR"; COULD_NOT_FIND = u8"Textractor: ไม่สามารถหาข้อมูลตัวอักษรได้"; - SELECT_LANGUAGE = u8"เลือกภาษา"; - SELECT_LANGUAGE_MESSAGE = u8"ภาษาใดที่ %1 ควรจะแปลให้เป็น?"; TOO_MANY_TRANS_REQUESTS = L"มีการเรียกขอมากเกินกำหนด : ปฏิเสธที่จะทำการขอคำแปลต่อ"; TRANSLATION_ERROR = L"เกิดข้อผิดพลาดระหว่างการแปลภาษา"; EXTRA_WINDOW_INFO = u8R"(คลิกขวาเพื่อที่จะตั่งค่า @@ -906,8 +903,6 @@ Source code สามารถหาได้จากส่วนของ GPLv LAUNCH_FAILED = L"Textractor: 실행할 수 없습니다"; INVALID_CODE = L"Textractor: 유효하지 않은 코드"; INVALID_CODEPAGE = L"Textractor: 텍스트를 변환할 수 없습니다 (유효하지 않은 코드페이지?)"; - SELECT_LANGUAGE = u8"언어 선택"; - SELECT_LANGUAGE_MESSAGE = u8"어떤 언어로 %1 번역하시겠습니까?"; TOO_MANY_TRANS_REQUESTS = L"너무 많은 번역요청: 요청 거부됨"; TRANSLATION_ERROR = L"번역 에러"; EXTRA_WINDOW_INFO = u8R"(오른쪽 클릭으로 설정변경