add gcp translator and add continous dialog for translators and update language lists and make extension dialogs uncloseable without properly removing the extension

This commit is contained in:
Akash Mozumdar 2020-03-16 02:56:04 -06:00
parent df3d3a0355
commit ac4cec9708
17 changed files with 375 additions and 184 deletions

View File

@ -15,18 +15,21 @@ extern const char* CONFIRM_EXTENSION_OVERWRITE;
extern const char* EXTENSION_WRITE_ERROR; extern const char* EXTENSION_WRITE_ERROR;
extern const char* EXTEN_WINDOW_INSTRUCTIONS; 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 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 struct Extension
{ {
std::wstring name; std::wstring name;
wchar_t* (*callback)(wchar_t*, const InfoForExtension*); wchar_t* (*callback)(wchar_t*, const InfoForExtension*);
}; };
Ui::ExtenWindow ui;
concurrency::reader_writer_lock extenMutex; concurrency::reader_writer_lock extenMutex;
std::vector<Extension> extensions; std::vector<Extension> extensions;
ExtenWindow* This = nullptr;
bool Load(QString extenName) 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.push_back(*std::find_if(::extensions.begin(), ::extensions.end(), [&](Extension extension) { return extension.name == S(extenName); }));
::extensions = extensions; ::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) bool DispatchSentenceToExtensions(std::wstring& sentence, const InfoForExtension* sentenceInfo)
@ -84,57 +120,22 @@ void CleanupExtensions()
} }
ExtenWindow::ExtenWindow(QWidget* parent) : ExtenWindow::ExtenWindow(QWidget* parent) :
QMainWindow(parent, Qt::WindowCloseButtonHint), QMainWindow(parent, Qt::WindowCloseButtonHint)
ui(new Ui::ExtenWindow)
{ {
ui->setupUi(this); This = this;
ui.setupUi(this);
connect(ui->extenList, &QListWidget::customContextMenuRequested, [this](QPoint point) ui.vboxLayout->addWidget(new QLabel(EXTEN_WINDOW_INSTRUCTIONS, this));
{
if (QMenu(this).exec({ std::make_unique<QAction>(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));
setWindowTitle(EXTENSIONS); 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); 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); for (auto extenName : QString(QTextFile(EXTEN_SAVE_FILE, QIODevice::ReadOnly).readAll()).split(">")) Load(extenName);
Sync(); Sync();
} }
ExtenWindow::~ExtenWindow() ExtenWindow::~ExtenWindow() = default;
{
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());
}
}
bool ExtenWindow::eventFilter(QObject* target, QEvent* event) bool ExtenWindow::eventFilter(QObject* target, QEvent* event)
{ {
@ -142,7 +143,7 @@ bool ExtenWindow::eventFilter(QObject* target, QEvent* event)
if (event->type() == QEvent::ChildRemoved) if (event->type() == QEvent::ChildRemoved)
{ {
QStringList extenNames; 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); Reorder(extenNames);
Sync(); Sync();
} }
@ -151,9 +152,9 @@ bool ExtenWindow::eventFilter(QObject* target, QEvent* event)
void ExtenWindow::keyPressEvent(QKeyEvent* 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(); Sync();
} }
} }

View File

@ -23,14 +23,8 @@ public:
~ExtenWindow(); ~ExtenWindow();
private: private:
inline static constexpr auto EXTEN_SAVE_FILE = u8"SavedExtensions.txt";
void Add(QFileInfo extenFile);
void Sync();
bool eventFilter(QObject* target, QEvent* event) override; bool eventFilter(QObject* target, QEvent* event) override;
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override;
void dropEvent(QDropEvent* event) override; void dropEvent(QDropEvent* event) override;
Ui::ExtenWindow* ui;
}; };

View File

@ -74,8 +74,8 @@ namespace
enum LaunchWithJapaneseLocale { PROMPT, ALWAYS, NEVER }; enum LaunchWithJapaneseLocale { PROMPT, ALWAYS, NEVER };
Ui::MainWindow ui;
std::atomic<DWORD> selectedProcessId = 0; std::atomic<DWORD> selectedProcessId = 0;
Ui::MainWindow ui{};
ExtenWindow* extenWindow = nullptr; ExtenWindow* extenWindow = nullptr;
std::unordered_set<DWORD> alreadyAttached; std::unordered_set<DWORD> alreadyAttached;
bool autoAttach = false, autoAttachSavedOnly = true; bool autoAttach = false, autoAttachSavedOnly = true;

