diff --git a/makespec/03-unix.pri b/makespec/03-unix.pri index 3102aaf6..097ff088 100644 --- a/makespec/03-unix.pri +++ b/makespec/03-unix.pri @@ -15,8 +15,10 @@ INCLUDEPATH += /usr/local/include/ message(" --> Linking against protobuf library.") LIBS += -L/usr/local/lib -lprotobuf -message(" --> Generating geosite headers for Unix") -system("$$PWD/../tools/unix-generate-geosite.sh $$PWD") +!no_generate_headers { + message(" --> Generating geosite headers for Unix") + system("$$PWD/../tools/unix-generate-geosite.sh $$PWD") +} use_grpc { no_generate_headers { diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION index 8af762b8..6b2af3f8 100644 --- a/makespec/BUILDVERSION +++ b/makespec/BUILDVERSION @@ -1 +1 @@ -3963 +3986 diff --git a/src/common/HTTPRequestHelper.cpp b/src/common/HTTPRequestHelper.cpp index 467a2a82..dbf2856d 100644 --- a/src/common/HTTPRequestHelper.cpp +++ b/src/common/HTTPRequestHelper.cpp @@ -46,6 +46,7 @@ namespace Qv2ray::common } request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); + request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, "Mozilla/5.0 (rv:71.0) Gecko/20100101 Firefox/71.0"); reply = accessManager.get(request); connect(reply, &QNetworkReply::finished, this, &QvHttpRequestHelper::onRequestFinished_p); @@ -105,6 +106,10 @@ namespace Qv2ray::common void QvHttpRequestHelper::onRequestFinished_p() { + if (reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute).toBool()) { + DEBUG(MODULE_NETWORK, "HTTP/2 was used.") + } + if (reply->error() != QNetworkReply::NoError) { QString error = QMetaEnum::fromType().key(reply->error()); LOG(MODULE_NETWORK, "Network request error string: " + error) diff --git a/src/common/QvHelpers.cpp b/src/common/QvHelpers.cpp index 05728876..7df5bd45 100644 --- a/src/common/QvHelpers.cpp +++ b/src/common/QvHelpers.cpp @@ -31,15 +31,19 @@ namespace Qv2ray::common source->close(); return str; } - - bool StringToFile(const QString *text, QFile *targetFile) + bool StringToFile(const QString &text, const QString &targetpath) { - bool override = targetFile->exists(); - targetFile->open(QFile::WriteOnly); - QTextStream stream(targetFile); - stream << *text << endl; + auto file = QFile(targetpath); + return StringToFile(text, file); + } + bool StringToFile(const QString &text, QFile &targetFile) + { + bool override = targetFile.exists(); + targetFile.open(QFile::WriteOnly); + QTextStream stream(&targetFile); + stream << text << endl; stream.flush(); - targetFile->close(); + targetFile.close(); return override; } diff --git a/src/common/QvHelpers.hpp b/src/common/QvHelpers.hpp index c89cce37..6d8d818b 100644 --- a/src/common/QvHelpers.hpp +++ b/src/common/QvHelpers.hpp @@ -23,7 +23,8 @@ namespace Qv2ray::common // QString StringFromFile(const QString &filePath); QString StringFromFile(QFile *source); - bool StringToFile(const QString *text, QFile *target); + bool StringToFile(const QString &text, QFile &target); + bool StringToFile(const QString &text, const QString &targetpath); // QJsonObject JsonFromString(QString string); QString JsonToString(QJsonObject json, QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Indented); diff --git a/src/core/CoreUtils.cpp b/src/core/CoreUtils.cpp index 22a7f3c3..ba9cd913 100644 --- a/src/core/CoreUtils.cpp +++ b/src/core/CoreUtils.cpp @@ -1,8 +1,9 @@ #include "CoreUtils.hpp" +#include "common/QvHelpers.hpp" namespace Qv2ray::core { - bool IsComplexConfig(CONFIGROOT root) + bool IsComplexConfig(const CONFIGROOT &root) { bool cRouting = root.contains("routing"); bool cRule = cRouting && root["routing"].toObject().contains("rules"); @@ -15,5 +16,34 @@ namespace Qv2ray::core bool cOutboundCount = cOutbounds && root["outbounds"].toArray().count() > 1; return cRules || cInboundCount || cOutboundCount; } + + bool GetOutboundData(const OUTBOUND &out, QString *host, int *port, QString *protocol) + { + // Set initial values. + *host = QObject::tr("N/A"); + *port = 0; + *protocol = out["protocol"].toString(QObject::tr("N/A")).toLower(); + + if (*protocol == "vmess") { + auto Server = StructFromJsonString(JsonToString(out["settings"].toObject()["vnext"].toArray().first().toObject())); + *host = Server.address; + *port = Server.port; + return true; + } else if (*protocol == "shadowsocks") { + auto x = JsonToString(out["settings"].toObject()["servers"].toArray().first().toObject()); + auto Server = StructFromJsonString(x); + *host = Server.address; + *port = Server.port; + return true; + } else if (*protocol == "socks") { + auto x = JsonToString(out["settings"].toObject()["servers"].toArray().first().toObject()); + auto Server = StructFromJsonString(x); + *host = Server.address; + *port = Server.port; + return true; + } else { + return false; + } + } } diff --git a/src/core/CoreUtils.hpp b/src/core/CoreUtils.hpp index d0284b23..06e59652 100644 --- a/src/core/CoreUtils.hpp +++ b/src/core/CoreUtils.hpp @@ -24,7 +24,8 @@ namespace Qv2ray::core return in.QV2RAY_RULE_TAG; } - bool IsComplexConfig(CONFIGROOT root); + bool GetOutboundData(const OUTBOUND &out, QString *host, int *port, QString *protocol); + bool IsComplexConfig(const CONFIGROOT &root); } using namespace Qv2ray::core; diff --git a/src/core/config/ConfigBackend.cpp b/src/core/config/ConfigBackend.cpp index 18cf0f35..b3406fd0 100644 --- a/src/core/config/ConfigBackend.cpp +++ b/src/core/config/ConfigBackend.cpp @@ -6,9 +6,8 @@ namespace Qv2ray::core::config void SaveGlobalConfig(const Qv2rayConfig &conf) { GlobalConfig = conf; - QFile config(QV2RAY_CONFIG_FILE); QString str = StructToJsonString(conf); - StringToFile(&str, &config); + StringToFile(str, QV2RAY_CONFIG_FILE); } void SetConfigDirPath(const QString &path) diff --git a/src/core/connection/ConnectionIO.cpp b/src/core/connection/ConnectionIO.cpp index 6c14f0a3..d153d653 100644 --- a/src/core/connection/ConnectionIO.cpp +++ b/src/core/connection/ConnectionIO.cpp @@ -5,12 +5,6 @@ namespace Qv2ray::core::connection { namespace ConnectionIO { - - //CONFIGROOT GetConnectionRoot(const SubscriptionId &subscription, const ConnectionId &id) - //{ - // return ReadConnectionInternal(QV2RAY_SUBSCRIPTION_DIR + subscription.toString() + "/" + id.toString() + QV2RAY_CONFIG_FILE_EXTENSION); - //} - //// //// Save Connection to a place, with checking if there's existing file. //// If so, append "_N" to the name. diff --git a/src/core/handler/ConnectionHandler.cpp b/src/core/handler/ConnectionHandler.cpp index 0436fd35..234520a3 100644 --- a/src/core/handler/ConnectionHandler.cpp +++ b/src/core/handler/ConnectionHandler.cpp @@ -284,7 +284,6 @@ namespace Qv2ray::core::handlers path.prepend(groups[group].isSubscription ? QV2RAY_SUBSCRIPTION_DIR : QV2RAY_CONNECTIONS_DIR); return CONFIGROOT(JsonFromString(StringFromFile(path))); } - // const tuple QvConnectionHandler::GetConnectionInfo(const ConnectionId &id) const { @@ -296,7 +295,7 @@ namespace Qv2ray::core::handlers for (auto item : root["outbounds"].toArray()) { OUTBOUND outBoundRoot = OUTBOUND(item.toObject()); QString outboundType = ""; - validOutboundFound = CHGetOutboundData_p(outBoundRoot, &host, &port); + validOutboundFound = GetOutboundData(outBoundRoot, &host, &port, &outboundType); if (validOutboundFound) { return make_tuple(host, port); @@ -308,34 +307,7 @@ namespace Qv2ray::core::handlers return make_tuple(QObject::tr("N/A"), 0); } - bool QvConnectionHandler::CHGetOutboundData_p(const OUTBOUND &out, QString *host, int *port) const - { - // Set initial values. - *host = QObject::tr("N/A"); - *port = 0; - auto protocol = out["protocol"].toString(QObject::tr("N/A")).toLower(); - if (protocol == "vmess") { - auto Server = StructFromJsonString(JsonToString(out["settings"].toObject()["vnext"].toArray().first().toObject())); - *host = Server.address; - *port = Server.port; - return true; - } else if (protocol == "shadowsocks") { - auto x = JsonToString(out["settings"].toObject()["servers"].toArray().first().toObject()); - auto Server = StructFromJsonString(x); - *host = Server.address; - *port = Server.port; - return true; - } else if (protocol == "socks") { - auto x = JsonToString(out["settings"].toObject()["servers"].toArray().first().toObject()); - auto Server = StructFromJsonString(x); - *host = Server.address; - *port = Server.port; - return true; - } else { - return false; - } - } void QvConnectionHandler::OnLatencyDataArrived(const QvTCPingResultObject &result) { @@ -346,4 +318,13 @@ namespace Qv2ray::core::handlers LOG(MODULE_CORE_HANDLER, "Received a latecy result with non-exist connection id.") } } + + bool QvConnectionHandler::UpdateConnection(const ConnectionId &id, const CONFIGROOT &root) + { + auto groupId = connections[id].groupId; + auto path = (groups[groupId].isSubscription ? QV2RAY_SUBSCRIPTION_DIR : QV2RAY_CONNECTIONS_DIR) + + groupId.toString() + "/" + id.toString() + QV2RAY_CONFIG_FILE_EXTENSION; + auto content = JsonToString(root); + return StringToFile(content, path); + } } diff --git a/src/core/handler/ConnectionHandler.hpp b/src/core/handler/ConnectionHandler.hpp index 10456a30..2ee80d61 100644 --- a/src/core/handler/ConnectionHandler.hpp +++ b/src/core/handler/ConnectionHandler.hpp @@ -5,6 +5,7 @@ #include "core/tcping/QvTCPing.hpp" #include "core/CoreSafeTypes.hpp" #include "core/connection/ConnectionIO.hpp" +#include "core/CoreUtils.hpp" namespace Qv2ray::core::handlers { @@ -37,7 +38,7 @@ namespace Qv2ray::core::handlers double GetConnectionLatency(const ConnectionId &id) const; const ConnectionId &CreateConnection(const QString &displayName, const GroupId &groupId, const CONFIGROOT &root); const optional DeleteConnection(const ConnectionId &id); - const optional UpdateConnection(const ConnectionId &id, const CONFIGROOT &root); + bool UpdateConnection(const ConnectionId &id, const CONFIGROOT &root); const optional RenameConnection(const ConnectionId &id, const QString &newName); const ConnectionId DuplicateConnection(const ConnectionId &id); const optional MoveConnectionGroup(const ConnectionId &id, const GroupId &newGroupId); @@ -101,7 +102,6 @@ namespace Qv2ray::core::handlers private: void CHSaveConnectionData_p(); // - bool CHGetOutboundData_p(const OUTBOUND &out, QString *host, int *port) const; optional CHStartConnection_p(const ConnectionId &id, const CONFIGROOT &root); void CHStopConnection_p(); bool CHSaveConnectionConfig_p(CONFIGROOT obj, const ConnectionId &id, bool override); @@ -112,7 +112,7 @@ namespace Qv2ray::core::handlers int pingConnectionTimerId; QHash groups; QHash connections; - QHash connectionRootCache; + //QHash connectionRootCache; private: QvTCPingHelper *tcpingHelper; diff --git a/src/core/kernel/KernelInteractions.cpp b/src/core/kernel/KernelInteractions.cpp index 5725d33b..ee08ce02 100644 --- a/src/core/kernel/KernelInteractions.cpp +++ b/src/core/kernel/KernelInteractions.cpp @@ -147,8 +147,7 @@ namespace Qv2ray::core::kernel // Write the final configuration to the disk. QString json = JsonToString(root); - QFile configFile(QV2RAY_GENERATED_FILE_PATH); - StringToFile(&json, &configFile); + StringToFile(json, QV2RAY_GENERATED_FILE_PATH); // auto filePath = QV2RAY_GENERATED_FILE_PATH; diff --git a/src/ui/editors/w_RoutesEditor.cpp b/src/ui/editors/w_RoutesEditor.cpp index 7d028706..a68b6586 100644 --- a/src/ui/editors/w_RoutesEditor.cpp +++ b/src/ui/editors/w_RoutesEditor.cpp @@ -157,8 +157,7 @@ void RouteEditor::onNodeClicked(Node &n) alias = GetFirstNodeData(n, QvOutboundNodeModel, OutboundNodeData)->GetOutbound(); QJsonObject _root = outbounds[alias].raw(); throw new runtime_error("Not implemented"); - //auto result = GetOutboundData(OUTBOUND(_root), &host, &port, &protocol); - //Q_UNUSED(result) + GetOutboundData(OUTBOUND(_root), &host, &port, &protocol); } else { alias = GetFirstNodeData(n, QvInboundNodeModel, InboundNodeData)->GetInbound(); QJsonObject _root = inbounds[alias].raw(); diff --git a/src/ui/w_ImportConfig.cpp b/src/ui/w_ImportConfig.cpp index c3551b2e..e9097a85 100644 --- a/src/ui/w_ImportConfig.cpp +++ b/src/ui/w_ImportConfig.cpp @@ -232,7 +232,7 @@ void ImportConfigWindow::on_editFileBtn_clicked() if (editor.result() == QDialog::Accepted) { auto str = JsonToString(json); - bool result = StringToFile(&str, &file); + bool result = StringToFile(str, file); if (!result) { QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Failed to save file, please check if you have proper permissions")); diff --git a/src/ui/w_MainWindow.cpp b/src/ui/w_MainWindow.cpp index 435601f8..0542c86a 100644 --- a/src/ui/w_MainWindow.cpp +++ b/src/ui/w_MainWindow.cpp @@ -74,12 +74,6 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr { setupUi(this); MainWindow::mwInstance = this; - connect(ConnectionManager, &QvConnectionHandler::OnCrashed, [&] { - this->show(); - QvMessageBoxWarn(this, tr("V2ray vcore terminated."), - tr("V2ray vcore terminated unexpectedly.") + NEWLINE + NEWLINE + - tr("To solve the problem, read the V2ray log in the log text browser.")); - }); QvMessageBusConnect(MainWindow); // infoWidget = new ConnectionInfoWidget(this); @@ -98,11 +92,20 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr updownImageBox_2->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)"); // // + connect(ConnectionManager, &QvConnectionHandler::OnCrashed, [&] { + this->show(); + QvMessageBoxWarn(this, tr("V2ray vcore terminated."), + tr("V2ray vcore terminated unexpectedly.") + NEWLINE + NEWLINE + + tr("To solve the problem, read the V2ray log in the log text browser.")); + }); connect(ConnectionManager, &QvConnectionHandler::OnConnected, this, &MainWindow::OnConnected); connect(ConnectionManager, &QvConnectionHandler::OnDisConnected, this, &MainWindow::OnDisConnected); connect(ConnectionManager, &QvConnectionHandler::OnStatsAvailable, this, &MainWindow::onConnectionStatsArrived); connect(ConnectionManager, &QvConnectionHandler::OnVCoreLogAvailable, this, &MainWindow::onVCoreLogArrived); // + connect(infoWidget, &ConnectionInfoWidget::OnEditRequested, this, &MainWindow::OnEditRequested); + connect(infoWidget, &ConnectionInfoWidget::OnJsonEditRequested, this, &MainWindow::OnJsonEditRequested); + // // Setup System tray icons and menus hTray.setToolTip(TRAY_TOOLTIP_PREFIX); // Basic actions @@ -201,10 +204,7 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr if (!GlobalConfig.autoStartId.isEmpty()) { auto id = ConnectionId(GlobalConfig.autoStartId); - ConnectionManager->StartConnection(id); - needShowWindow = !ConnectionManager->IsConnected(id); - } else { - needShowWindow = true; + needShowWindow = ConnectionManager->StartConnection(id).has_value(); } if (needShowWindow) { @@ -212,6 +212,9 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)//, vinstance(), hTr } //// If we are not connected to anything, show the MainWindow. + if (needShowWindow) { + } + #ifndef DISABLE_AUTO_UPDATE requestHelper = new QvHttpRequestHelper(); connect(requestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate); @@ -298,24 +301,6 @@ MainWindow::~MainWindow() hTray.hide(); } -//void MainWindow::on_stopButton_clicked() -//{ -// //hTray.setToolTip(TRAY_TOOLTIP_PREFIX); -// //statusLabel->setText(tr("Disconnected")); -// action_Tray_Start->setEnabled(true); -// action_Tray_Stop->setEnabled(false); -// action_Tray_Reconnect->setEnabled(false); -// // Set to false as the system proxy has been cleared in the StopConnection function. -// tray_SystemProxyMenu->setEnabled(false); -// //startButton->setEnabled(true); -// //stopButton->setEnabled(false); -// //// -// //netspeedLabel->setText("0.00 B/s\r\n0.00 B/s"); -// //dataamountLabel->setText("0.00 B\r\n0.00 B"); -// //LOG(UI, "Stopped successfully.") -// //this->hTray.showMessage("Qv2ray", tr("Disconnected from: ") + CurrentConnectionIdentifier.IdentifierString()); -//} - void MainWindow::closeEvent(QCloseEvent *event) { this->hide(); @@ -579,50 +564,6 @@ void MainWindow::on_importConfigButton_clicked() } void MainWindow::on_editConfigButton_clicked() { - //// Check if we have a connection selected... - //if (!IsSelectionConnectable) { - // QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a Config")); - // return; - //} - // - //auto firstSelected = connectionListWidget->selectedItems().first(); - //auto _identifier = ItemConnectionIdentifier(firstSelected); - //SUBSCRIPTION_CONFIG_MODIFY_ASK(firstSelected) - //// - //auto outBoundRoot = connections[_identifier].config; - //CONFIGROOT root; - //bool isChanged = false; - // - //if (IsComplexConfig(outBoundRoot)) { - // LOG(UI, "INFO: Opening route editor.") - // RouteEditor routeWindow(outBoundRoot, this); - // root = routeWindow.OpenEditor(); - // isChanged = routeWindow.result() == QDialog::Accepted; - //} else { - // LOG(UI, "INFO: Opening single connection edit window.") - // OutboundEditor w(OUTBOUND(outBoundRoot["outbounds"].toArray().first().toObject()), this); - // auto outboundEntry = w.OpenEditor(); - // isChanged = w.result() == QDialog::Accepted; - // QJsonArray outboundsList; - // outboundsList.push_back(outboundEntry); - // root.insert("outbounds", outboundsList); - //} - // - //QString alias = _identifier.connectionName; - // - //if (isChanged) { - // if (CheckConfigType(firstSelected, SUBSCRIPTION)) { - // auto name = connections[_identifier].connectionName; - // // Assume name will not change. - // SaveSubscriptionConfig(root, connections[_identifier].subscriptionName, &name); - // } else { - // connections[_identifier].config = root; - // // true indicates the alias will NOT change - // SaveConnectionConfig(root, &alias, true); - // } - // - // OnConfigListChanged(alias == CurrentConnectionIdentifier.connectionName); - //} } void MainWindow::on_action_RCM_ConvToComplex_triggered() @@ -658,26 +599,6 @@ void MainWindow::on_action_RCM_ConvToComplex_triggered() void MainWindow::on_action_RCM_EditJson_triggered() { - //// Check if we have a connection selected... - //if (!IsSelectionConnectable) { - // QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a Config")); - // return; - //} - // - //auto selectedFirst = connectionListWidget->currentItem(); - //auto _identifier = ItemConnectionIdentifier(selectedFirst); - //SUBSCRIPTION_CONFIG_MODIFY_DENY(selectedFirst) - //JsonEditor w(connections[_identifier].config, this); - //auto root = CONFIGROOT(w.OpenEditor()); - //bool isChanged = w.result() == QDialog::Accepted; - //QString alias = _identifier.connectionName; - // - //if (isChanged) { - // connections[_identifier].config = root; - // // Alias here will not change. - // SaveConnectionConfig(root, &alias, true); - // ShowAndSetConnection(CurrentConnectionIdentifier, false, false); - //} } void MainWindow::on_action_RCM_ShareQR_triggered() @@ -871,3 +792,50 @@ void MainWindow::onVCoreLogArrived(const ConnectionId &id, const QString &log) if (val >= max * 0.8 || val >= max - 20) bar->setValue(max); } + + +void MainWindow::OnEditRequested(const ConnectionId &id) +{ + auto outBoundRoot = ConnectionManager->GetConnectionRoot(id); + CONFIGROOT root; + bool isChanged = false; + + if (IsComplexConfig(outBoundRoot)) { + LOG(MODULE_UI, "INFO: Opening route editor.") + RouteEditor routeWindow(outBoundRoot, this); + root = routeWindow.OpenEditor(); + isChanged = routeWindow.result() == QDialog::Accepted; + } else { + LOG(MODULE_UI, "INFO: Opening single connection edit window.") + auto out = OUTBOUND(outBoundRoot["outbounds"].toArray().first().toObject()); + OutboundEditor w(out, this); + auto outboundEntry = w.OpenEditor(); + isChanged = w.result() == QDialog::Accepted; + QJsonArray outboundsList; + outboundsList.push_back(outboundEntry); + root.insert("outbounds", outboundsList); + } + + if (isChanged) { + //if (CheckConfigType(firstSelected, SUBSCRIPTION)) { + // auto name = connections[_identifier].connectionName; + // // Assume name will not change. + // SaveSubscriptionConfig(root, connections[_identifier].subscriptionName, &name); + //} else { + // connections[_identifier].config = root; + // // true indicates the alias will NOT change + // SaveConnectionConfig(root, &alias, true); + //} + ConnectionManager->UpdateConnection(id, root); + //OnConfigListChanged(alias == CurrentConnectionIdentifier.connectionName); + } +} +void MainWindow::OnJsonEditRequested(const ConnectionId &id) +{ + JsonEditor w(ConnectionManager->GetConnectionRoot(id), this); + auto root = CONFIGROOT(w.OpenEditor()); + + if (w.result() == QDialog::Accepted) { + ConnectionManager->UpdateConnection(id, root); + } +} diff --git a/src/ui/w_MainWindow.hpp b/src/ui/w_MainWindow.hpp index 650db1cf..2f417718 100644 --- a/src/ui/w_MainWindow.hpp +++ b/src/ui/w_MainWindow.hpp @@ -60,6 +60,8 @@ class MainWindow : public QMainWindow, Ui::MainWindow // void OnConnected(const ConnectionId &id); void OnDisConnected(const ConnectionId &id); + void OnEditRequested(const ConnectionId &id); + void OnJsonEditRequested(const ConnectionId &id); void onConnectionWidgetFocusRequested(const ConnectionItemWidget *widget); //void onConnectionConnected(const ConnectionId &id); diff --git a/src/ui/w_PreferencesWindow.cpp b/src/ui/w_PreferencesWindow.cpp index c9b27315..88f1ddff 100644 --- a/src/ui/w_PreferencesWindow.cpp +++ b/src/ui/w_PreferencesWindow.cpp @@ -892,8 +892,7 @@ void PreferencesWindow::on_pacGoBtn_clicked() QDir(QV2RAY_RULES_DIR).mkpath(QV2RAY_RULES_DIR); } - QFile privateGFWListFile(QV2RAY_RULES_GFWLIST_PATH); - StringToFile(&fileContent, &privateGFWListFile); + StringToFile(fileContent, QV2RAY_RULES_GFWLIST_PATH); } void PreferencesWindow::on_pacPortSB_valueChanged(int arg1) diff --git a/src/ui/w_SubscriptionManager.cpp b/src/ui/w_SubscriptionManager.cpp index db46a766..a30ccfd7 100644 --- a/src/ui/w_SubscriptionManager.cpp +++ b/src/ui/w_SubscriptionManager.cpp @@ -120,7 +120,7 @@ void SubscribeEditor::on_updateButton_clicked() subscriptions[currentSubName].address = newAddress; } - SaveConfig(); + //SaveConfig(); if (QvMessageBoxAsk(this, tr("Update Subscription"), tr("Would you like to reload this subscription from the Url?")) == QMessageBox::Yes) { StartUpdateSubscription(currentSubName); @@ -129,10 +129,9 @@ void SubscribeEditor::on_updateButton_clicked() void SubscribeEditor::StartUpdateSubscription(const QString &subscriptionName) { - //this->setEnabled(false); - //auto data = helper.syncget(subscriptions[subscriptionName].address, withProxyCB->isChecked()); - //auto content = DecodeSubscriptionString(data).trimmed(); - // + this->setEnabled(false); + auto data = helper.syncget(subscriptions[subscriptionName].address, withProxyCB->isChecked()); + auto content = DecodeSubscriptionString(data).trimmed(); //if (!content.isEmpty()) { // connectionsList->clear(); // auto vmessList = SplitLines(content); @@ -160,7 +159,7 @@ void SubscribeEditor::StartUpdateSubscription(const QString &subscriptionName) // QvMessageBoxWarn(this, tr("Updating subscriptions"), tr("Failed to process the result from the upstream, please check your Url.")); //} // - //this->setEnabled(true); + this->setEnabled(true); } void SubscribeEditor::on_removeSubsButton_clicked() @@ -213,16 +212,16 @@ void SubscribeEditor::on_subscriptionList_currentRowChanged(int currentRow) void SubscribeEditor::SaveConfig() { - QMap newConf; - - for (auto _ : subscriptions.toStdMap()) { - if (!_.second.address.isEmpty()) { - newConf[_.first] = _.second; - } - } - - GlobalConfig.subscriptions = newConf; - SaveGlobalConfig(GlobalConfig); + //QMap newConf; + // + //for (auto _ : subscriptions.toStdMap()) { + // if (!_.second.address.isEmpty()) { + // newConf[_.first] = _.second; + // } + //} + // + //GlobalConfig.subscriptions = newConf; + //SaveGlobalConfig(GlobalConfig); } void SubscribeEditor::on_buttonBox_accepted() diff --git a/src/ui/widgets/ConnectionInfoWidget.cpp b/src/ui/widgets/ConnectionInfoWidget.cpp index 7afdd5ea..5e3143b7 100644 --- a/src/ui/widgets/ConnectionInfoWidget.cpp +++ b/src/ui/widgets/ConnectionInfoWidget.cpp @@ -24,19 +24,19 @@ void ConnectionInfoWidget::ShowDetails(const tuple &_iden { groupId = get<0>(_identifier); connectionId = get<1>(_identifier); + bool isConnection = connectionId != NullConnectionId; + editJsonBtn->setEnabled(isConnection); + connectBtn->setEnabled(isConnection); + duplicateBtn->setEnabled(isConnection); + editBtn->setEnabled(isConnection); - if (connectionId != NullConnectionId) { - //connNameLabel->setText(ConnectionManager->GetDisplayName(connectionId)); + if (isConnection) { groupLabel->setText(ConnectionManager->GetDisplayName(groupId, 175)); protocolLabel->setText(ConnectionManager->GetConnectionProtocolString(connectionId)); auto [host, port] = ConnectionManager->GetConnectionInfo(connectionId); addressLabel->setText(host); portLabel->setNum(port); // - editJsonBtn->setEnabled(true); - connectBtn->setEnabled(true); - duplicateBtn->setEnabled(true); - // auto shareLink = ConvertConfigToString(connectionId); shareLinkTxt->setText(shareLink); shareLinkTxt->setCursorPosition(0); @@ -55,10 +55,6 @@ void ConnectionInfoWidget::ShowDetails(const tuple &_iden addressLabel->setText(tr("N/A")); portLabel->setText(tr("N/A")); // - editJsonBtn->setEnabled(false); - connectBtn->setEnabled(false); - duplicateBtn->setEnabled(false); - // shareLinkTxt->clear(); qrLabel->clear(); } @@ -76,27 +72,15 @@ void ConnectionInfoWidget::on_connectBtn_clicked() ConnectionManager->StartConnection(connectionId); } } -//// Share QR -//if (!IsSelectionConnectable) { -// return; -//} -// -//auto _identifier = ItemConnectionIdentifier(connectionListWidget->currentItem()); -//auto root = connections[_identifier].config; -//auto type = get<2>(GetConnectionInfo(root)); -// -//if (!IsComplexConfig(root) && (type == "vmess" || type == "shadowsocks")) { -// ConfigExporter v(root, _identifier, this); -// v.OpenExport(); -//} else { -// QvMessageBoxWarn(this, tr("Share Connection"), tr("There're no support of sharing configs other than vmess and shadowsocks")); -//} + void ConnectionInfoWidget::on_editBtn_clicked() { + emit OnEditRequested(connectionId); } void ConnectionInfoWidget::on_editJsonBtn_clicked() { + emit OnJsonEditRequested(connectionId); } void ConnectionInfoWidget::on_deleteBtn_clicked() diff --git a/src/ui/widgets/ConnectionInfoWidget.hpp b/src/ui/widgets/ConnectionInfoWidget.hpp index 00b5f5c6..968b88e1 100644 --- a/src/ui/widgets/ConnectionInfoWidget.hpp +++ b/src/ui/widgets/ConnectionInfoWidget.hpp @@ -13,6 +13,10 @@ class ConnectionInfoWidget : public QWidget, private Ui::ConnectionInfoWidget void ShowDetails(const tuple &_identifier); ~ConnectionInfoWidget(); + signals: + void OnEditRequested(const ConnectionId &id); + void OnJsonEditRequested(const ConnectionId &id); + private slots: void on_connectBtn_clicked(); void on_editBtn_clicked(); @@ -25,9 +29,7 @@ class ConnectionInfoWidget : public QWidget, private Ui::ConnectionInfoWidget private slots: void OnConnected(const ConnectionId &id); void OnDisConnected(const ConnectionId &id); - void on_duplicateBtn_clicked(); - void on_latencyBtn_clicked(); private: