can use right click and file dialog to add extension, also fix segfault when multiple copies of extension are added then removed

This commit is contained in:
Akash Mozumdar 2019-08-29 13:46:21 -04:00
parent 590c08e8d0
commit 1cf60785e3
4 changed files with 43 additions and 23 deletions

View File

@ -2,12 +2,15 @@
#include "ui_extenwindow.h"
#include "defs.h"
#include <concrt.h>
#include <QMenu>
#include <QFileDialog>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QUrl>
extern const char* EXTENSIONS;
extern const char* ADD_EXTENSION;
extern const char* INVALID_EXTENSION;
extern const char* CONFIRM_EXTENSION_OVERWRITE;
extern const char* EXTENSION_WRITE_ERROR;
@ -20,7 +23,7 @@ namespace
struct Extension
{
std::wstring name;
wchar_t*(*callback)(wchar_t*, const InfoForExtension*);
wchar_t* (*callback)(wchar_t*, const InfoForExtension*);
};
concurrency::reader_writer_lock extenMutex;
@ -30,6 +33,8 @@ namespace
{
// Extension is dll and exports "OnNewSentence"
if (QTextFile(extenName + ".dll", QIODevice::ReadOnly).readAll().contains("OnNewSentence"))
{
if (HMODULE module = LoadLibraryW(S(extenName).c_str()))
{
if (auto callback = (decltype(Extension::callback))GetProcAddress(LoadLibraryOnce(S(extenName)), "OnNewSentence"))
{
@ -37,6 +42,8 @@ namespace
extensions.push_back({ S(extenName), callback });
return true;
}
FreeLibrary(module);
}
}
return false;
}
@ -73,8 +80,7 @@ bool DispatchSentenceToExtensions(std::wstring& sentence, const InfoForExtension
void CleanupExtensions()
{
std::scoped_lock writeLock(extenMutex);
for (auto extension : extensions)
FreeLibrary(GetModuleHandleW(extension.name.c_str()));
for (auto extension : extensions) FreeLibrary(GetModuleHandleW(extension.name.c_str()));
extensions.clear();
}
@ -84,6 +90,12 @@ ExtenWindow::ExtenWindow(QWidget* parent) :
{
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));
setWindowTitle(EXTENSIONS);
@ -99,6 +111,20 @@ 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();
@ -140,16 +166,5 @@ void ExtenWindow::dragEnterEvent(QDragEnterEvent* event)
void ExtenWindow::dropEvent(QDropEvent* event)
{
for (auto file : event->mimeData()->urls())
{
QFileInfo extenFile = file.toLocalFile();
if (extenFile.suffix() != "dll") continue;
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())) Sync();
else QMessageBox::information(this, EXTENSIONS, QString(INVALID_EXTENSION).arg(extenFile.fileName()));
}
for (auto file : event->mimeData()->urls()) Add(file.toLocalFile());
}

View File

@ -25,6 +25,7 @@ public:
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;

View File

@ -17,6 +17,9 @@
<layout class="QVBoxLayout">
<item>
<widget class="QListWidget" name="extenList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>

View File

@ -41,11 +41,12 @@ Negatives for data_offset/split_offset refer to registers
-C for RAX, -14 for RBX, -1C for RCX, -24 for RDX, and so on for RSP, RBP, RSI, RDI, R8-R15
* means dereference pointer+deref_offset)";
const char* SAVE_SETTINGS = u8"Save settings";
const char* EXTEN_WINDOW_INSTRUCTIONS = u8R"(Drag and drop extension (.dll) files here from your computer to add them
(Does not work if running as administrator)
Drag and drop within the list to reorder
const char* EXTEN_WINDOW_INSTRUCTIONS = u8R"(To add an extension, right click the extension list
Alternatively, drag and drop the extension file from your computer
To reorder extensions, drag and drop them within the list
(Extensions are used from top to bottom: order DOES matter)
Press delete with an extension selected to remove it)";
To remove an extension, select it and press delete)";
const char* ADD_EXTENSION = u8"Add extension";
const char* INVALID_EXTENSION = u8"%1 is an invalid extension";
const char* CONFIRM_EXTENSION_OVERWRITE = u8"Another version of this extension already exists, do you want to delete and overwrite it?";
const char* EXTENSION_WRITE_ERROR = u8"Failed to save extension";