View File

@ -40,6 +40,7 @@ foreach ($language in @{
"Extra Newlines.dll", "Extra Newlines.dll",
"Extra Window.dll", "Extra Window.dll",
"Google Translate.dll", "Google Translate.dll",
"Google Cloud Translate.dll",
"Lua.dll", "Lua.dll",
"Regex Filter.dll", "Regex Filter.dll",
"Remove Repeated Characters.dll", "Remove Repeated Characters.dll",

View File

@ -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\ Newlines MODULE extranewlines.cpp extensionimpl.cpp)
add_library(Extra\ Window MODULE extrawindow.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\ 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(Lua MODULE lua.cpp extensionimpl.cpp)
add_library(Regex\ Filter MODULE regexfilter.cpp extensionimpl.cpp) add_library(Regex\ Filter MODULE regexfilter.cpp extensionimpl.cpp)
add_library(Remove\ Repeated\ Characters MODULE removerepeatchar.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(Bing\ Translate winhttp Qt5::Widgets)
target_link_libraries(Extra\ Window Qt5::Widgets) target_link_libraries(Extra\ Window Qt5::Widgets)
target_link_libraries(Google\ Translate winhttp 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(Lua lua53 Qt5::Widgets)
target_link_libraries(Regex\ Filter Qt5::Widgets) target_link_libraries(Regex\ Filter Qt5::Widgets)
target_link_libraries(Thread\ Linker Qt5::Widgets) target_link_libraries(Thread\ Linker Qt5::Widgets)

View File

@ -6,54 +6,79 @@ extern const wchar_t* TRANSLATION_ERROR;
extern Synchronized<std::wstring> translateTo; extern Synchronized<std::wstring> translateTo;
const char* TRANSLATION_PROVIDER = "Bing"; const char* TRANSLATION_PROVIDER = "Bing Translate";
QStringList languages QStringList languages
{ {
"Afrikaans: af",
"Arabic: ar", "Arabic: ar",
"Bosnian: bs-Latn", "Bangla: bn",
"Bosnian: bs",
"Bulgarian: bg", "Bulgarian: bg",
"Cantonese (Traditional): yue",
"Catalan: ca", "Catalan: ca",
"Chinese(Simplified): zh-CHS", "Chinese (Simplified): zh-Hans",
"Chinese(Traditional): zh-CHT", "Chinese (Traditional): zh-Hant",
"Croatian: hr", "Croatian: hr",
"Czech: cs", "Czech: cs",
"Danish: da", "Danish: da",
"Dutch: nl", "Dutch: nl",
"English: en", "English: en",
"Estonian: et", "Estonian: et",
"Fijian: fj",
"Filipino: fil",
"Finnish: fi", "Finnish: fi",
"French: fr", "French: fr",
"German: de", "German: de",
"Greek: el", "Greek: el",
"Haitian Creole: ht",
"Hebrew: he", "Hebrew: he",
"Hindi: hi", "Hindi: hi",
"Hmong Daw: mww",
"Hungarian: hu", "Hungarian: hu",
"Icelandic: is",
"Indonesian: id", "Indonesian: id",
"Irish: ga",
"Italian: it", "Italian: it",
"Japanese: ja", "Japanese: ja",
"Klingon: tlh", "Kannada: kn",
"Klingon (Latin): tlh-Latn",
"Klingon (pIqaD): tlh-Piqd",
"Korean: ko", "Korean: ko",
"Latvian: lv", "Latvian: lv",
"Lithuanian: lt", "Lithuanian: lt",
"Malagasy: mg",
"Malay: ms", "Malay: ms",
"Malayalam: ml",
"Maltese: mt", "Maltese: mt",
"Norwegian: no", "Maori: mi",
"Norwegian: nb",
"Persian: fa", "Persian: fa",
"Polish: pl", "Polish: pl",
"Portuguese: pt", "Portuguese (Brazil): pt",
"Portuguese (Portugal): pt-pt",
"Punjabi: pa",
"Querétaro Otomi: otq",
"Romanian: ro", "Romanian: ro",
"Russian: ru", "Russian: ru",
"Serbian: sr-Cyrl", "Samoan: sm",
"Serbian (Cyrillic): sr-Cyrl",
"Serbian (Latin): sr-Latn",
"Slovak: sk", "Slovak: sk",
"Slovenian: sl", "Slovenian: sl",
"Spanish: es", "Spanish: es",
"Swahili: sw",
"Swedish: sv", "Swedish: sv",
"Tahitian: ty",
"Tamil: ta",
"Telugu: te",
"Thai: th", "Thai: th",
"Tongan: to",
"Turkish: tr", "Turkish: tr",
"Ukranian: uk", "Ukrainian: uk",
"Urdu: ur", "Urdu: ur",
"Vietnamese: vi", "Vietnamese: vi",
"Welsh: cy" "Welsh: cy",
"Yucatec Maya: yua"
}; };
std::pair<bool, std::wstring> Translate(const std::wstring& text) std::pair<bool, std::wstring> Translate(const std::wstring& text)
@ -65,7 +90,7 @@ std::pair<bool, std::wstring> Translate(const std::wstring& text)
FormatString(L"/ttranslatev3?fromLang=auto-detect&to=%s&text=%s", translateTo->c_str(), Escape(text)).c_str() 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 // 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, TRANSLATION_ERROR };
else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) }; else return { false, FormatString(L"%s (code=%u)", TRANSLATION_ERROR, httpRequest.errorCode) };
} }

