diff --git a/include/configs/proxy/WireguardBean.h b/include/configs/proxy/WireguardBean.h index ef52846..58ee1a2 100644 --- a/include/configs/proxy/WireguardBean.h +++ b/include/configs/proxy/WireguardBean.h @@ -17,15 +17,15 @@ namespace Configs { // Amnezia Options bool enable_amnezia = false; - int junk_packet_count; - int junk_packet_min_size; - int junk_packet_max_size; - int init_packet_junk_size; - int response_packet_junk_size; - int init_packet_magic_header; - int response_packet_magic_header; - int underload_packet_magic_header; - int transport_packet_magic_header; + int junk_packet_count = 0; + int junk_packet_min_size = 0; + int junk_packet_max_size = 0; + int init_packet_junk_size = 0; + int response_packet_junk_size = 0; + int init_packet_magic_header = 0; + int response_packet_magic_header = 0; + int underload_packet_magic_header = 0; + int transport_packet_magic_header = 0; WireguardBean() : AbstractBean(0) { _add(new configItem("private_key", &privateKey, itemType::string)); diff --git a/include/ui/mainwindow.h b/include/ui/mainwindow.h index e1d932e..9e6b281 100644 --- a/include/ui/mainwindow.h +++ b/include/ui/mainwindow.h @@ -232,10 +232,16 @@ private: void refresh_table_item(int row, const std::shared_ptr& profile, bool stopping); + void parseQrImage(const QPixmap *image); + void keyPressEvent(QKeyEvent *event) override; void closeEvent(QCloseEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event); + + void dropEvent(QDropEvent* event) override; + // void HotkeyEvent(const QString &key); diff --git a/include/ui/mainwindow.ui b/include/ui/mainwindow.ui index bb12e7f..b64930a 100644 --- a/include/ui/mainwindow.ui +++ b/include/ui/mainwindow.ui @@ -557,7 +557,7 @@ 0 0 800 - 17 + 25 @@ -575,6 +575,7 @@ + @@ -1052,6 +1053,11 @@ Hide window + + + Add profile from File + + diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index b78e880..69574e2 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -49,7 +49,9 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #include #endif +#include #include +#include #include #include <3rdparty/QHotkey/qhotkey.h> #include <3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp> @@ -66,6 +68,7 @@ void UI_InitMainWindow() { MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { mainwindow = this; + setAcceptDrops(true); MW_dialog_message = [=,this](const QString &a, const QString &b) { runOnUiThread([=,this] { @@ -588,6 +591,25 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi ui->menu_export_config->setVisible(name == software_core_name); ui->menu_export_config->setText(tr("Export %1 config").arg(name)); }); + connect(ui->actionAdd_profile_from_File, &QAction::triggered, this, [=,this]() + { + auto path = QFileDialog::getOpenFileName(); + if (path.isEmpty()) + { + return; + } + auto file = QFile(path); + if (!file.exists()) return; + if (file.size() > 50 * 1024 * 1024) + { + MW_show_log("File too large, will not process it"); + return; + } + file.open(QIODevice::ReadOnly); + auto contents = file.readAll(); + file.close(); + Subscription::groupUpdater->AsyncUpdate(contents); + }); connect(qApp, &QGuiApplication::commitDataRequest, this, &MainWindow::on_commitDataRequest); @@ -622,6 +644,55 @@ void MainWindow::closeEvent(QCloseEvent *event) { } } +void MainWindow::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls() || event->mimeData()->hasText()) { + event->acceptProposedAction(); + } else { + event->ignore(); + } +} + +void MainWindow::dropEvent(QDropEvent* event) +{ + auto mimeData = event->mimeData(); + + if (mimeData->hasUrls()) { + QList urlList = mimeData->urls(); + for (const QUrl &url : urlList) { + if (url.isLocalFile()) { + if (auto qpx = QPixmap(url.toLocalFile()); !qpx.isNull()) + { + parseQrImage(&qpx); + } else if (auto file = QFile(url.toLocalFile()); file.exists()) + { + file.open(QFile::ReadOnly); + if (file.size() > 50 * 1024 * 1024) + { + file.close(); + MW_show_log("File size is larger than 50MB, will not parse it"); + event->acceptProposedAction(); + return; + } + auto contents = file.readAll(); + file.close(); + Subscription::groupUpdater->AsyncUpdate(contents); + } + } + } + event->acceptProposedAction(); + return; + } + + if (mimeData->hasText()) { + Subscription::groupUpdater->AsyncUpdate(mimeData->text()); + event->acceptProposedAction(); + return; + } + + event->ignore(); +} + MainWindow::~MainWindow() { delete ui; } @@ -1898,6 +1969,19 @@ QPixmap grabScreen(QScreen* screen, bool& ok) return screen->grabWindow(0, geom.x(), geom.y(), geom.width(), geom.height()); } +void MainWindow::parseQrImage(const QPixmap *image) +{ + const QVector texts = QrDecoder().decode(image->toImage().convertToFormat(QImage::Format_Grayscale8)); + if (texts.isEmpty()) { + MessageBoxInfo(software_name, tr("QR Code not found")); + } else { + for (const QString &text : texts) { + show_log_impl("QR Code Result:\n" + text); + Subscription::groupUpdater->AsyncUpdate(text); + } + } +} + void MainWindow::on_menu_scan_qr_triggered() { hide(); QThread::sleep(1); @@ -1907,15 +1991,7 @@ void MainWindow::on_menu_scan_qr_triggered() { show(); if (ok) { - const QVector texts = QrDecoder().decode(qpx.toImage().convertToFormat(QImage::Format_Grayscale8)); - if (texts.isEmpty()) { - MessageBoxInfo(software_name, tr("QR Code not found")); - } else { - for (const QString &text : texts) { - show_log_impl("QR Code Result:\n" + text); - Subscription::groupUpdater->AsyncUpdate(text); - } - } + parseQrImage(&qpx); } else { MessageBoxInfo(software_name, tr("Unable to capture screen")); @@ -2370,6 +2446,7 @@ void MainWindow::setActionsData() ui->actionUrl_Test_Group->setData(QString("m21")); ui->actionUrl_Test_Selected->setData(QString("m22")); ui->actionHide_window->setData(QString("m23")); + ui->actionAdd_profile_from_File->setData(QString("m24")); } QList MainWindow::getActionsForShortcut()