mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 12:34:37 +03:00
feat: Automatic update subscription
This commit is contained in:
@@ -1061,7 +1061,6 @@ namespace NekoGui {
|
||||
auto configFn = ":/neko/vpn/sing-box-vpn.json";
|
||||
if (QFile::exists("vpn/sing-box-vpn.json")) configFn = "vpn/sing-box-vpn.json";
|
||||
auto config = ReadFileText(configFn)
|
||||
.replace("%ENABLED_FAKEDNS%", dataStore->fake_dns ? "true" : "false")
|
||||
.replace("//%IPV6_ADDRESS%", dataStore->vpn_ipv6 ? R"("inet6_address": "fdfe:dcba:9876::1/126",)" : "")
|
||||
.replace("//%SOCKS_USER_PASS%", socks_user_pass)
|
||||
.replace("//%PROCESS_NAME_RULE%", process_name_rule)
|
||||
@@ -1072,6 +1071,7 @@ namespace NekoGui {
|
||||
.replace("%STRICT_ROUTE%", dataStore->vpn_strict_route ? "true" : "false")
|
||||
.replace("%FINAL_OUT%", no_match_out)
|
||||
.replace("%DNS_ADDRESS%", BOX_UNDERLYING_DNS)
|
||||
.replace("%FAKE_DNS_ENABLE%", dataStore->fake_dns ? "true" : "false")
|
||||
.replace("%FAKE_DNS_INBOUND%", dataStore->fake_dns ? "tun-in" : "empty")
|
||||
.replace("%PORT%", Int2String(dataStore->inbound_socks_port));
|
||||
// hook.js
|
||||
|
||||
@@ -305,6 +305,7 @@ namespace NekoGui {
|
||||
_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("skip_auto_update", &skip_auto_update, itemType::boolean));
|
||||
_add(new configItem("name", &name, itemType::string));
|
||||
_add(new configItem("order", &order, itemType::integerList));
|
||||
_add(new configItem("url", &url, itemType::string));
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace NekoGui {
|
||||
public:
|
||||
int id = -1;
|
||||
bool archive = false;
|
||||
bool skip_auto_update = false;
|
||||
QString name = "";
|
||||
QString url = "";
|
||||
QString info = "";
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QNetworkProxy>
|
||||
#include <QEventLoop>
|
||||
#include <QMetaEnum>
|
||||
#include <QTimer>
|
||||
|
||||
#include "main/NekoGui.hpp"
|
||||
|
||||
@@ -52,12 +53,21 @@ namespace NekoGui_network {
|
||||
}
|
||||
MW_show_log(QString("SSL Errors: %1 %2").arg(error_str.join(","), NekoGui::dataStore->sub_insecure ? "(Ignored)" : ""));
|
||||
});
|
||||
//
|
||||
// Wait for response
|
||||
auto abortTimer = new QTimer;
|
||||
abortTimer->setSingleShot(true);
|
||||
abortTimer->setInterval(10000);
|
||||
QObject::connect(abortTimer, &QTimer::timeout, _reply, &QNetworkReply::abort);
|
||||
abortTimer->start();
|
||||
{
|
||||
QEventLoop loop;
|
||||
QObject::connect(&accessManager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
|
||||
QObject::connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
}
|
||||
if (abortTimer != nullptr) {
|
||||
abortTimer->stop();
|
||||
abortTimer->deleteLater();
|
||||
}
|
||||
//
|
||||
auto result = NekoHTTPResponse{_reply->error() == QNetworkReply::NetworkError::NoError ? "" : _reply->errorString(),
|
||||
_reply->readAll(), _reply->rawHeaderPairs()};
|
||||
|
||||
@@ -271,6 +271,7 @@ namespace NekoGui {
|
||||
_add(new configItem("sp_format", &system_proxy_format, itemType::string));
|
||||
_add(new configItem("sub_clear", &sub_clear, itemType::boolean));
|
||||
_add(new configItem("sub_insecure", &sub_insecure, itemType::boolean));
|
||||
_add(new configItem("sub_auto_update", &sub_auto_update, itemType::integer));
|
||||
_add(new configItem("enable_js_hook", &enable_js_hook, itemType::integer));
|
||||
_add(new configItem("log_ignore", &log_ignore, itemType::stringList));
|
||||
_add(new configItem("start_minimal", &start_minimal, itemType::boolean));
|
||||
|
||||
@@ -121,6 +121,7 @@ namespace NekoGui {
|
||||
bool sub_use_proxy = false;
|
||||
bool sub_clear = false;
|
||||
bool sub_insecure = false;
|
||||
int sub_auto_update = -30;
|
||||
|
||||
// Security
|
||||
bool skip_cert = false;
|
||||
|
||||
@@ -28,6 +28,12 @@ inline std::function<void(QString, QString)> MW_dialog_message;
|
||||
class QThread;
|
||||
inline QThread *DS_cores;
|
||||
|
||||
// Timers
|
||||
|
||||
class QTimer;
|
||||
inline QTimer *TM_auto_update_subsctiption;
|
||||
inline std::function<void(int)> TM_auto_update_subsctiption_Reset_Minute;
|
||||
|
||||
// String
|
||||
|
||||
#define FIRST_OR_SECOND(a, b) a.isEmpty() ? b : a
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
},
|
||||
"dns": {
|
||||
"fakeip": {
|
||||
"enabled": %ENABLED_FAKEDNS%,
|
||||
"enabled": %FAKE_DNS_ENABLE%,
|
||||
"inet4_range": "198.18.0.0/15",
|
||||
"inet6_range": "fc00::/18"
|
||||
},
|
||||
|
||||
@@ -114,9 +114,7 @@ namespace QtGrpc {
|
||||
abortTimer = new QTimer;
|
||||
abortTimer->setSingleShot(true);
|
||||
abortTimer->setInterval(timeout_ms);
|
||||
QObject::connect(abortTimer, &QTimer::timeout, abortTimer, [=]() {
|
||||
networkReply->abort();
|
||||
});
|
||||
QObject::connect(abortTimer, &QTimer::timeout, networkReply, &QNetworkReply::abort);
|
||||
abortTimer->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -561,3 +561,53 @@ namespace NekoGui_sub {
|
||||
}
|
||||
}
|
||||
} // namespace NekoGui_sub
|
||||
|
||||
bool UI_update_all_groups_Updating = false;
|
||||
|
||||
#define should_skip_group(g) (g == nullptr || g->url.isEmpty() || g->archive || (onlyAllowed && g->skip_auto_update))
|
||||
|
||||
void serialUpdateSubscription(const QList<int> &groupsTabOrder, int _order, bool onlyAllowed) {
|
||||
// calculate next group
|
||||
int nextOrder = _order;
|
||||
std::shared_ptr<NekoGui::Group> nextGroup;
|
||||
forever {
|
||||
nextOrder += 1;
|
||||
if (nextOrder >= groupsTabOrder.size()) break;
|
||||
auto nextGid = groupsTabOrder[nextOrder];
|
||||
nextGroup = NekoGui::profileManager->GetGroup(nextGid);
|
||||
if (should_skip_group(nextGroup)) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
// calculate this group
|
||||
auto group = NekoGui::profileManager->GetGroup(groupsTabOrder[_order]);
|
||||
if (group == nullptr) {
|
||||
UI_update_all_groups_Updating = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// v2.2: listener is moved to GroupItem, no refresh here.
|
||||
NekoGui_sub::groupUpdater->AsyncUpdate(group->url, group->id, [=] {
|
||||
if (nextGroup == nullptr) {
|
||||
UI_update_all_groups_Updating = false;
|
||||
} else {
|
||||
serialUpdateSubscription(groupsTabOrder, nextOrder, onlyAllowed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void UI_update_all_groups(bool onlyAllowed) {
|
||||
if (UI_update_all_groups_Updating) {
|
||||
MW_show_log("The last subscription update has not exited.");
|
||||
return;
|
||||
}
|
||||
// first: freeze group order
|
||||
auto groupsTabOrder = NekoGui::profileManager->groupsTabOrder;
|
||||
for (const auto &gid: groupsTabOrder) {
|
||||
auto group = NekoGui::profileManager->GetGroup(gid);
|
||||
if (should_skip_group(group)) continue;
|
||||
// start
|
||||
UI_update_all_groups_Updating = true;
|
||||
serialUpdateSubscription(groupsTabOrder, groupsTabOrder.indexOf(gid), onlyAllowed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,3 +29,6 @@ namespace NekoGui_sub {
|
||||
|
||||
extern GroupUpdater *groupUpdater;
|
||||
} // namespace NekoGui_sub
|
||||
|
||||
// 更新所有订阅 关闭分组窗口时 更新动作继续执行
|
||||
void UI_update_all_groups(bool onlyAllowed = false);
|
||||
|
||||
@@ -247,6 +247,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Timeout (s)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Automatic update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Interval (minute, invalid if less than 30)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditGroup</name>
|
||||
@@ -314,6 +322,18 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Clear</source>
|
||||
<translation type="unfinished">پاک کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip automatic update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common</source>
|
||||
<translation type="unfinished">متداول</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Share</source>
|
||||
<translation type="unfinished">اشتراک گذاری</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditProfile</name>
|
||||
|
||||
@@ -243,6 +243,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Timeout (s)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Automatic update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Interval (minute, invalid if less than 30)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditGroup</name>
|
||||
@@ -310,6 +318,18 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>None</source>
|
||||
<translation>Нет</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip automatic update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common</source>
|
||||
<translation type="unfinished">Общие</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Share</source>
|
||||
<translation type="unfinished">Поделиться</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditProfile</name>
|
||||
|
||||
@@ -243,6 +243,14 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Timeout (s)</source>
|
||||
<translation>超时(秒)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Automatic update</source>
|
||||
<translation>自动更新订阅</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Interval (minute, invalid if less than 30)</source>
|
||||
<translation>时间间隔(分钟,少于 30 分钟无效)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditGroup</name>
|
||||
@@ -310,6 +318,18 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
|
||||
<source>Clear</source>
|
||||
<translation>清除</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip automatic update</source>
|
||||
<translation>跳过自动更新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Common</source>
|
||||
<translation>通用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Share</source>
|
||||
<translation>分享</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogEditProfile</name>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
class ExtraCoreWidget : public QWidget {
|
||||
public:
|
||||
@@ -158,6 +159,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
D_LOAD_BOOL(sub_use_proxy)
|
||||
D_LOAD_BOOL(sub_clear)
|
||||
D_LOAD_BOOL(sub_insecure)
|
||||
D_LOAD_INT_ENABLE(sub_auto_update, sub_auto_update_enable)
|
||||
|
||||
// Core
|
||||
|
||||
@@ -298,10 +300,17 @@ void DialogBasicSettings::accept() {
|
||||
|
||||
// Subscription
|
||||
|
||||
if (ui->sub_auto_update_enable->isChecked()) {
|
||||
TM_auto_update_subsctiption_Reset_Minute(ui->sub_auto_update->text().toInt());
|
||||
} else {
|
||||
TM_auto_update_subsctiption_Reset_Minute(0);
|
||||
}
|
||||
|
||||
NekoGui::dataStore->user_agent = ui->user_agent->text();
|
||||
D_SAVE_BOOL(sub_use_proxy)
|
||||
D_SAVE_BOOL(sub_clear)
|
||||
D_SAVE_BOOL(sub_insecure)
|
||||
D_SAVE_INT_ENABLE(sub_auto_update, sub_auto_update_enable)
|
||||
|
||||
// Core
|
||||
|
||||
|
||||
@@ -486,37 +486,84 @@
|
||||
<string>Subscription</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="sub_auto_update_enable">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>User Agent</string>
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="MyLineEdit" name="user_agent"/>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>Interval (minute, invalid if less than 30)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="sub_auto_update">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="MyLineEdit" name="user_agent"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="sub_use_proxy">
|
||||
<property name="text">
|
||||
<string>Use proxy when updating subscription</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="sub_insecure">
|
||||
<property name="text">
|
||||
<string>Ignore TLS errors when updating subscription</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="sub_clear">
|
||||
<property name="text">
|
||||
<string>Clear servers before updating subscription</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automatic update</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>User Agent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
|
||||
@@ -53,34 +53,6 @@ void DialogManageGroups::on_add_clicked() {
|
||||
|
||||
void DialogManageGroups::on_update_all_clicked() {
|
||||
if (QMessageBox::question(this, tr("Confirmation"), tr("Update all subscriptions?")) == QMessageBox::StandardButton::Yes) {
|
||||
for (const auto &gid: NekoGui::profileManager->groupsTabOrder) {
|
||||
auto group = NekoGui::profileManager->GetGroup(gid);
|
||||
if (group == nullptr || group->url.isEmpty()) continue;
|
||||
UI_update_one_group(NekoGui::profileManager->groupsTabOrder.indexOf(gid));
|
||||
return;
|
||||
}
|
||||
UI_update_all_groups();
|
||||
}
|
||||
}
|
||||
|
||||
void UI_update_one_group(int _order) {
|
||||
// calculate next group
|
||||
int nextOrder = _order;
|
||||
std::shared_ptr<NekoGui::Group> nextGroup;
|
||||
forever {
|
||||
nextOrder += 1;
|
||||
if (nextOrder >= NekoGui::profileManager->groupsTabOrder.size()) break;
|
||||
auto nextGid = NekoGui::profileManager->groupsTabOrder[nextOrder];
|
||||
nextGroup = NekoGui::profileManager->GetGroup(nextGid);
|
||||
if (nextGroup == nullptr || nextGroup->url.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
// calculate this group
|
||||
auto group = NekoGui::profileManager->GetGroup(NekoGui::profileManager->groupsTabOrder[_order]);
|
||||
if (group == nullptr) return;
|
||||
|
||||
// v2.2: listener is moved to GroupItem, no refresh here.
|
||||
NekoGui_sub::groupUpdater->AsyncUpdate(group->url, group->id, [=] {
|
||||
if (nextGroup != nullptr) UI_update_one_group(nextOrder);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,7 +30,3 @@ private slots:
|
||||
|
||||
void on_update_all_clicked();
|
||||
};
|
||||
|
||||
// 更新所有订阅 关闭分组窗口时 更新动作继续执行
|
||||
|
||||
void UI_update_one_group(int _order);
|
||||
|
||||
@@ -6,28 +6,30 @@
|
||||
|
||||
#include <QClipboard>
|
||||
|
||||
#define ADJUST_SIZE runOnUiThread([=] { adjustSize(); adjustPosition(mainwindow); }, this);
|
||||
|
||||
DialogEditGroup::DialogEditGroup(const std::shared_ptr<NekoGui::Group> &ent, QWidget *parent) : QDialog(parent), ui(new Ui::DialogEditGroup) {
|
||||
ui->setupUi(this);
|
||||
this->ent = ent;
|
||||
|
||||
connect(ui->type, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
|
||||
ui->cat_sub->setHidden(index == 0);
|
||||
ADJUST_SIZE
|
||||
});
|
||||
|
||||
ui->name->setText(ent->name);
|
||||
ui->archive->setChecked(ent->archive);
|
||||
ui->skip_auto_update->setChecked(ent->skip_auto_update);
|
||||
ui->url->setText(ent->url);
|
||||
ui->type->setCurrentIndex(ent->url.isEmpty() ? 0 : 1);
|
||||
ui->type->currentIndexChanged(ui->type->currentIndex());
|
||||
ui->manually_column_width->setChecked(ent->manually_column_width);
|
||||
ui->copy_links->setVisible(false);
|
||||
ui->copy_links_nkr->setVisible(false);
|
||||
ui->cat_share->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);
|
||||
ui->cat_share->setVisible(true);
|
||||
}
|
||||
} else { // new group
|
||||
ui->front_proxy->hide();
|
||||
@@ -60,6 +62,8 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr<NekoGui::Group> &ent, QWi
|
||||
QApplication::clipboard()->setText(links.join("\n"));
|
||||
MessageBoxInfo(software_name, tr("Copied"));
|
||||
});
|
||||
|
||||
ADJUST_SIZE
|
||||
}
|
||||
|
||||
DialogEditGroup::~DialogEditGroup() {
|
||||
@@ -76,6 +80,7 @@ void DialogEditGroup::accept() {
|
||||
ent->name = ui->name->text();
|
||||
ent->url = ui->url->text();
|
||||
ent->archive = ui->archive->isChecked();
|
||||
ent->skip_auto_update = ui->skip_auto_update->isChecked();
|
||||
ent->manually_column_width = ui->manually_column_width->isChecked();
|
||||
ent->front_proxy_id = CACHE.front_proxy;
|
||||
QDialog::accept();
|
||||
|
||||
@@ -7,62 +7,34 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<height>468</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit Group</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="cat_common" native="true">
|
||||
<widget class="QGroupBox" name="cat_common">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Common</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="main">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="name"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="manually_column_width">
|
||||
<property name="text">
|
||||
<string>Manually column width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="archive">
|
||||
<property name="text">
|
||||
<string>Archive</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
@@ -91,6 +63,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="manually_column_width">
|
||||
<property name="text">
|
||||
<string>Manually column width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="archive">
|
||||
<property name="text">
|
||||
<string>Archive</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
@@ -119,28 +116,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="cat_sub" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<widget class="QGroupBox" name="cat_sub">
|
||||
<property name="title">
|
||||
<string>Subscription</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QGridLayout" name="_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
@@ -151,12 +131,21 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="MyLineEdit" name="url"/>
|
||||
</item>
|
||||
</layout>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="skip_auto_update">
|
||||
<property name="text">
|
||||
<string>Skip automatic update</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cat_share">
|
||||
<property name="title">
|
||||
<string>Share</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="copy_links">
|
||||
@@ -173,6 +162,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
@@ -198,6 +188,7 @@
|
||||
<tabstop>manually_column_width</tabstop>
|
||||
<tabstop>archive</tabstop>
|
||||
<tabstop>url</tabstop>
|
||||
<tabstop>skip_auto_update</tabstop>
|
||||
<tabstop>copy_links</tabstop>
|
||||
<tabstop>copy_links_nkr</tabstop>
|
||||
</tabstops>
|
||||
|
||||
@@ -434,6 +434,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
connect(t, &QTimer::timeout, this, [&] { NekoGui_sys::logCounter.fetchAndStoreRelaxed(0); });
|
||||
t->start(1000);
|
||||
|
||||
TM_auto_update_subsctiption = new QTimer;
|
||||
TM_auto_update_subsctiption_Reset_Minute = [&](int m) {
|
||||
TM_auto_update_subsctiption->stop();
|
||||
if (m >= 30) TM_auto_update_subsctiption->start(m * 60 * 1000);
|
||||
};
|
||||
connect(TM_auto_update_subsctiption, &QTimer::timeout, this, [&] { UI_update_all_groups(true); });
|
||||
TM_auto_update_subsctiption_Reset_Minute(NekoGui::dataStore->sub_auto_update);
|
||||
|
||||
if (!NekoGui::dataStore->flag_tray) show();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user