View File

@ -7,8 +7,8 @@ template <typename C, int delimiterCount, int blockSize = 0x1000 / sizeof(C)> //
class BlockMarkupIterator class BlockMarkupIterator
{ {
public: public:
BlockMarkupIterator(const std::istream& it, const std::basic_string_view<C>(&delimiters)[delimiterCount]) : BlockMarkupIterator(const std::istream& stream, const std::basic_string_view<C>(&delimiters)[delimiterCount]) :
streambuf(*it.rdbuf()) streambuf(*stream.rdbuf())
{ {
std::copy_n(delimiters, delimiterCount, this->delimiters.begin()); std::copy_n(delimiters, delimiterCount, this->delimiters.begin());
} }

View File

@ -444,7 +444,7 @@ private:
QStringList currentInflectionsUsed = inflectionsUsed; QStringList currentInflectionsUsed = inflectionsUsed;
currentInflectionsUsed.push_front(inflection.name); currentInflectionsUsed.push_front(inflection.name);
QString root = inflection.root; 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); for (const auto& definition : LookupDefinitions(root, foundDefinitions, currentInflectionsUsed)) results.push_back(definition);
} }
return results; return results;

View File

@ -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<std::wstring> 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<std::wstring> 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(
"<a href=\"https://codelabs.developers.google.com/codelabs/cloud-translation-intro\">https://codelabs.developers.google.com/codelabs/cloud-translation-intro</a>"
);
googleCloudInfo->setOpenExternalLinks(true);
display->addRow(googleCloudInfo);
}
break;
case DLL_PROCESS_DETACH:
{
}
break;
}
return TRUE;
}
std::pair<bool, std::wstring> 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) };
}

View File

