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:
parent
df3d3a0355
commit
ac4cec9708
@ -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<Extension> 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<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));
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -74,8 +74,8 @@ namespace
|
||||
|
||||
enum LaunchWithJapaneseLocale { PROMPT, ALWAYS, NEVER };
|
||||
|
||||
Ui::MainWindow ui;
|
||||
std::atomic<DWORD> selectedProcessId = 0;
|
||||
Ui::MainWindow ui{};
|
||||
ExtenWindow* extenWindow = nullptr;
|
||||
std::unordered_set<DWORD> alreadyAttached;
|
||||
bool autoAttach = false, autoAttachSavedOnly = true;
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -6,54 +6,79 @@ extern const wchar_t* TRANSLATION_ERROR;
|
||||
|
||||
extern Synchronized<std::wstring> 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<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()
|
||||
})
|
||||
// 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) };
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ template <typename C, int delimiterCount, int blockSize = 0x1000 / sizeof(C)> //
|
||||
class BlockMarkupIterator
|
||||
{
|
||||
public:
|
||||
BlockMarkupIterator(const std::istream& it, const std::basic_string_view<C>(&delimiters)[delimiterCount]) :
|
||||
streambuf(*it.rdbuf())
|
||||
BlockMarkupIterator(const std::istream& stream, const std::basic_string_view<C>(&delimiters)[delimiterCount]) :
|
||||
streambuf(*stream.rdbuf())
|
||||
{
|
||||
std::copy_n(delimiters, delimiterCount, this->delimiters.begin());
|
||||
}
|
||||
|
@ -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;
|
||||
|
119
extensions/googlecloudtranslate.cpp
Normal file
119
extensions/googlecloudtranslate.cpp
Normal 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) };
|
||||
}
|
@ -7,19 +7,26 @@ extern const wchar_t* TRANSLATION_ERROR;
|
||||
|
||||
extern Synchronized<std::wstring> 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",
|
||||
"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"
|
||||
};
|
||||
|
||||
|
@ -41,10 +41,11 @@ bool logErrors = true;
|
||||
Synchronized<std::string> script;
|
||||
std::atomic<int> 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)
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -15,10 +15,11 @@ std::optional<std::wregex> 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);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FilterWindow</class>
|
||||
<widget class="QMainWindow" name="FilterWindow">
|
||||
<widget class="QDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@ -10,7 +10,6 @@
|
||||
<height>105</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget">
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="input"/>
|
||||
@ -53,7 +52,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -11,17 +11,17 @@ extern const char* HEXADECIMAL;
|
||||
std::unordered_map<int64_t, std::unordered_multiset<int64_t>> 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)
|
||||
|
@ -4,12 +4,11 @@
|
||||
#include "network.h"
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <QComboBox>
|
||||
#include <QTimer>
|
||||
|
||||
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;
|
||||
@ -19,6 +18,8 @@ std::pair<bool, std::wstring> Translate(const std::wstring& text);
|
||||
const char* LANGUAGE = u8"Language";
|
||||
const std::string TRANSLATION_CACHE_FILE = FormatString("%s Cache.txt", TRANSLATION_PROVIDER);
|
||||
|
||||
QFormLayout* display;
|
||||
QSettings* settings;
|
||||
Synchronized<std::wstring> translateTo = L"en";
|
||||
|
||||
Synchronized<std::map<std::wstring, std::wstring>> 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<std::wstring_view>{ L"|SENTENCE|", L"|TRANSLATION|" });
|
||||
@ -69,16 +69,23 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
|
||||
}
|
||||
savedSize = translationCache->size();
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
||||
~Window()
|
||||
{
|
||||
SaveCache();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
private:
|
||||
void saveLanguage(QString language)
|
||||
{
|
||||
settings.setValue(LANGUAGE, S(translateTo->assign(S(language.split(": ")[1]))));
|
||||
}
|
||||
|
||||
QFormLayout layout{ this };
|
||||
QComboBox languageBox{ this };
|
||||
QSettings settings{ openSettings(this) };
|
||||
} window;
|
||||
|
||||
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
||||
{
|
||||
if (sentenceInfo["text number"] == 0) return false;
|
||||
|
33
text.cpp
33
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
|
||||
@ -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"(오른쪽 클릭으로 설정변경
|
||||
|
Loading…
Reference in New Issue
Block a user