diff --git a/db/ConfigBuilder.cpp b/db/ConfigBuilder.cpp index cec12f9..066186a 100644 --- a/db/ConfigBuilder.cpp +++ b/db/ConfigBuilder.cpp @@ -93,27 +93,46 @@ namespace NekoGui { } QString BuildChain(int chainId, const std::shared_ptr &status) { - // Make list - QList> ents; - auto ent = status->ent; - auto result = status->result; + auto group = profileManager->GetGroup(status->ent->gid); + if (group == nullptr) { + status->result->error = QString("This profile is not in any group, your data may be corrupted."); + return {}; + } - if (ent->type == "chain") { - auto list = ent->ChainBean()->list; - std::reverse(std::begin(list), std::end(list)); - for (auto id: list) { - ents += profileManager->GetProfile(id); - if (ents.last() == nullptr) { - status->result->error = QString("chain missing ent: %1").arg(id); - return {}; - } - if (ents.last()->type == "chain") { - status->result->error = QString("chain in chain is not allowed: %1").arg(id); - return {}; + auto resolveChain = [=](const std::shared_ptr &ent) { + QList> resolved; + if (ent->type == "chain") { + auto list = ent->ChainBean()->list; + std::reverse(std::begin(list), std::end(list)); + for (auto id: list) { + resolved += profileManager->GetProfile(id); + if (resolved.last() == nullptr) { + status->result->error = QString("chain missing ent: %1").arg(id); + break; + } + if (resolved.last()->type == "chain") { + status->result->error = QString("chain in chain is not allowed: %1").arg(id); + break; + } } + } else { + resolved += ent; + }; + return resolved; + }; + + // Make list + auto ents = resolveChain(status->ent); + if (!status->result->error.isEmpty()) return {}; + + if (group->front_proxy_id >= 0) { + auto fEnt = profileManager->GetProfile(group->front_proxy_id); + if (fEnt == nullptr) { + status->result->error = QString("front proxy ent not found."); + return {}; } - } else { - ents += ent; + ents += resolveChain(fEnt); + if (!status->result->error.isEmpty()) return {}; } // BuildChain diff --git a/db/Database.cpp b/db/Database.cpp index 5efba31..85152d0 100644 --- a/db/Database.cpp +++ b/db/Database.cpp @@ -207,6 +207,7 @@ namespace NekoGui { Group::Group() { _add(new configItem("id", &id, itemType::integer)); + _add(new configItem("front_proxy_id", &front_proxy_id, itemType::integer)); _add(new configItem("archive", &archive, itemType::boolean)); _add(new configItem("name", &name, itemType::string)); _add(new configItem("order", &order, itemType::integerList)); diff --git a/db/Group.hpp b/db/Group.hpp index f6e0a36..1dfd743 100644 --- a/db/Group.hpp +++ b/db/Group.hpp @@ -12,6 +12,7 @@ namespace NekoGui { QString url = ""; QString info = ""; qint64 sub_last_update = 0; + int front_proxy_id = -1; // list ui bool manually_column_width = false; diff --git a/translations/fa_IR.ts b/translations/fa_IR.ts index 054d80d..6b4607d 100644 --- a/translations/fa_IR.ts +++ b/translations/fa_IR.ts @@ -290,6 +290,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod Manually column width عرض ستون به صورت دستی + + Front Proxy + + + + None + هیچ یک + DialogEditProfile diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 8063456..63ae7b0 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -290,6 +290,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in VPN mode, normal mod Manually column width 手动调节列宽 + + Front Proxy + 前置代理 + + + None + + DialogEditProfile diff --git a/ui/edit/dialog_edit_group.cpp b/ui/edit/dialog_edit_group.cpp index 32e60f4..d560aee 100644 --- a/ui/edit/dialog_edit_group.cpp +++ b/ui/edit/dialog_edit_group.cpp @@ -2,12 +2,13 @@ #include "ui_dialog_edit_group.h" #include "db/Database.hpp" +#include "ui/mainwindow_interface.h" #include -DialogEditGroup::DialogEditGroup(const std::shared_ptr &ent, QWidget *parent) - : QDialog(parent), ui(new Ui::DialogEditGroup) { +DialogEditGroup::DialogEditGroup(const std::shared_ptr &ent, QWidget *parent) : QDialog(parent), ui(new Ui::DialogEditGroup) { ui->setupUi(this); + this->ent = ent; connect(ui->type, static_cast(&QComboBox::currentIndexChanged), this, [=](int index) { ui->cat_sub->setHidden(index == 0); @@ -21,27 +22,20 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr &ent, QWi ui->manually_column_width->setChecked(ent->manually_column_width); ui->copy_links->setVisible(false); ui->copy_links_nkr->setVisible(false); + if (ent->id >= 0) { // already a group ui->type->setDisabled(true); if (!ent->Profiles().isEmpty()) { ui->copy_links->setVisible(true); ui->copy_links_nkr->setVisible(true); } + } else { // new group + ui->front_proxy->hide(); + ui->front_proxy_l->hide(); } - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, [=] { - if (ent->id >= 0) { // already a group - if (!ent->url.isEmpty() && ui->url->text().isEmpty()) { - MessageBoxWarning(tr("Warning"), tr("Please input URL")); - return; - } - } - ent->name = ui->name->text(); - ent->url = ui->url->text(); - ent->archive = ui->archive->isChecked(); - ent->manually_column_width = ui->manually_column_width->isChecked(); - QDialog::accept(); - }); + CACHE.front_proxy = ent->front_proxy_id; + refresh_front_proxy(); connect(ui->copy_links, &QPushButton::clicked, this, [=] { QStringList links; @@ -66,3 +60,35 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr &ent, QWi DialogEditGroup::~DialogEditGroup() { delete ui; } + +void DialogEditGroup::accept() { + if (ent->id >= 0) { // already a group + if (!ent->url.isEmpty() && ui->url->text().isEmpty()) { + MessageBoxWarning(tr("Warning"), tr("Please input URL")); + return; + } + } + ent->name = ui->name->text(); + ent->url = ui->url->text(); + ent->archive = ui->archive->isChecked(); + ent->manually_column_width = ui->manually_column_width->isChecked(); + ent->front_proxy_id = CACHE.front_proxy; + QDialog::accept(); +} + +void DialogEditGroup::refresh_front_proxy() { + auto fEnt = NekoGui::profileManager->GetProfile(CACHE.front_proxy); + ui->front_proxy->setText(fEnt == nullptr ? tr("None") : fEnt->bean->DisplayTypeAndName()); +} + +void DialogEditGroup::on_front_proxy_clicked() { + auto parent = dynamic_cast(this->parent()); + parent->hide(); + this->hide(); + GetMainWindow()->start_select_mode(this, [=](int id) { + CACHE.front_proxy = id; + refresh_front_proxy(); + parent->show(); + show(); + }); +} diff --git a/ui/edit/dialog_edit_group.h b/ui/edit/dialog_edit_group.h index c6c678e..5aa3d9f 100644 --- a/ui/edit/dialog_edit_group.h +++ b/ui/edit/dialog_edit_group.h @@ -19,4 +19,18 @@ public: private: Ui::DialogEditGroup *ui; + + std::shared_ptr ent; + + struct { + int front_proxy; + } CACHE; + + void refresh_front_proxy(); + +private slots: + + void accept() override; + + void on_front_proxy_clicked(); }; diff --git a/ui/edit/dialog_edit_group.ui b/ui/edit/dialog_edit_group.ui index ae920e6..423d0f5 100644 --- a/ui/edit/dialog_edit_group.ui +++ b/ui/edit/dialog_edit_group.ui @@ -84,6 +84,20 @@ + + + + + + + + + + + Front Proxy + + + @@ -177,5 +191,21 @@ + + buttonBox + accepted() + DialogEditGroup + accept() + + + 199 + 291 + + + 199 + 157 + + + diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index a3d39f4..a92efa3 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -592,13 +592,15 @@ void MainWindow::dialog_message_impl(const QString &sender, const QString &info) inline bool dialog_is_using = false; -#define USE_DIALOG(a) \ - if (dialog_is_using) return; \ - dialog_is_using = true; \ - auto dialog = new a(this); \ - dialog->exec(); \ - dialog->deleteLater(); \ - dialog_is_using = false; +#define USE_DIALOG(a) \ + if (dialog_is_using) return; \ + dialog_is_using = true; \ + auto dialog = new a(this); \ + connect(dialog, &QDialog::finished, this, [=] { \ + dialog->deleteLater(); \ + dialog_is_using = false; \ + }); \ + dialog->show(); void MainWindow::on_menu_basic_settings_triggered() { USE_DIALOG(DialogBasicSettings) diff --git a/ui/widget/GroupItem.cpp b/ui/widget/GroupItem.cpp index 19f307d..195ee98 100644 --- a/ui/widget/GroupItem.cpp +++ b/ui/widget/GroupItem.cpp @@ -45,6 +45,7 @@ GroupItem::GroupItem(QWidget *parent, const std::shared_ptr &ent ui->setupUi(this); this->setLayoutDirection(Qt::LeftToRight); + this->parentWindow = parent; this->ent = ent; this->item = item; if (ent == nullptr) return; @@ -102,15 +103,16 @@ void GroupItem::on_update_sub_clicked() { } void GroupItem::on_edit_clicked() { - auto dialog = new DialogEditGroup(ent, this); - int ret = dialog->exec(); - dialog->deleteLater(); - - if (ret == QDialog::Accepted) { - ent->Save(); - refresh_data(); - MW_dialog_message(Dialog_DialogManageGroups, "refresh" + Int2String(ent->id)); - } + auto dialog = new DialogEditGroup(ent, parentWindow); + connect(dialog, &QDialog::finished, this, [=] { + if (dialog->result() == QDialog::Accepted) { + ent->Save(); + refresh_data(); + MW_dialog_message(Dialog_DialogManageGroups, "refresh" + Int2String(ent->id)); + } + dialog->deleteLater(); + }); + dialog->show(); } void GroupItem::on_remove_clicked() { diff --git a/ui/widget/GroupItem.h b/ui/widget/GroupItem.h index 61c7e58..14aa864 100644 --- a/ui/widget/GroupItem.h +++ b/ui/widget/GroupItem.h @@ -27,6 +27,8 @@ public: private: Ui::GroupItem *ui; + QWidget *parentWindow; + signals: void edit_clicked();