@ -7,19 +7,26 @@ extern const wchar_t* TRANSLATION_ERROR;
extern Synchronized<std::wstring> translateTo; extern Synchronized<std::wstring> translateTo;
const char* TRANSLATION_PROVIDER = "Google"; const char* TRANSLATION_PROVIDER = "Google Translate";
QStringList languages QStringList languages
{ {
"Afrikaans: af", "Afrikaans: af",
"Arabic: ar",
"Albanian: sq", "Albanian: sq",
"Amharic: am",
"Arabic: ar",
"Armenian: hy",
"Azerbaijani: az",
"Basque: eu",
"Belarusian: be", "Belarusian: be",
"Bengali: bn", "Bengali: bn",
"Bosnian: bs", "Bosnian: bs",
"Bulgarian: bg", "Bulgarian: bg",
"Catalan: ca", "Catalan: ca",
"Chinese(Simplified): zh-CH", "Cebuano: ceb",
"Chinese(Traditional): zh-TW", "Chichewa: ny",
"Chinese (Simplified): zh",
"Chinese (Traditional): zh-TW",
"Corsican: co",
"Croatian: hr", "Croatian: hr",
"Czech: cs", "Czech: cs",
"Danish: da", "Danish: da",
@ -30,45 +37,87 @@ QStringList languages
"Filipino: tl", "Filipino: tl",
"Finnish: fi", "Finnish: fi",
"French: fr", "French: fr",
"Frisian: fy",
"Galician: gl", "Galician: gl",
"Georgian: ka",
"German: de", "German: de",
"Greek: el", "Greek: el",
"Gujarati: gu",
"Haitian Creole: ht",
"Hausa: ha",
"Hawaiian: haw",
"Hebrew: iw", "Hebrew: iw",
"Hindi: hi", "Hindi: hi",
"Hmong: hmn",
"Hungarian: hu", "Hungarian: hu",
"Icelandic: is", "Icelandic: is",
"Igbo: ig",
"Indonesian: id", "Indonesian: id",
"Irish: ga", "Irish: ga",
"Italian: it", "Italian: it",
"Japanese: ja", "Japanese: ja",
"Klingon: tlh", "Javanese: jw",
"Kannada: kn",
"Kazakh: kk",
"Khmer: km",
"Kinyarwanda: rw",
"Korean: ko", "Korean: ko",
"Kurdish (Kurmanji): ku",
"Kyrgyz: ky",
"Lao: lo",
"Latin: la", "Latin: la",
"Latvian: lv", "Latvian: lv",
"Lithuanian: lt", "Lithuanian: lt",
"Luxembourgish: lb",
"Macedonian: mk", "Macedonian: mk",
"Malagasy: mg",
"Malay: ms", "Malay: ms",
"Malayalam: ml",
"Maltese: mt", "Maltese: mt",
"Maori: mi",
"Marathi: mr",
"Mongolian: mn",
"Myanmar (Burmese): my",
"Nepali: ne",
"Norwegian: no", "Norwegian: no",
"Odia (Oriya): or",
"Pashto: ps",
"Persian: fa", "Persian: fa",
"Polish: pl", "Polish: pl",
"Portuguese: pt", "Portuguese: pt",
"Punjabi: pa",
"Romanian: ro", "Romanian: ro",
"Russian: ru", "Russian: ru",
"Samoan: sm",
"Scots Gaelic: gd",
"Serbian: sr", "Serbian: sr",
"Sesotho: st",
"Shona: sn",
"Sindhi: sd",
"Sinhala: si",
"Slovak: sk", "Slovak: sk",
"Slovenian: sl", "Slovenian: sl",
"Somali: so", "Somali: so",
"Spanish: es", "Spanish: es",
"Sundanese: su",
"Swahili: sw", "Swahili: sw",
"Swedish: sv", "Swedish: sv",
"Tajik: tg",
"Tamil: ta",
"Tatar: tt",
"Telugu: te",
"Thai: th", "Thai: th",
"Turkish: tr", "Turkish: tr",
"Ukranian: uk", "Turkmen: tk",
"Ukrainian: uk",
"Urdu: ur", "Urdu: ur",
"Uyghur: ug",
"Uzbek: uz",
"Vietnamese: vi", "Vietnamese: vi",
"Welsh: cy", "Welsh: cy",
"Xhosa: xh",
"Yiddish: yi", "Yiddish: yi",
"Yoruba: yo",
"Zulu: zu" "Zulu: zu"
}; };

View File

@ -41,10 +41,11 @@ bool logErrors = true;
Synchronized<std::string> script; Synchronized<std::string> script;
std::atomic<int> revCount = 0; std::atomic<int> revCount = 0;
class Window : public QMainWindow class Window : public QDialog
{ {
public: public:
Window() Window()
: QDialog(nullptr, Qt::WindowMinMaxButtonsHint)
{ {
connect(&loadButton, &QPushButton::clicked, this, &Window::LoadScript); connect(&loadButton, &QPushButton::clicked, this, &Window::LoadScript);
@ -53,7 +54,6 @@ public:
layout.addWidget(&loadButton); layout.addWidget(&loadButton);
resize(800, 600); resize(800, 600);
setCentralWidget(&centralWidget);
setWindowTitle("Lua"); setWindowTitle("Lua");
QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection); QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
} }
@ -76,10 +76,9 @@ private:
QTextFile(LUA_SAVE_FILE, QIODevice::WriteOnly | QIODevice::Truncate).write(scriptEditor.toPlainText().toUtf8()); QTextFile(LUA_SAVE_FILE, QIODevice::WriteOnly | QIODevice::Truncate).write(scriptEditor.toPlainText().toUtf8());
} }
QWidget centralWidget{ this }; QHBoxLayout layout{ this };
QHBoxLayout layout{ &centralWidget }; QPlainTextEdit scriptEditor{ QTextFile(LUA_SAVE_FILE, QIODevice::ReadOnly).readAll(), this };
QPlainTextEdit scriptEditor{ QTextFile(LUA_SAVE_FILE, QIODevice::ReadOnly).readAll(), &centralWidget }; QPushButton loadButton{ LOAD_LUA_SCRIPT, this };
QPushButton loadButton{ LOAD_LUA_SCRIPT, &centralWidget };
} window; } window;
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)

