mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 10:50:23 +08:00
update: several refactors and Import window redesign
This commit is contained in:
parent
fc71624213
commit
31f6e1389f
@ -1 +1 @@
|
||||
5460
|
||||
5461
|
||||
|
@ -66,9 +66,9 @@ namespace Qv2ray::common
|
||||
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, ua);
|
||||
}
|
||||
|
||||
QByteArray QvHttpRequestHelper::Get(const QString &url)
|
||||
QByteArray QvHttpRequestHelper::Get(const QUrl &url)
|
||||
{
|
||||
request.setUrl({ url });
|
||||
request.setUrl(url);
|
||||
setAccessManagerAttributes(accessManager);
|
||||
auto _reply = accessManager.get(request);
|
||||
//
|
||||
|
@ -33,7 +33,11 @@ namespace Qv2ray::common
|
||||
~QvHttpRequestHelper();
|
||||
// get
|
||||
void AsyncGet(const QString &url);
|
||||
QByteArray Get(const QString &url);
|
||||
QByteArray Get(const QUrl &url);
|
||||
QByteArray Get(const QString &url)
|
||||
{
|
||||
return Get(QUrl{ url });
|
||||
}
|
||||
signals:
|
||||
void OnRequestFinished(QByteArray &data);
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "ConnectionIO.hpp"
|
||||
|
||||
#include "Serialization.hpp"
|
||||
#include "common/HTTPRequestHelper.hpp"
|
||||
#include "common/QvHelpers.hpp"
|
||||
|
||||
namespace Qv2ray::core::connection
|
||||
@ -8,14 +10,7 @@ namespace Qv2ray::core::connection
|
||||
{
|
||||
CONFIGROOT ConvertConfigFromFile(const QString &sourceFilePath, bool importComplex)
|
||||
{
|
||||
QFile source(sourceFilePath);
|
||||
|
||||
if (!source.exists())
|
||||
{
|
||||
LOG(MODULE_FILEIO, "Trying to import from an non-existing file.") return CONFIGROOT();
|
||||
}
|
||||
|
||||
auto root = CONFIGROOT(JsonFromString(StringFromFile(source)));
|
||||
auto root = CONFIGROOT(JsonFromString(StringFromFile(sourceFilePath)));
|
||||
|
||||
if (!importComplex)
|
||||
{
|
||||
@ -29,5 +24,27 @@ namespace Qv2ray::core::connection
|
||||
root.remove("dns");
|
||||
return root;
|
||||
}
|
||||
QMultiHash<QString, CONFIGROOT> GetConnectionConfigFromSubscription(const QUrl &subscriptionUrl, const QString &groupName)
|
||||
{
|
||||
QMultiHash<QString, CONFIGROOT> subscriptionContent;
|
||||
QvHttpRequestHelper helper;
|
||||
const auto data = helper.Get(subscriptionUrl);
|
||||
auto subscriptionLines = SplitLines(TryDecodeSubscriptionString(data));
|
||||
for (const auto &line : subscriptionLines)
|
||||
{
|
||||
QString __alias;
|
||||
QString __errMessage;
|
||||
// Assign a group name, to pass the name check.
|
||||
QString __groupName = groupName;
|
||||
auto connectionConfigMap = ConvertConfigFromString(line.trimmed(), &__alias, &__errMessage, &__groupName);
|
||||
if (!__errMessage.isEmpty())
|
||||
LOG(MODULE_SUBSCRIPTION, "Error: " + __errMessage)
|
||||
for (const auto &val : connectionConfigMap)
|
||||
{
|
||||
subscriptionContent.insert(connectionConfigMap.key(val), val);
|
||||
}
|
||||
}
|
||||
return subscriptionContent;
|
||||
}
|
||||
} // namespace ConnectionIO
|
||||
} // namespace Qv2ray::core::connection
|
||||
|
@ -6,6 +6,7 @@ namespace Qv2ray::core::connection
|
||||
{
|
||||
// File Protocol
|
||||
CONFIGROOT ConvertConfigFromFile(const QString &sourceFilePath, bool importComplex);
|
||||
QMultiHash<QString, CONFIGROOT> GetConnectionConfigFromSubscription(const QUrl &subscriptionUrl, const QString &groupName);
|
||||
} // namespace ConnectionIO
|
||||
} // namespace Qv2ray::core::connection
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "Serialization.hpp"
|
||||
|
||||
#include "Generation.hpp"
|
||||
#include "common/QvHelpers.hpp"
|
||||
#include "components/plugins/QvPluginHost.hpp"
|
||||
#include "core/CoreUtils.hpp"
|
||||
#include "core/handler/ConfigHandler.hpp"
|
||||
@ -49,7 +48,7 @@ namespace Qv2ray::core::connection
|
||||
{
|
||||
CONFIGROOT root;
|
||||
auto outbound = GenerateOutboundEntry(val.first, OUTBOUNDSETTING(val.second), {});
|
||||
root.insert("outbounds", QJsonArray{ outbound });
|
||||
QJsonIO::SetValue(root, outbound, "outbounds", 0);
|
||||
connectionConf.insert(key, root);
|
||||
}
|
||||
}
|
||||
@ -108,14 +107,5 @@ namespace Qv2ray::core::connection
|
||||
return sharelink;
|
||||
}
|
||||
|
||||
QString DecodeSubscriptionString(const QByteArray &arr)
|
||||
{
|
||||
// String may start with: vmess:// and ss://
|
||||
// We only process vmess:// here
|
||||
// Some subscription providers may use plain vmess:// saperated by
|
||||
// lines But others may use base64 of above.
|
||||
auto result = QString::fromUtf8(arr).trimmed();
|
||||
return result.contains("://") ? result : SafeBase64Decode(result);
|
||||
}
|
||||
} // namespace Serialization
|
||||
} // namespace Qv2ray::core::connection
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "base/Qv2rayBase.hpp"
|
||||
#include "common/QvHelpers.hpp"
|
||||
|
||||
namespace Qv2ray::core::connection
|
||||
{
|
||||
@ -15,7 +16,11 @@ namespace Qv2ray::core::connection
|
||||
const inline auto QV2RAY_SSD_DEFAULT_NAME_PATTERN = QObject::tr("%1 - %2 (rate %3)");
|
||||
//
|
||||
// General
|
||||
QString DecodeSubscriptionString(const QByteArray &arr);
|
||||
inline const QString TryDecodeSubscriptionString(const QByteArray &arr)
|
||||
{
|
||||
auto result = QString::fromUtf8(arr).trimmed();
|
||||
return result.contains("://") ? result : SafeBase64Decode(result);
|
||||
}
|
||||
QMultiHash<QString, CONFIGROOT> ConvertConfigFromString(const QString &link, QString *aliasPrefix, QString *errMessage,
|
||||
QString *newGroupName = nullptr);
|
||||
const QString ConvertConfigToString(const ConnectionGroupPair &id, bool isSip002 = false);
|
||||
|
@ -66,7 +66,6 @@ namespace Qv2ray::core::connection
|
||||
CONFIGROOT Deserialize(const QString &vmessStr, QString *alias, QString *errMessage)
|
||||
{
|
||||
#define default CONFIGROOT()
|
||||
LOG(MODULE_SETTINGS, "Trying to convert from a vmess string.")
|
||||
QString vmess = vmessStr;
|
||||
|
||||
if (vmess.trimmed() != vmess)
|
||||
|
@ -66,7 +66,6 @@ namespace Qv2ray::core::handlers
|
||||
connect(kernelHandler, &KernelInstanceHandler::OnDisconnected, this, &QvConfigHandler::OnDisconnected);
|
||||
//
|
||||
tcpingHelper = new QvTCPingHelper(5, this);
|
||||
httpHelper = new QvHttpRequestHelper(this);
|
||||
connect(tcpingHelper, &QvTCPingHelper::OnLatencyTestCompleted, this, &QvConfigHandler::OnLatencyDataArrived_p);
|
||||
//
|
||||
// Save per 1 minutes.
|
||||
@ -369,7 +368,6 @@ namespace Qv2ray::core::handlers
|
||||
{
|
||||
LOG(MODULE_CORE_HANDLER, "Triggering save settings from destructor")
|
||||
delete kernelHandler;
|
||||
delete httpHelper;
|
||||
CHSaveConfigData();
|
||||
}
|
||||
|
||||
@ -465,57 +463,33 @@ namespace Qv2ray::core::handlers
|
||||
bool QvConfigHandler::UpdateSubscription(const GroupId &id)
|
||||
{
|
||||
CheckGroupExistanceEx(id, false);
|
||||
if (isHttpRequestInProgress || !groups[id].isSubscription)
|
||||
if (!groups[id].isSubscription)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
isHttpRequestInProgress = true;
|
||||
auto data = httpHelper->Get(groups[id].subscriptionOption.address);
|
||||
isHttpRequestInProgress = false;
|
||||
return CHUpdateSubscription_p(id, data);
|
||||
return CHUpdateSubscription_p(id, groups[id].subscriptionOption.address);
|
||||
}
|
||||
|
||||
bool QvConfigHandler::CHUpdateSubscription_p(const GroupId &id, const QByteArray &subscriptionData)
|
||||
bool QvConfigHandler::CHUpdateSubscription_p(const GroupId &id, const QString &url)
|
||||
{
|
||||
CheckGroupExistanceEx(id, false);
|
||||
if (!groups.contains(id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QMultiHash<QString, CONFIGROOT> allSubscriptionConnections;
|
||||
//
|
||||
//
|
||||
//
|
||||
// ====================================================================================== Begin reading subscription
|
||||
auto _newConnections = GetConnectionConfigFromSubscription(url, GetDisplayName(id));
|
||||
if (_newConnections.count() < 5)
|
||||
{
|
||||
auto subscriptionLines = SplitLines(DecodeSubscriptionString(subscriptionData));
|
||||
for (const auto &line : subscriptionLines)
|
||||
{
|
||||
QString __alias;
|
||||
QString __errMessage;
|
||||
// Assign a group name, to pass the name check.
|
||||
QString __groupName = GetDisplayName(id);
|
||||
auto connectionConfigMap = ConvertConfigFromString(line.trimmed(), &__alias, &__errMessage, &__groupName);
|
||||
if (!__errMessage.isEmpty())
|
||||
LOG(MODULE_SUBSCRIPTION, "Error: " + __errMessage)
|
||||
for (const auto &val : connectionConfigMap)
|
||||
{
|
||||
allSubscriptionConnections.insert(connectionConfigMap.key(val), val);
|
||||
}
|
||||
}
|
||||
if (allSubscriptionConnections.count() < 5)
|
||||
{
|
||||
LOG(MODULE_SUBSCRIPTION, "Find a subscription with less than 5 connections.")
|
||||
if (QvMessageBoxAsk(nullptr, tr("Update Subscription"),
|
||||
tr("%1 entrie(s) have been found from the subscription source, do you want to continue?")
|
||||
.arg(allSubscriptionConnections.count())) != QMessageBox::Yes)
|
||||
LOG(MODULE_SUBSCRIPTION, "Find a subscription with less than 5 connections.")
|
||||
if (QvMessageBoxAsk(
|
||||
nullptr, tr("Update Subscription"),
|
||||
tr("%1 entrie(s) have been found from the subscription source, do you want to continue?").arg(_newConnections.count())) !=
|
||||
QMessageBox::Yes)
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// ====================================================================================== End reading subscription
|
||||
//
|
||||
//
|
||||
//
|
||||
// ====================================================================================== Begin Connection Data Storage
|
||||
// Anyway, we try our best to preserve the connection id.
|
||||
@ -540,9 +514,9 @@ namespace Qv2ray::core::handlers
|
||||
auto originalConnectionIdList = groups[id].connections;
|
||||
groups[id].connections.clear();
|
||||
//
|
||||
for (const auto &config : allSubscriptionConnections)
|
||||
for (const auto &config : _newConnections)
|
||||
{
|
||||
const auto _alias = allSubscriptionConnections.key(config);
|
||||
const auto _alias = _newConnections.key(config);
|
||||
QString errMessage;
|
||||
|
||||
if (!errMessage.isEmpty())
|
||||
@ -562,7 +536,7 @@ namespace Qv2ray::core::handlers
|
||||
LOG(MODULE_CORE_HANDLER, "Reused connection id from name: " + _alias)
|
||||
auto _conn = nameMap.take(_alias);
|
||||
groups[id].connections << _conn;
|
||||
UpdateConnection(_conn, config);
|
||||
UpdateConnection(_conn, config, true);
|
||||
// Remove Connection Id from the list.
|
||||
originalConnectionIdList.removeAll(_conn);
|
||||
typeMap.remove(typeMap.key(_conn));
|
||||
@ -573,7 +547,7 @@ namespace Qv2ray::core::handlers
|
||||
auto _conn = typeMap.take(outboundData);
|
||||
groups[id].connections << _conn;
|
||||
// Update Connection Properties
|
||||
UpdateConnection(_conn, config);
|
||||
UpdateConnection(_conn, config, true);
|
||||
RenameConnection(_conn, _alias);
|
||||
// Remove Connection Id from the list.
|
||||
originalConnectionIdList.removeAll(_conn);
|
||||
@ -583,7 +557,7 @@ namespace Qv2ray::core::handlers
|
||||
{
|
||||
// New connection id is required since nothing matched found...
|
||||
LOG(MODULE_CORE_HANDLER, "Generated new connection id for connection: " + _alias)
|
||||
CreateConnection(config, _alias, id);
|
||||
CreateConnection(config, _alias, id, true);
|
||||
}
|
||||
// ====================================================================================== End guessing new ConnectionId
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/Qv2rayBase.hpp"
|
||||
#include "common/HTTPRequestHelper.hpp"
|
||||
#include "components/latency/QvTCPing.hpp"
|
||||
#include "core/CoreUtils.hpp"
|
||||
#include "core/connection/ConnectionIO.hpp"
|
||||
@ -152,7 +151,7 @@ namespace Qv2ray::core::handlers
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
bool CHUpdateSubscription_p(const GroupId &id, const QByteArray &subscriptionData);
|
||||
bool CHUpdateSubscription_p(const GroupId &id, const QString &url);
|
||||
|
||||
private:
|
||||
int saveTimerId;
|
||||
@ -163,8 +162,6 @@ namespace Qv2ray::core::handlers
|
||||
QHash<ConnectionId, CONFIGROOT> connectionRootCache;
|
||||
|
||||
private:
|
||||
QvHttpRequestHelper *httpHelper;
|
||||
bool isHttpRequestInProgress = false;
|
||||
QvTCPingHelper *tcpingHelper;
|
||||
KernelInstanceHandler *kernelHandler;
|
||||
};
|
||||
|
@ -257,7 +257,7 @@ GroupManager::~GroupManager()
|
||||
void GroupManager::on_addGroupButton_clicked()
|
||||
{
|
||||
auto const key = tr("New Group") + " - " + GenerateRandomString(5);
|
||||
auto id = ConnectionManager->CreateGroup(key, true);
|
||||
auto id = ConnectionManager->CreateGroup(key, false);
|
||||
//
|
||||
auto item = new QListWidgetItem(key);
|
||||
item->setData(Qt::UserRole, id.toString());
|
||||
@ -266,7 +266,7 @@ void GroupManager::on_addGroupButton_clicked()
|
||||
|
||||
void GroupManager::on_updateButton_clicked()
|
||||
{
|
||||
if (QvMessageBoxAsk(this, tr("Reload Subscription"), tr("Would you like to reload the subscription?")) == QMessageBox::Yes)
|
||||
if (QvMessageBoxAsk(this, tr("Update Subscription"), tr("Would you like to update the subscription?")) == QMessageBox::Yes)
|
||||
{
|
||||
this->setEnabled(false);
|
||||
ConnectionManager->UpdateSubscription(currentGroupId);
|
||||
|
@ -105,7 +105,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources.qrc">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/assets/icons/ui_light/add.png</normaloff>:/assets/icons/ui_light/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@ -125,7 +125,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources.qrc">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/assets/icons/ui_light/delete.png</normaloff>:/assets/icons/ui_light/delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@ -227,6 +227,9 @@
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
@ -321,26 +324,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Connection Settings</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="connectionSettingsLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Route Settings</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="routeSettingsLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -352,7 +335,7 @@
|
||||
<tabstop>updateIntervalSB</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../resources.qrc"/>
|
||||
<include location="../../../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
@ -20,12 +20,22 @@
|
||||
#include <QJsonObject>
|
||||
#include <QThread>
|
||||
|
||||
constexpr auto LINK_PAGE = 0;
|
||||
constexpr auto QRCODE_PAGE = 1;
|
||||
constexpr auto MANUAL_PAGE = 2;
|
||||
constexpr auto ADVANCED_PAGE = 3;
|
||||
|
||||
ImportConfigWindow::ImportConfigWindow(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
// nameTxt->setText(tr("My Connection Imported at: ") + QDateTime::currentDateTime().toString("MM-dd hh:mm"));
|
||||
nameTxt->setText(tr("New Connection") + QDateTime::currentDateTime().toString("MM-dd hh:mm"));
|
||||
QvMessageBusConnect(ImportConfigWindow);
|
||||
RESTORE_RUNTIME_CONFIG(screenShotHideQv2ray, hideQv2rayCB->setChecked)
|
||||
//
|
||||
for (const auto &gid : ConnectionManager->AllGroups())
|
||||
{
|
||||
groupCombo->addItem(GetDisplayName(gid), gid.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void ImportConfigWindow::UpdateColorScheme()
|
||||
@ -54,23 +64,28 @@ QMultiHash<QString, CONFIGROOT> ImportConfigWindow::SelectConnection(bool outbou
|
||||
// false and disable the checkbox
|
||||
keepImportedInboundCheckBox->setEnabled(!outboundsOnly);
|
||||
routeEditBtn->setEnabled(!outboundsOnly);
|
||||
groupCombo->setEnabled(false);
|
||||
this->exec();
|
||||
QMultiHash<QString, CONFIGROOT> conn;
|
||||
for (const auto &connEntry : connections.values())
|
||||
for (const auto &connEntry : connectionsToNewGroup.values())
|
||||
{
|
||||
conn += connEntry;
|
||||
}
|
||||
for (const auto &connEntry : connectionsToExistingGroup.values())
|
||||
{
|
||||
conn += connEntry;
|
||||
}
|
||||
return result() == Accepted ? conn : QMultiHash<QString, CONFIGROOT>{};
|
||||
}
|
||||
|
||||
int ImportConfigWindow::ImportConnection()
|
||||
int ImportConfigWindow::PerformImportConnection()
|
||||
{
|
||||
this->exec();
|
||||
int count = 0;
|
||||
for (const auto &groupName : connections.keys())
|
||||
for (const auto &groupObject : connectionsToNewGroup)
|
||||
{
|
||||
GroupId groupId = groupName.isEmpty() ? DefaultGroupId : ConnectionManager->CreateGroup(groupName, false);
|
||||
const auto groupObject = connections[groupName];
|
||||
const auto groupName = connectionsToNewGroup.key(groupObject);
|
||||
GroupId groupId = ConnectionManager->CreateGroup(groupName, false);
|
||||
for (const auto &connConf : groupObject)
|
||||
{
|
||||
auto connName = groupObject.key(connConf);
|
||||
@ -84,6 +99,21 @@ int ImportConfigWindow::ImportConnection()
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &groupObject : connectionsToExistingGroup)
|
||||
{
|
||||
const auto groupId = connectionsToExistingGroup.key(groupObject);
|
||||
for (const auto &connConf : groupObject)
|
||||
{
|
||||
auto connName = groupObject.key(connConf);
|
||||
auto [protocol, host, port] = GetConnectionInfo(connConf);
|
||||
if (connName.isEmpty())
|
||||
{
|
||||
connName = protocol + "/" + host + ":" + QSTRN(port) + "-" + GenerateRandomString(5);
|
||||
}
|
||||
ConnectionManager->CreateConnection(connConf, connName, groupId, true);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -116,7 +146,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
|
||||
if (_r == QDialog::Accepted)
|
||||
{
|
||||
auto str = DecodeQRCode(pix);
|
||||
|
||||
qrImageLabel->setPixmap(QPixmap::fromImage(pix));
|
||||
if (str.trimmed().isEmpty())
|
||||
{
|
||||
LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + QSTRN(pix.width()) + ", v=" + QSTRN(pix.height()))
|
||||
@ -124,7 +154,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
|
||||
}
|
||||
else
|
||||
{
|
||||
vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE);
|
||||
qrCodeLinkTxt->setText(str.trimmed());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,7 +165,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
||||
|
||||
switch (tabWidget->currentIndex())
|
||||
{
|
||||
case 0:
|
||||
case LINK_PAGE:
|
||||
{
|
||||
QStringList linkList = SplitLines(vmessConnectionStringTxt->toPlainText());
|
||||
//
|
||||
@ -165,11 +195,19 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
||||
linkErrors[link] = QSTRN(linkErrors.count() + 1) + ": " + errMessage;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
else if (newGroupName.isEmpty())
|
||||
{
|
||||
for (const auto &conf : config)
|
||||
{
|
||||
AddToGroup(newGroupName, config.key(conf), conf);
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(config.key(conf), conf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for (const auto &conf : config)
|
||||
{
|
||||
connectionsToNewGroup[newGroupName].insert(config.key(conf), conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,7 +227,26 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case QRCODE_PAGE:
|
||||
{
|
||||
QString errorMsg;
|
||||
const auto root = ConvertConfigFromString(qrCodeLinkTxt->text(), &aliasPrefix, &errorMsg);
|
||||
if (!errorMsg.isEmpty())
|
||||
{
|
||||
QvMessageBoxWarn(this, tr("Failed to import connection"), errorMsg);
|
||||
break;
|
||||
}
|
||||
for (const auto &conf : root)
|
||||
{
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(root.key(conf), conf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MANUAL_PAGE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case ADVANCED_PAGE:
|
||||
{
|
||||
// From File...
|
||||
bool ImportAsComplex = keepImportedInboundCheckBox->isChecked();
|
||||
@ -203,7 +260,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
||||
|
||||
aliasPrefix += "_" + QFileInfo(path).fileName();
|
||||
CONFIGROOT config = ConvertConfigFromFile(path, ImportAsComplex);
|
||||
AddToGroup("", aliasPrefix, config);
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(aliasPrefix, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -275,7 +332,7 @@ void ImportConfigWindow::on_connectionEditBtn_clicked()
|
||||
CONFIGROOT root;
|
||||
root.insert("outbounds", outboundsList);
|
||||
//
|
||||
AddToGroup("", alias, root);
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(alias, root);
|
||||
accept();
|
||||
}
|
||||
}
|
||||
@ -291,12 +348,13 @@ void ImportConfigWindow::on_subscriptionButton_clicked()
|
||||
GroupManager w(this);
|
||||
w.exec();
|
||||
auto importToComplex = !keepImportedInboundCheckBox->isEnabled();
|
||||
connections.clear();
|
||||
connectionsToNewGroup.clear();
|
||||
connectionsToExistingGroup.clear();
|
||||
|
||||
if (importToComplex)
|
||||
{
|
||||
auto [alias, conf] = w.GetSelectedConfig();
|
||||
AddToGroup("", alias, conf);
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(alias, conf);
|
||||
}
|
||||
|
||||
accept();
|
||||
@ -311,7 +369,7 @@ void ImportConfigWindow::on_routeEditBtn_clicked()
|
||||
|
||||
if (isChanged)
|
||||
{
|
||||
AddToGroup("", alias, result);
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(alias, result);
|
||||
accept();
|
||||
}
|
||||
}
|
||||
@ -331,7 +389,7 @@ void ImportConfigWindow::on_jsonEditBtn_clicked()
|
||||
|
||||
if (isChanged)
|
||||
{
|
||||
AddToGroup("", alias, CONFIGROOT(result));
|
||||
connectionsToExistingGroup[GroupId{ groupCombo->currentData().toString() }].insert(alias, CONFIGROOT(result));
|
||||
accept();
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ class ImportConfigWindow
|
||||
public:
|
||||
explicit ImportConfigWindow(QWidget *parent = nullptr);
|
||||
~ImportConfigWindow();
|
||||
int ImportConnection();
|
||||
int PerformImportConnection();
|
||||
QMultiHash<QString, CONFIGROOT> SelectConnection(bool outboundsOnly);
|
||||
|
||||
private:
|
||||
@ -43,19 +43,8 @@ class ImportConfigWindow
|
||||
|
||||
private:
|
||||
void UpdateColorScheme();
|
||||
QMap<QString, QMultiHash<QString, CONFIGROOT>> connections;
|
||||
QMap<QString, QString> linkErrors;
|
||||
void AddToGroup(const QString &groupName, const QString &alias, const CONFIGROOT &root)
|
||||
{
|
||||
if (connections.contains(groupName))
|
||||
{
|
||||
connections[groupName].insert(alias, root);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMultiHash<QString, CONFIGROOT> temp;
|
||||
temp.insert(alias, root);
|
||||
connections.insert(groupName, temp);
|
||||
}
|
||||
}
|
||||
//
|
||||
QHash<GroupId, QMultiHash<QString, CONFIGROOT>> connectionsToExistingGroup;
|
||||
QHash<QString, QMultiHash<QString, CONFIGROOT>> connectionsToNewGroup;
|
||||
};
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>522</width>
|
||||
<height>460</height>
|
||||
<width>549</width>
|
||||
<height>482</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
@ -42,15 +42,18 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Import To Group</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="groupCombo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Import Source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
@ -58,197 +61,193 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="tabWidgetPage2">
|
||||
<attribute name="title">
|
||||
<string>VMess / QRCode</string>
|
||||
<string>Link</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Connection Share Link</string>
|
||||
<string>Share Link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPlainTextEdit" name="vmessConnectionStringTxt">
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Paste share link here, one line for each.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QListWidget" name="errorsList"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Error List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Share Link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Error List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>QRCode File</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="imageFileEdit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectImageBtn">
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Screenshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox">
|
||||
<property name="suffix">
|
||||
<string> secs</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Delay</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="hideQv2rayCB">
|
||||
<property name="text">
|
||||
<string>Hide Qv2ray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="qrFromScreenBtn">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Go</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPlainTextEdit" name="vmessConnectionStringTxt">
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Paste share link here, one line for each.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QListWidget" name="errorsList"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabWidgetPage4">
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Subscriptions / Manually Input</string>
|
||||
<string>QR Code</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="subscriptionButton">
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Open Subscription Manager</string>
|
||||
<string>QRCode File</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="imageFileEdit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectImageBtn">
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Screenshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="hideQv2rayCB">
|
||||
<property name="text">
|
||||
<string>Hide Qv2ray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox">
|
||||
<property name="suffix">
|
||||
<string> secs</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Delay</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="qrFromScreenBtn">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Go</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="qrImageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Manually Input Connections</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Detected Link</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="qrCodeLinkTxt">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Input Manually</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Connection Editor</string>
|
||||
<string>Simple Editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="connectionEditBtn">
|
||||
<property name="text">
|
||||
<string>Open Connection Editor</string>
|
||||
@ -258,51 +257,27 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Route Editor</string>
|
||||
<string>Complex Editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="routeEditBtn">
|
||||
<property name="text">
|
||||
<string>Open Route Editor</string>
|
||||
<string>Open Route / Complex Connection Editor</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Json Editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QPushButton" name="jsonEditBtn">
|
||||
<property name="text">
|
||||
<string>Open JSON Editor</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Subscription Manager</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Subscription Link</string>
|
||||
<string>You can manually input connection here.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -310,17 +285,24 @@
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabWidgetPage1">
|
||||
<attribute name="title">
|
||||
<string>Existing File</string>
|
||||
<string>Advanced</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Manually Input Connections</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="fileLabel">
|
||||
<property name="text">
|
||||
<string>Path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fileLineTxt">
|
||||
@ -338,13 +320,30 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="keepImportedInboundCheckBox">
|
||||
<property name="text">
|
||||
<string>Import as Complex Config (Manually edit route rules and inbounds)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Json Editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="jsonEditBtn">
|
||||
<property name="text">
|
||||
<string>Open JSON Editor</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
@ -384,21 +383,10 @@
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>nameTxt</tabstop>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>vmessConnectionStringTxt</tabstop>
|
||||
<tabstop>errorsList</tabstop>
|
||||
<tabstop>imageFileEdit</tabstop>
|
||||
<tabstop>selectImageBtn</tabstop>
|
||||
<tabstop>doubleSpinBox</tabstop>
|
||||
<tabstop>hideQv2rayCB</tabstop>
|
||||
<tabstop>qrFromScreenBtn</tabstop>
|
||||
<tabstop>subscriptionButton</tabstop>
|
||||
<tabstop>connectionEditBtn</tabstop>
|
||||
<tabstop>routeEditBtn</tabstop>
|
||||
<tabstop>jsonEditBtn</tabstop>
|
||||
<tabstop>fileLineTxt</tabstop>
|
||||
<tabstop>selectFileBtn</tabstop>
|
||||
<tabstop>keepImportedInboundCheckBox</tabstop>
|
||||
<tabstop>beginImportBtn</tabstop>
|
||||
<tabstop>cancelImportBtn</tabstop>
|
||||
</tabstops>
|
||||
|
@ -576,7 +576,7 @@ void MainWindow::on_action_RCM_DeleteThese_triggered()
|
||||
void MainWindow::on_importConfigButton_clicked()
|
||||
{
|
||||
ImportConfigWindow w(this);
|
||||
w.ImportConnection();
|
||||
w.PerformImportConnection();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_RCM_EditAsComplex_triggered()
|
||||
|
@ -86,7 +86,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources.qrc">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/assets/icons/ui_light/locate.png</normaloff>:/assets/icons/ui_light/locate.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@ -110,7 +110,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources.qrc">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/assets/icons/ui_light/sort.png</normaloff>:/assets/icons/ui_light/sort.png</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
@ -291,7 +291,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources.qrc">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/assets/icons/ui_light/delete.png</normaloff>:/assets/icons/ui_light/delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@ -354,7 +354,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources.qrc">
|
||||
<iconset resource="../../../resources.qrc">
|
||||
<normaloff>:/assets/icons/ui_light/delete.png</normaloff>:/assets/icons/ui_light/delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@ -538,7 +538,7 @@
|
||||
<tabstop>importConfigButton</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../resources.qrc"/>
|
||||
<include location="../../../resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
Loading…
Reference in New Issue
Block a user