diff --git a/GUI/extenwindow.ui b/GUI/extenwindow.ui
index b6fbe41..7ae493f 100644
--- a/GUI/extenwindow.ui
+++ b/GUI/extenwindow.ui
@@ -16,24 +16,26 @@
Extensions
-
- QObject
-{
- font: 10pt "MS Shell Dlg 2";
-}
-#textOutput
-{
- font: 13pt "MS Shell Dlg 2";;
-}
-QPushButton, QComboBox
-{
- padding-top: 3px;
- padding-bottom: 3px;
- padding-right: 5px;
- padding-left: 5px;
- text-align: left;
-}
-
+
+
+ QObject
+ {
+ font: 10pt "MS Shell Dlg 2";
+ }
+ #textOutput
+ {
+ font: 13pt "MS Shell Dlg 2";
+ }
+ QPushButton, QComboBox
+ {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ padding-right: 5px;
+ padding-left: 5px;
+ text-align: left;
+ }
+
+
-
diff --git a/GUI/mainwindow.ui b/GUI/mainwindow.ui
index 692749d..6aee2a2 100644
--- a/GUI/mainwindow.ui
+++ b/GUI/mainwindow.ui
@@ -13,24 +13,26 @@
Textractor
-
- QObject
-{
- font: 10pt "MS Shell Dlg 2";
-}
-#textOutput
-{
- font: 13pt "MS Shell Dlg 2";
-}
-QPushButton, QComboBox
-{
- padding-top: 3px;
- padding-bottom: 3px;
- padding-right: 5px;
- padding-left: 5px;
- text-align: left;
-}
-
+
+
+ QObject
+ {
+ font: 10pt "MS Shell Dlg 2";
+ }
+ #textOutput
+ {
+ font: 13pt "MS Shell Dlg 2";
+ }
+ QPushButton, QComboBox
+ {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ padding-right: 5px;
+ padding-left: 5px;
+ text-align: left;
+ }
+
+
-
diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt
index 8a301dc..797cd8e 100644
--- a/extensions/CMakeLists.txt
+++ b/extensions/CMakeLists.txt
@@ -10,7 +10,9 @@ add_library(Extra\ Newlines SHARED extranewlines/extranewlines.cpp extensionimpl
add_library(Google\ Translate SHARED googletranslate/googletranslate.cpp extensionimpl.cpp)
add_library(Regex\ Filter SHARED regexfilter/regexfilter.cpp regexfilter/window.cpp extensionimpl.cpp)
add_library(Remove\ Repetition SHARED removerepeat/removerepeat.cpp extensionimpl.cpp)
+add_library(Thread\ Linker SHARED threadlinker/threadlinker.cpp threadlinker/window.cpp extensionimpl.cpp)
target_link_libraries(Bing\ Translate winhttp Qt5::Widgets)
target_link_libraries(Google\ Translate winhttp Qt5::Widgets)
target_link_libraries(Regex\ Filter Qt5::Widgets)
+target_link_libraries(Thread\ Linker Qt5::Widgets)
diff --git a/extensions/threadlinker/threadlinker.cpp b/extensions/threadlinker/threadlinker.cpp
new file mode 100644
index 0000000..eac598b
--- /dev/null
+++ b/extensions/threadlinker/threadlinker.cpp
@@ -0,0 +1,37 @@
+#include "../extension.h"
+#include "window.h"
+#include
+
+Window* w = nullptr;
+
+BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ QTimer::singleShot(0, [] { (w = new Window)->show(); });
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+ delete w;
+ }
+ break;
+ }
+ return TRUE;
+}
+
+bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
+{
+ if (w == nullptr) return false;
+ std::lock_guard l(w->m);
+
+ static std::unordered_map queuedWritesByHandle;
+ int64_t textHandle = sentenceInfo["text handle"];
+ for (auto linkedHandle : w->linkedTextHandles[textHandle]) queuedWritesByHandle[linkedHandle] += L"\r\n" + sentence;
+ if (queuedWritesByHandle[textHandle].empty()) return false;
+ sentence += queuedWritesByHandle[textHandle];
+ queuedWritesByHandle[textHandle].clear();
+ return true;
+}
diff --git a/extensions/threadlinker/window.cpp b/extensions/threadlinker/window.cpp
new file mode 100644
index 0000000..3d7688c
--- /dev/null
+++ b/extensions/threadlinker/window.cpp
@@ -0,0 +1,37 @@
+#include "window.h"
+#include "ui_window.h"
+#include
+
+Window::Window(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::Window)
+{
+ ui->setupUi(this);
+ threadLinkList = findChild("threadLinkList");
+}
+
+Window::~Window()
+{
+ delete ui;
+}
+
+void Window::on_linkButton_clicked()
+{
+ bool ok1, ok2, ok3, ok4;
+ int from = QInputDialog::getText(this, "Link From", "Thread number to link from?", QLineEdit::Normal, "", &ok1, Qt::WindowCloseButtonHint).toInt(&ok2, 16);
+ int to = QInputDialog::getText(this, "Link To", "Thread number to link to?", QLineEdit::Normal, "", &ok3, Qt::WindowCloseButtonHint).toInt(&ok4, 16);
+ if (ok1 && ok2 && ok3 && ok4)
+ {
+ std::lock_guard l(m);
+ linkedTextHandles[from].insert(to);
+ threadLinkList->addItem(QString::number(from, 16) + "->" + QString::number(to, 16));
+ }
+}
+
+void Window::on_unlinkButton_clicked()
+{
+ std::lock_guard l(m);
+ QStringList link = threadLinkList->currentItem()->text().split("->");
+ threadLinkList->takeItem(threadLinkList->currentRow());
+ linkedTextHandles[link[0].toInt(nullptr, 16)].erase(link[1].toInt(nullptr, 16));
+}
diff --git a/extensions/threadlinker/window.h b/extensions/threadlinker/window.h
new file mode 100644
index 0000000..46f4985
--- /dev/null
+++ b/extensions/threadlinker/window.h
@@ -0,0 +1,35 @@
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Ui
+{
+ class Window;
+}
+
+class Window : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit Window(QWidget *parent = nullptr);
+ ~Window();
+
+ Ui::Window* ui;
+ std::mutex m;
+ std::unordered_map> linkedTextHandles;
+
+private slots:
+ void on_linkButton_clicked();
+ void on_unlinkButton_clicked();
+
+private:
+ QListWidget* threadLinkList;
+};
+
+#endif // WINDOW_H
diff --git a/extensions/threadlinker/window.ui b/extensions/threadlinker/window.ui
new file mode 100644
index 0000000..606b000
--- /dev/null
+++ b/extensions/threadlinker/window.ui
@@ -0,0 +1,79 @@
+
+
+ Window
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Thread Linker
+
+
+
+ QObject
+ {
+ font: 10pt "MS Shell Dlg 2";
+ }
+ #textOutput
+ {
+ font: 13pt "MS Shell Dlg 2";
+ }
+ QPushButton, QComboBox
+ {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ padding-right: 5px;
+ padding-left: 5px;
+ text-align: left;
+ }
+
+
+
+
+
-
+
+
+
+ -
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+ Link
+
+
+
+ -
+
+
+ Unlink
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+
+
+
+
+
+
+
+