View File

@ -56,11 +56,12 @@ void Unescape(std::wstring& text)
{ {
if (text[i] == L'\\') if (text[i] == L'\\')
{ {
text[i] = 0x200b; text[i] = 0;
if (text[i + 1] == L'r') text[i + 1] = 0x200b; // for some reason \r gets displayed as a newline 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'n') text[i + 1] = L'\n';
if (text[i + 1] == L't') text[i + 1] = L'\t'; if (text[i + 1] == L't') text[i + 1] = L'\t';
if (text[i + 1] == L'\\') ++i; if (text[i + 1] == L'\\') ++i;
} }
} }
text.erase(std::remove(text.begin(), text.end(), 0), text.end());
} }

View File

@ -15,10 +15,11 @@ std::optional<std::wregex> regex;
std::shared_mutex m; std::shared_mutex m;
DWORD (*GetSelectedProcessId)() = nullptr; DWORD (*GetSelectedProcessId)() = nullptr;
class Window : public QMainWindow class Window : public QDialog
{ {
public: public:
Window() Window()
: QDialog(nullptr, Qt::WindowMinMaxButtonsHint)
{ {
ui.setupUi(this); ui.setupUi(this);

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>FilterWindow</class> <class>FilterWindow</class>
<widget class="QMainWindow" name="FilterWindow"> <widget class="QDialog">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -10,49 +10,47 @@
<height>105</height> <height>105</height>
</rect> </rect>
</property> </property>
<widget class="QWidget"> <layout class="QVBoxLayout">
<layout class="QVBoxLayout"> <item>
<item> <widget class="QLineEdit" name="input"/>
<widget class="QLineEdit" name="input"/> </item>
</item> <item>
<item> <widget class="QLabel" name="output">
<widget class="QLabel" name="output"> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="alignment">
<property name="alignment"> <set>Qt::AlignCenter</set>
<set>Qt::AlignCenter</set> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="save">
<widget class="QPushButton" name="save"> <property name="text">
<property name="text"> <string>Save</string>
<string>Save</string> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QLabel">
<widget class="QLabel"> <property name="text">
<property name="text"> <string>&lt;a href=&quot;https://regexr.com&quot;&gt;regexr.com&lt;/a&gt;</string>
<string>&lt;a href=&quot;https://regexr.com&quot;&gt;regexr.com&lt;/a&gt;</string> </property>
</property> <property name="textFormat">
<property name="textFormat"> <enum>Qt::RichText</enum>
<enum>Qt::RichText</enum> </property>
</property> <property name="alignment">
<property name="alignment"> <set>Qt::AlignCenter</set>
<set>Qt::AlignCenter</set> </property>
</property> <property name="openExternalLinks">
<property name="openExternalLinks"> <bool>true</bool>
<bool>true</bool> </property>
</property> <property name="textInteractionFlags">
<property name="textInteractionFlags"> <set>Qt::TextBrowserInteraction</set>
<set>Qt::TextBrowserInteraction</set> </property>
</property> </widget>
</widget> </item>
</item> </layout>
</layout>
</widget>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>

View File

@ -11,17 +11,17 @@ extern const char* HEXADECIMAL;
std::unordered_map<int64_t, std::unordered_multiset<int64_t>> linkedTextHandles; std::unordered_map<int64_t, std::unordered_multiset<int64_t>> linkedTextHandles;
std::shared_mutex m; std::shared_mutex m;
class Window : public QMainWindow class Window : public QDialog
{ {
public: public:
Window() Window()
: QDialog(nullptr, Qt::WindowMinMaxButtonsHint)
{ {
connect(&linkButton, &QPushButton::clicked, this, &Window::Link); connect(&linkButton, &QPushButton::clicked, this, &Window::Link);
layout.addWidget(&linkList); layout.addWidget(&linkList);
layout.addWidget(&linkButton); layout.addWidget(&linkButton);
setCentralWidget(&centralWidget);
setWindowTitle(THREAD_LINKER); setWindowTitle(THREAD_LINKER);
QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection); QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
} }
@ -51,10 +51,9 @@ private:
} }
} }
QWidget centralWidget{ this }; QHBoxLayout layout{ this };
QHBoxLayout layout{ &centralWidget }; QListWidget linkList{ this };
QListWidget linkList{ &centralWidget }; QPushButton linkButton{ LINK, this };
QPushButton linkButton{ LINK, &centralWidget };
} window; } window;
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)

