AdaptixC2-Mod0/AdaptixClient/Source/Utils/NonBlockingDialogs.cpp
2026-04-06 00:20:51 -05:00

225 lines
7.2 KiB
C++

#include <Utils/NonBlockingDialogs.h>
#include <QDir>
#include <QFileInfo>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QAbstractButton>
#include <QTimer>
#include <QApplication>
#include <QEventLoop>
#include <functional>
QTimer* NonBlockingDialogs::keepAliveTimer = nullptr;
int NonBlockingDialogs::activeDialogs = 0;
void NonBlockingDialogs::startKeepAlive()
{
activeDialogs++;
if (!keepAliveTimer) {
keepAliveTimer = new QTimer();
QObject::connect(keepAliveTimer, &QTimer::timeout, [](){
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 50);
});
}
if (!keepAliveTimer->isActive()) {
keepAliveTimer->start(500);
}
}
void NonBlockingDialogs::stopKeepAlive()
{
activeDialogs--;
if (activeDialogs <= 0 && keepAliveTimer) {
keepAliveTimer->stop();
activeDialogs = 0;
}
}
void NonBlockingDialogs::getSaveFileName(QWidget* parent, const QString& caption, const QString& dir, const QString& filter, std::function<void(const QString&)> callback)
{
QFileInfo fileInfo(dir);
QFileDialog* dialog = new QFileDialog(parent);
dialog->setAcceptMode(QFileDialog::AcceptSave);
dialog->setWindowTitle(caption);
dialog->setDirectory(fileInfo.absolutePath());
dialog->setNameFilter(filter);
dialog->setOption(QFileDialog::DontUseNativeDialog, true);
dialog->selectFile(fileInfo.fileName());
dialog->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(dialog, &QFileDialog::finished, [dialog, callback](int result) {
stopKeepAlive();
if (result == QDialog::Accepted && !dialog->selectedFiles().isEmpty()) {
callback(dialog->selectedFiles().first());
} else {
callback(QString());
}
});
startKeepAlive();
dialog->open();
}
void NonBlockingDialogs::getOpenFileName(QWidget* parent, const QString& caption, const QString& dir, const QString& filter, std::function<void(const QString&)> callback)
{
QFileDialog* dialog = new QFileDialog(parent);
dialog->setAcceptMode(QFileDialog::AcceptOpen);
dialog->setFileMode(QFileDialog::ExistingFile);
dialog->setWindowTitle(caption);
dialog->setDirectory(dir);
dialog->setNameFilter(filter);
dialog->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(dialog, &QFileDialog::finished, [dialog, callback](int result) {
stopKeepAlive();
if (result == QDialog::Accepted && !dialog->selectedFiles().isEmpty()) {
callback(dialog->selectedFiles().first());
} else {
callback(QString());
}
});
startKeepAlive();
dialog->open();
}
void NonBlockingDialogs::getExistingDirectory(QWidget* parent, const QString& caption, const QString& dir, std::function<void(const QString&)> callback)
{
QFileDialog* dialog = new QFileDialog(parent);
dialog->setAcceptMode(QFileDialog::AcceptOpen);
dialog->setFileMode(QFileDialog::Directory);
dialog->setOption(QFileDialog::ShowDirsOnly, true);
dialog->setWindowTitle(caption);
dialog->setDirectory(dir);
dialog->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(dialog, &QFileDialog::finished, [dialog, callback](int result) {
stopKeepAlive();
if (result == QDialog::Accepted && !dialog->selectedFiles().isEmpty()) {
callback(dialog->selectedFiles().first());
} else {
callback(QString());
}
});
startKeepAlive();
dialog->open();
}
void NonBlockingDialogs::getText(QWidget* parent, const QString& title, const QString& label, const QString& text, std::function<void(const QString&, bool)> callback)
{
QInputDialog* dialog = new QInputDialog(parent);
dialog->setWindowTitle(title);
dialog->setLabelText(label);
dialog->setTextValue(text);
dialog->setInputMode(QInputDialog::TextInput);
dialog->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(dialog, &QInputDialog::textValueSelected, [callback](const QString& text) {
stopKeepAlive();
callback(text, true);
});
QObject::connect(dialog, &QInputDialog::rejected, [callback]() {
stopKeepAlive();
callback(QString(), false);
});
startKeepAlive();
dialog->open();
}
void NonBlockingDialogs::getInt(QWidget* parent, const QString& title, const QString& label, int value, int min, int max, int step, std::function<void(int, bool)> callback)
{
QInputDialog* dialog = new QInputDialog(parent);
dialog->setWindowTitle(title);
dialog->setLabelText(label);
dialog->setIntValue(value);
dialog->setIntMinimum(min);
dialog->setIntMaximum(max);
dialog->setIntStep(step);
dialog->setInputMode(QInputDialog::IntInput);
dialog->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(dialog, &QInputDialog::intValueSelected, [callback](int value) {
stopKeepAlive();
callback(value, true);
});
QObject::connect(dialog, &QInputDialog::rejected, [callback]() {
stopKeepAlive();
callback(0, false);
});
startKeepAlive();
dialog->open();
}
void NonBlockingDialogs::question(QWidget* parent, const QString& title, const QString& text, std::function<void(QMessageBox::StandardButton)> callback)
{
QMessageBox* msgBox = new QMessageBox(parent);
msgBox->setWindowTitle(title);
msgBox->setText(text);
msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox->setDefaultButton(QMessageBox::No);
msgBox->setIcon(QMessageBox::Question);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(msgBox, &QMessageBox::buttonClicked, [callback](QAbstractButton* button) {
stopKeepAlive();
QMessageBox::StandardButton standardButton = QMessageBox::NoButton;
if (button) {
QMessageBox* msgBox = qobject_cast<QMessageBox*>(button->parent());
if (msgBox) {
standardButton = msgBox->standardButton(button);
}
}
callback(standardButton);
});
startKeepAlive();
msgBox->open();
}
void NonBlockingDialogs::information(QWidget* parent, const QString& title, const QString& text, std::function<void()> callback)
{
QMessageBox* msgBox = new QMessageBox(parent);
msgBox->setWindowTitle(title);
msgBox->setText(text);
msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setIcon(QMessageBox::Information);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(msgBox, &QMessageBox::finished, [callback](int) {
stopKeepAlive();
if (callback) {
callback();
}
});
startKeepAlive();
msgBox->open();
}
void NonBlockingDialogs::critical(QWidget* parent, const QString& title, const QString& text, std::function<void()> callback)
{
QMessageBox* msgBox = new QMessageBox(parent);
msgBox->setWindowTitle(title);
msgBox->setText(text);
msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setIcon(QMessageBox::Critical);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(msgBox, &QMessageBox::finished, [callback](int) {
stopKeepAlive();
if (callback) {
callback();
}
});
startKeepAlive();
msgBox->open();
}