Textractor/extensions/threadlinker.cpp
2019-02-27 11:33:17 -05:00

105 lines
2.7 KiB
C++

#include "extension.h"
#include <QMainWindow>
#include <QLayout>
#include <QPushButton>
#include <QListWidget>
#include <QInputDialog>
#include <QKeyEvent>
#include <QTimer>
extern const char* THREAD_LINKER;
extern const char* LINK;
extern const char* THREAD_LINK_FROM;
extern const char* THREAD_LINK_TO;
std::mutex m;
std::unordered_map<int64_t, std::unordered_multiset<int64_t>> linkedTextHandles;
struct : QMainWindow
{
void launch()
{
auto centralWidget = new QWidget(this);
auto layout = new QHBoxLayout(centralWidget);
auto linkList = new QListWidget(centralWidget);
auto addLink = new QPushButton(LINK, centralWidget);
layout->addWidget(linkList);
layout->addWidget(addLink);
connect(addLink, &QPushButton::clicked, [=]
{
bool ok1, ok2, ok3, ok4;
int from = QInputDialog::getText(this, THREAD_LINK_FROM, "", QLineEdit::Normal, "0x", &ok1, Qt::WindowCloseButtonHint).toInt(&ok2, 16);
int to = QInputDialog::getText(this, THREAD_LINK_TO, "", QLineEdit::Normal, "0x", &ok3, Qt::WindowCloseButtonHint).toInt(&ok4, 16);
if (ok1 && ok2 && ok3 && ok4)
{
std::lock_guard l(m);
linkedTextHandles[from].insert(to);
linkList->addItem(QString::number(from, 16) + "->" + QString::number(to, 16));
}
});
Unlink = [=]
{
if (linkList->currentItem())
{
QStringList link = linkList->currentItem()->text().split("->");
linkList->takeItem(linkList->currentRow());
std::lock_guard l(m);
linkedTextHandles[link[0].toInt(nullptr, 16)].erase(link[1].toInt(nullptr, 16));
}
};
setCentralWidget(centralWidget);
setWindowTitle(THREAD_LINKER);
show();
}
void keyPressEvent(QKeyEvent* event) override
{
if (event->key() == Qt::Key_Delete) Unlink();
}
std::function<void()> Unlink;
}*window = 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, []
{
std::lock_guard l(m);
(window = new std::remove_pointer_t<decltype(window)>)->launch();
});
}
break;
case DLL_PROCESS_DETACH:
{
if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
{
std::lock_guard l(m);
delete window;
window = nullptr;
}
}
break;
}
return TRUE;
}
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
{
std::lock_guard l(m);
static std::unordered_map<int64_t, std::wstring> queuedWritesByHandle;
int64_t textHandle = sentenceInfo["text handle"];
for (auto linkedHandle : linkedTextHandles[textHandle]) queuedWritesByHandle[linkedHandle] += L"\n" + sentence;
if (queuedWritesByHandle[textHandle].empty()) return false;
sentence += queuedWritesByHandle[textHandle];
queuedWritesByHandle[textHandle].clear();
return true;
}