View File

@ -4,12 +4,11 @@
#include "network.h" #include "network.h"
#include <map> #include <map>
#include <fstream> #include <fstream>
#include <QComboBox>
#include <QTimer> #include <QTimer>
extern const char* NATIVE_LANGUAGE; extern const char* NATIVE_LANGUAGE;
extern const char* SELECT_LANGUAGE; extern const char* TRANSLATE_TO;
extern const char* SELECT_LANGUAGE_MESSAGE;
extern const char* LANGUAGE_SAVED;
extern const wchar_t* TOO_MANY_TRANS_REQUESTS; extern const wchar_t* TOO_MANY_TRANS_REQUESTS;
extern const char* TRANSLATION_PROVIDER; extern const char* TRANSLATION_PROVIDER;
@ -17,8 +16,10 @@ extern QStringList languages;
std::pair<bool, std::wstring> Translate(const std::wstring& text); std::pair<bool, std::wstring> Translate(const std::wstring& text);
const char* LANGUAGE = u8"Language"; 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<std::wstring> translateTo = L"en"; Synchronized<std::wstring> translateTo = L"en";
Synchronized<std::map<std::wstring, std::wstring>> translationCache; Synchronized<std::map<std::wstring, std::wstring>> translationCache;
@ -33,31 +34,30 @@ void SaveCache()
savedSize = translationCache->size(); 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: display = &layout;
{ ::settings = &settings;
static QSettings settings = openSettings();
languageBox.addItems(languages);
settings.beginGroup(TRANSLATION_PROVIDER); settings.beginGroup(TRANSLATION_PROVIDER);
if (settings.contains(LANGUAGE)) translateTo->assign(S(settings.value(LANGUAGE).toString())); int language = -1;
else QTimer::singleShot(0, [] if (settings.contains(LANGUAGE)) language = languageBox.findText(settings.value(LANGUAGE).toString(), Qt::MatchEndsWith);
{ if (language < 0) language = languageBox.findText(NATIVE_LANGUAGE, Qt::MatchStartsWith);
QString language = QInputDialog::getItem( if (language < 0) language = languageBox.findText("English", Qt::MatchStartsWith);
nullptr, languageBox.setCurrentIndex(language);
SELECT_LANGUAGE, saveLanguage(languageBox.currentText());
QString(SELECT_LANGUAGE_MESSAGE).arg(TRANSLATION_PROVIDER), connect(&languageBox, &QComboBox::currentTextChanged, this, &Window::saveLanguage);
languages,
std::find_if(languages.begin(), languages.end(), [](QString language) { return language.startsWith(NATIVE_LANGUAGE); }) - languages.begin(), layout.addRow(TRANSLATE_TO, &languageBox);
false,
nullptr, setWindowTitle(TRANSLATION_PROVIDER);
Qt::WindowCloseButtonHint QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
);
translateTo->assign(S(language.split(": ")[1]));
settings.setValue(LANGUAGE, S(translateTo->c_str()));
QMessageBox::information(nullptr, SELECT_LANGUAGE, QString(LANGUAGE_SAVED).arg(CONFIG_FILE));
});
std::ifstream stream(TRANSLATION_CACHE_FILE, std::ios::binary); std::ifstream stream(TRANSLATION_CACHE_FILE, std::ios::binary);
BlockMarkupIterator savedTranslations(stream, Array<std::wstring_view>{ L"|SENTENCE|", L"|TRANSLATION|" }); BlockMarkupIterator savedTranslations(stream, Array<std::wstring_view>{ L"|SENTENCE|", L"|TRANSLATION|" });
@ -69,15 +69,22 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
} }
savedSize = translationCache->size(); savedSize = translationCache->size();
} }
break;
case DLL_PROCESS_DETACH: ~Window()
{ {
SaveCache(); 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) bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
{ {

View File

@ -4,6 +4,18 @@
#define ARCH "x86" #define ARCH "x86"
#endif #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* NATIVE_LANGUAGE = "English";
const char* ATTACH = u8"Attach to game"; const char* ATTACH = u8"Attach to game";
const char* LAUNCH = u8"Launch 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* READ_ERROR = u8"Textractor: Reader ERROR (likely an incorrect R-code)";
const char* HIJACK_ERROR = u8"Textractor: Hijack ERROR"; const char* HIJACK_ERROR = u8"Textractor: Hijack ERROR";
const char* COULD_NOT_FIND = u8"Textractor: could not find text"; const char* COULD_NOT_FIND = u8"Textractor: could not find text";
const char* SELECT_LANGUAGE = u8"Select language"; const char* TRANSLATE_TO = u8"Translate to";
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 wchar_t* TOO_MANY_TRANS_REQUESTS = L"Too many translation requests: refuse to make more"; 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 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 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)"; 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"; 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)"; READ_ERROR = u8"Textractor: Reader ERROR (probablemente un R-code incorrecto)";
HIJACK_ERROR = u8"Textractor: Hijack ERROR"; HIJACK_ERROR = u8"Textractor: Hijack ERROR";
COULD_NOT_FIND = u8"Textractor: no se puede encontrar texto"; 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"; TOO_MANY_TRANS_REQUESTS = L"Demasiadas peticiones de traducción: no se puede hacer más";
TRANSLATION_ERROR = L"Error al traducir"; TRANSLATION_ERROR = L"Error al traducir";
EXTRA_WINDOW_INFO = u8R"(Clic derecho para configurar 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 #endif // SPANISH
#ifdef SIMPLIFIED_CHINESE #ifdef SIMPLIFIED_CHINESE
NATIVE_LANGUAGE = "Chinese(Simplified)"; NATIVE_LANGUAGE = "Chinese (Simplified)";
ATTACH = u8"附加到游戏"; ATTACH = u8"附加到游戏";
LAUNCH = u8"启动游戏"; LAUNCH = u8"启动游戏";
DETACH = 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码可能不正确)"; READ_ERROR = u8"Textractor: Reader 错误 (R码可能不正确)";
HIJACK_ERROR = u8"Textractor: Hijack 错误"; HIJACK_ERROR = u8"Textractor: Hijack 错误";
COULD_NOT_FIND = u8"Textractor: 无法找到文本"; COULD_NOT_FIND = u8"Textractor: 无法找到文本";
SELECT_LANGUAGE = u8"选择语言";
SELECT_LANGUAGE_MESSAGE = u8"想要使用 %1 翻译到哪种语言?";
TOO_MANY_TRANS_REQUESTS = L"太多翻译请求: 拒绝生成更多"; TOO_MANY_TRANS_REQUESTS = L"太多翻译请求: 拒绝生成更多";
TRANSLATION_ERROR = L"翻译时出错"; TRANSLATION_ERROR = L"翻译时出错";
EXTRA_WINDOW_INFO = u8R"(右键修改设置 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)"; READ_ERROR = u8"Textractor: Reader ERROR (вероятно неверный R-code)";
HIJACK_ERROR = u8"Textractor: Hijack ERROR"; HIJACK_ERROR = u8"Textractor: Hijack ERROR";
COULD_NOT_FIND = u8"Textractor: невозможно найти текст"; COULD_NOT_FIND = u8"Textractor: невозможно найти текст";
SELECT_LANGUAGE = u8"Выберете язык";
SELECT_LANGUAGE_MESSAGE = u8"На какой язык переводить в %1?";
TOO_MANY_TRANS_REQUESTS = L"Слишком много запросов для перевода: отклонено"; TOO_MANY_TRANS_REQUESTS = L"Слишком много запросов для перевода: отклонено";
TRANSLATION_ERROR = L"Ошибка при переводе"; TRANSLATION_ERROR = L"Ошибка при переводе";
EXTRA_WINDOW_INFO = u8R"(Правый клик для изменения настроек 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)"; READ_ERROR = u8"Textractor: Reader ERROR (Kemungkinan R-Code salah)";
HIJACK_ERROR = u8"Textractor: Hijack ERROR"; HIJACK_ERROR = u8"Textractor: Hijack ERROR";
COULD_NOT_FIND = u8"Textractor: tidak dapat menemukan teks"; 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"; TOO_MANY_TRANS_REQUESTS = L"Terlalu banyak permintaan terjemahan: menolak untuk menerjemahkan";
TRANSLATION_ERROR = L"Terjadi kesalahan ketika menerjemahkan"; TRANSLATION_ERROR = L"Terjadi kesalahan ketika menerjemahkan";
EXTRA_WINDOW_INFO = u8R"(Klik kanan untuk merubah pengaturan 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)"; READ_ERROR = u8"Textractor: Reader ERROR (probabilmente un R-code incorretto)";
HIJACK_ERROR = u8"Textractor: Hijack ERROR"; HIJACK_ERROR = u8"Textractor: Hijack ERROR";
COULD_NOT_FIND = u8"Textractor: impossibile trovare il testo"; 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"; TOO_MANY_TRANS_REQUESTS = L"Troppe richieste di traduzione: rifiuta per farne altre";
TRANSLATION_ERROR = L"Errore durante la traduzione"; TRANSLATION_ERROR = L"Errore durante la traduzione";
EXTRA_WINDOW_INFO = u8R"(Tasto destro per cambiare le impostazioni 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)"; SEND_ERROR = u8"Textractor: ERRO no envio (provavelmente um H-code incorreto)";
READ_ERROR = u8"Textractor: ERRO na leitura (provavelmente um R-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"; 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"; TOO_MANY_TRANS_REQUESTS = L"Foram feitos pedidos de tradução demais: recusa na feitura de mais pedidos";
TRANSLATION_ERROR = L"Erro enquanto traduzindo"; TRANSLATION_ERROR = L"Erro enquanto traduzindo";
EXTRA_WINDOW_INFO = u8R"(Clique com o botão direito para mudar as opções 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)"; READ_ERROR = u8"Textractor: Reader ERROR (คาดว่าเป็นความผิดพลาดของ R-Code)";
HIJACK_ERROR = u8"Textractor: Hijack ERROR"; HIJACK_ERROR = u8"Textractor: Hijack ERROR";
COULD_NOT_FIND = u8"Textractor: ไม่สามารถหาข้อมูลตัวอักษรได้"; COULD_NOT_FIND = u8"Textractor: ไม่สามารถหาข้อมูลตัวอักษรได้";
SELECT_LANGUAGE = u8"เลือกภาษา";
SELECT_LANGUAGE_MESSAGE = u8"ภาษาใดที่ %1 ควรจะแปลให้เป็น?";
TOO_MANY_TRANS_REQUESTS = L"มีการเรียกขอมากเกินกำหนด : ปฏิเสธที่จะทำการขอคำแปลต่อ"; TOO_MANY_TRANS_REQUESTS = L"มีการเรียกขอมากเกินกำหนด : ปฏิเสธที่จะทำการขอคำแปลต่อ";
TRANSLATION_ERROR = L"เกิดข้อผิดพลาดระหว่างการแปลภาษา"; TRANSLATION_ERROR = L"เกิดข้อผิดพลาดระหว่างการแปลภาษา";
EXTRA_WINDOW_INFO = u8R"(คลิกขวาเพื่อที่จะตั่งค่า EXTRA_WINDOW_INFO = u8R"(คลิกขวาเพื่อที่จะตั่งค่า
@ -906,8 +903,6 @@ Source code สามารถหาได้จากส่วนของ GPLv
LAUNCH_FAILED = L"Textractor: 실행할 수 없습니다"; LAUNCH_FAILED = L"Textractor: 실행할 수 없습니다";
INVALID_CODE = L"Textractor: 유효하지 않은 코드"; INVALID_CODE = L"Textractor: 유효하지 않은 코드";
INVALID_CODEPAGE = L"Textractor: 텍스트를 변환할 수 없습니다 (유효하지 않은 코드페이지?)"; INVALID_CODEPAGE = L"Textractor: 텍스트를 변환할 수 없습니다 (유효하지 않은 코드페이지?)";
SELECT_LANGUAGE = u8"언어 선택";
SELECT_LANGUAGE_MESSAGE = u8"어떤 언어로 %1 번역하시겠습니까?";
TOO_MANY_TRANS_REQUESTS = L"너무 많은 번역요청: 요청 거부됨"; TOO_MANY_TRANS_REQUESTS = L"너무 많은 번역요청: 요청 거부됨";
TRANSLATION_ERROR = L"번역 에러"; TRANSLATION_ERROR = L"번역 에러";
EXTRA_WINDOW_INFO = u8R"(오른쪽 클릭으로 설정변경 EXTRA_WINDOW_INFO = u8R"(오른쪽 클릭으로 설정변경