[add] Added keyboard operations and log prettify

Former-commit-id: 3a8144f65d
This commit is contained in:
Leroy.H.Y 2019-11-28 16:09:54 +08:00
parent c6f70c1a60
commit e4f7f99ae1
14 changed files with 362 additions and 34 deletions

View File

@ -1 +1 @@
960
977

View File

@ -10,7 +10,7 @@ TARGET = qv2ray
TEMPLATE = app
# Don't merge those configs with below.
CONFIG += enable_decoder_qr_code enable_encoder_qr_code qt c++11 openssl-linked
CONFIG += enable_decoder_qr_code enable_encoder_qr_code qt c++11 openssl-linked
include(3rdparty/qzxing_noTests/QZXing-components.pri)
# Main config
@ -32,6 +32,7 @@ SOURCES += \
src/components/QvCoreInteractions.cpp \
src/components/QvGFWPACConverter.cpp \
src/components/QvHTTPRequestHelper.cpp \
src/components/QvLogHighlighter.cpp \
src/QvCoreConfigOperations.cpp \
src/QvConfigUpgrade.cpp \
src/QvCoreConfigOperations_Convertion.cpp \
@ -71,6 +72,7 @@ HEADERS += \
src/components/QvComponentsHandler.hpp \
src/components/QvCoreInteractions.hpp \
src/components/QvHTTPRequestHelper.hpp \
src/components/QvLogHighlighter.hpp \
src/components/QvNetSpeedPlugin.hpp \
src/components/QvPACHandler.hpp \
src/components/QvSystemProxyConfigurator.hpp \

View File

@ -0,0 +1,120 @@
#include "QvLogHighlighter.hpp"
#define PORT_R "([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-5]{2}[0-3][0-5])*"
#define TO_EOL "(([\\s\\S]*)|([\\d\\D]*)|([\\w\\W]*))$"
namespace Qv2ray
{
namespace Components
{
Highlighter::Highlighter(QTextDocument *parent)
: QSyntaxHighlighter(parent)
{
HighlightingRule rule;
keywordFormat.setForeground(Qt::darkMagenta);
keywordFormat.setFontWeight(QFont::Bold);
const QString keywordPatterns[] = {
"tcp", "udp"
};
for (const QString &pattern : keywordPatterns) {
rule.pattern = QRegularExpression(pattern);
rule.format = keywordFormat;
highlightingRules.append(rule);
}
dateFormat.setFontWeight(QFont::Bold);
dateFormat.setForeground(Qt::cyan);
rule.pattern = QRegularExpression("\\d\\d\\d\\d/\\d\\d/\\d\\d");
rule.format = dateFormat;
highlightingRules.append(rule);
//
timeFormat.setFontWeight(QFont::Bold);
timeFormat.setForeground(Qt::cyan);
rule.pattern = QRegularExpression("\\d\\d:\\d\\d:\\d\\d");
rule.format = timeFormat;
highlightingRules.append(rule);
//
debugFormat.setForeground(Qt::darkGray);
rule.pattern = QRegularExpression("\\[[Dd]ebug\\]" TO_EOL);
rule.format = debugFormat;
highlightingRules.append(rule);
//
infoFormat.setForeground(Qt::darkCyan);
rule.pattern = QRegularExpression("\\[[Ii]nfo\\]" TO_EOL);
rule.format = infoFormat;
highlightingRules.append(rule);
//
//
{
// IP IPv6 Host
ipPortFormat.setFontWeight(QFont::Bold);
ipPortFormat.setForeground(Qt::green);
rule.pattern = QRegularExpression("(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\:" PORT_R);
rule.pattern.setPatternOptions(QRegularExpression::PatternOption::ExtendedPatternSyntaxOption);
rule.format = ipPortFormat;
highlightingRules.append(rule);
//
ip6PortFormat.setFontWeight(QFont::Bold);
ip6PortFormat.setForeground(Qt::green);
rule.pattern = QRegularExpression("\\[\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*\\]:" PORT_R);
rule.pattern.setPatternOptions(QRegularExpression::PatternOption::ExtendedPatternSyntaxOption);
rule.format = ip6PortFormat;
highlightingRules.append(rule);
//
hostFormat.setFontWeight(QFont::Bold);
hostFormat.setForeground(Qt::yellow);
rule.pattern = QRegularExpression("([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}(/|):" PORT_R);
rule.pattern.setPatternOptions(QRegularExpression::PatternOption::ExtendedPatternSyntaxOption);
rule.format = hostFormat;
highlightingRules.append(rule);
}
//
//
acceptedFormat.setForeground(Qt::darkGreen);
rule.pattern = QRegularExpression("\\saccepted\\s");
rule.format = acceptedFormat;
highlightingRules.append(rule);
//
rejectedFormat.setFontWeight(QFont::Bold);
rejectedFormat.setForeground(Qt::red);
rule.pattern = QRegularExpression("\\srejected\\s" TO_EOL);
rule.format = rejectedFormat;
highlightingRules.append(rule);
//
x.setFontWeight(QFont::Bold);
x.setForeground(Qt::darkGreen);
rule.pattern = QRegularExpression(" v2ray.com(/(\\w*))*: ");
rule.format = x;
highlightingRules.append(rule);
//
warningFormat.setFontWeight(QFont::Bold);
warningFormat.setForeground(QColor::fromRgb(230, 180, 0));
rule.pattern = QRegularExpression("\\[[Ww]arning\\]" TO_EOL);
rule.format = warningFormat;
highlightingRules.append(rule);
//
failedFormat.setFontWeight(QFont::Bold);
failedFormat.setForeground(Qt::red);
rule.pattern = QRegularExpression("failed");
rule.format = failedFormat;
highlightingRules.append(rule);
//
}
void Highlighter::highlightBlock(const QString &text)
{
for (const HighlightingRule &rule : qAsConst(highlightingRules)) {
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
while (matchIterator.hasNext()) {
QRegularExpressionMatch match = matchIterator.next();
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
}
}
setCurrentBlockState(0);
}
}
}

View File

@ -0,0 +1,102 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef HIGHLIGHTER_H
#define HIGHLIGHTER_H
#include <QSyntaxHighlighter>
#include <QTextCharFormat>
#include <QRegularExpression>
#include <QTextDocument>
#include "QvUtils.hpp"
namespace Qv2ray
{
namespace Components
{
class Highlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
Highlighter(QTextDocument *parent = nullptr);
protected:
void highlightBlock(const QString &text) override;
private:
struct HighlightingRule {
QRegularExpression pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;
QTextCharFormat keywordFormat;
QTextCharFormat dateFormat;
QTextCharFormat acceptedFormat;
QTextCharFormat rejectedFormat;
QTextCharFormat failedFormat;
QTextCharFormat warningFormat;
QTextCharFormat infoFormat;
QTextCharFormat debugFormat;
QTextCharFormat timeFormat;
QTextCharFormat ipPortFormat;
QTextCharFormat ip6PortFormat;
QTextCharFormat hostFormat;
QTextCharFormat x;
};
}
}
using namespace Qv2ray::Components;
#endif // HIGHLIGHTER_H

View File

@ -161,6 +161,7 @@ int main(int argc, char *argv[])
"Copyright (c) 2011 SCHUTZ Sacha (@dridk): QJsonModel (MIT)" NEWLINE
"Copyright (c) 2019 Nikolaos Ftylitakis (@ftylitak): QZXing (Apache2)" NEWLINE
"Copyright (c) 2016 Singein (@Singein): ScreenShot (MIT)" NEWLINE
"Copyright (c) 2016 Nikhil Marathe (@nikhilm): QHttpServer (MIT)" NEWLINE
NEWLINE
"Qv2ray " QV2RAY_VERSION_STRING " running on " +
(QSysInfo::prettyProductName() + " " + QSysInfo::currentCpuArchitecture()).toStdString() + NEWLINE)

View File

@ -394,8 +394,23 @@
</layout>
</widget>
<tabstops>
<tabstop>nameTxt</tabstop>
<tabstop>importSourceCombo</tabstop>
<tabstop>fileLineTxt</tabstop>
<tabstop>keepImportedInboundCheckBox</tabstop>
<tabstop>editFileBtn</tabstop>
<tabstop>selectFileBtn</tabstop>
<tabstop>imageFileEdit</tabstop>
<tabstop>selectImageBtn</tabstop>
<tabstop>qrFromScreenBtn</tabstop>
<tabstop>doubleSpinBox</tabstop>
<tabstop>vmessConnectionStringTxt</tabstop>
<tabstop>errorsList</tabstop>
<tabstop>subscriptionLinkTxt</tabstop>
<tabstop>tableWidget</tabstop>
<tabstop>connectionEditBtn</tabstop>
<tabstop>cancelImportBtn</tabstop>
<tabstop>beginImportBtn</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -359,7 +359,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<iconset>
<normaloff>:/icons/remove_connection_btn.png</normaloff>:/icons/remove_connection_btn.png</iconset>
</property>
</widget>
@ -380,7 +380,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<iconset>
<normaloff>:/icons/add_connection_btn.png</normaloff>:/icons/add_connection_btn.png</iconset>
</property>
</widget>
@ -507,7 +507,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<iconset>
<normaloff>:/icons/remove_connection_btn.png</normaloff>:/icons/remove_connection_btn.png</iconset>
</property>
</widget>
@ -528,7 +528,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<iconset>
<normaloff>:/icons/add_connection_btn.png</normaloff>:/icons/add_connection_btn.png</iconset>
</property>
</widget>
@ -806,9 +806,7 @@
<tabstop>enableSniffingCB</tabstop>
<tabstop>destOverrideList</tabstop>
</tabstops>
<resources>
<include location="../../resources.qrc"/>
</resources>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>

View File

@ -1,4 +1,4 @@
#include <QAction>
#include <QAction>
#include <QCloseEvent>
#include <QDebug>
#include <QFile>
@ -34,12 +34,14 @@ MainWindow::MainWindow(QWidget *parent)
uploadList(),
downloadList(),
HTTPRequestHelper(),
hTray(new QSystemTrayIcon(this))
hTray(new QSystemTrayIcon(this)),
highlighter()
{
auto conf = GetGlobalConfig();
vinstance = new ConnectionInstance(this);
setupUi(this);
//
highlighter = new Highlighter(logText->document());
pacServer = new PACHandler();
//
this->setWindowIcon(QIcon(":/icons/qv2ray.png"));
@ -72,6 +74,7 @@ MainWindow::MainWindow(QWidget *parent)
action_Tray_Start->setEnabled(true);
action_Tray_Stop->setEnabled(false);
action_Tray_Reconnect->setEnabled(false);
//
trayMenu->addAction(action_Tray_ShowHide);
trayMenu->addSeparator();
trayMenu->addAction(action_Tray_Start);
@ -79,6 +82,7 @@ MainWindow::MainWindow(QWidget *parent)
trayMenu->addAction(action_Tray_Reconnect);
trayMenu->addSeparator();
trayMenu->addAction(action_Tray_Quit);
//
connect(action_Tray_ShowHide, &QAction::triggered, this, &MainWindow::ToggleVisibility);
connect(action_Tray_Start, &QAction::triggered, this, &MainWindow::on_startButton_clicked);
connect(action_Tray_Stop, &QAction::triggered, this, &MainWindow::on_stopButton_clicked);
@ -91,7 +95,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(action_RCM_EditJson, &QAction::triggered, this, &MainWindow::on_action_RCM_EditJson_triggered);
connect(action_RCM_ConvToComplex, &QAction::triggered, this, &MainWindow::on_action_RCM_ConvToComplex_triggered);
//
// Share optionss
// Share options
connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered);
//
connect(this, &MainWindow::Connect, this, &MainWindow::on_startButton_clicked);
@ -109,7 +113,7 @@ MainWindow::MainWindow(QWidget *parent)
listMenu->addAction(action_RCM_ShareQR);
//
LoadConnections();
QObject::connect(&HTTPRequestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate);
connect(&HTTPRequestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate);
HTTPRequestHelper.get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest");
//
// For charts
@ -134,11 +138,13 @@ MainWindow::MainWindow(QWidget *parent)
speedChartObj->addSeries(downloadSerie);
speedChartObj->createDefaultAxes();
speedChartObj->axes(Qt::Vertical).first()->setRange(0, 512);
static_cast<QValueAxis>(speedChartObj->axes(Qt::Horizontal).first()).setLabelFormat("dd.dd");
//
static_cast<QValueAxis>(speedChartObj->axes(Qt::Horizontal).first()).setLabelFormat("dd");
speedChartObj->axes(Qt::Horizontal).first()->setRange(0, 30);
speedChartObj->setContentsMargins(-20, -50, -20, -25);
speedChartView = new QChartView(speedChartObj, this);
speedChartView->setRenderHint(QPainter::RenderHint::HighQualityAntialiasing, true);
//
auto layout = new QHBoxLayout(speedChart);
layout->addWidget(speedChartView);
speedChart->setLayout(layout);
@ -147,7 +153,7 @@ MainWindow::MainWindow(QWidget *parent)
if (hasAutoStart) {
// At least kernal is ready.
if (conf.autoStartConfig != "" && QList<string>::fromStdList(conf.configs).contains(conf.autoStartConfig)) {
if (!conf.autoStartConfig.empty() && QList<string>::fromStdList(conf.configs).contains(conf.autoStartConfig)) {
// Has auto start.
CurrentConnectionName = QSTRING(conf.autoStartConfig);
auto item = connectionListWidget->findItems(QSTRING(conf.autoStartConfig), Qt::MatchExactly).front();
@ -170,6 +176,22 @@ MainWindow::MainWindow(QWidget *parent)
StartProcessingPlugins(this);
}
void MainWindow::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
if (focusWidget() == connectionListWidget) {
auto index = connectionListWidget->currentRow();
if (index < 0) return;
auto connectionName = connectionListWidget->currentItem()->text();
ShowAndSetConnection(connectionName, true, true);
}
}
}
void MainWindow::on_action_StartThis_triggered()
{
if (connectionListWidget->selectedItems().empty()) {
@ -206,6 +228,7 @@ void MainWindow::VersionUpdate(QByteArray &data)
tr("Download Link: ") + link, QMessageBox::Ignore);
if (result == QMessageBox::Yes) {
CLOG(result)
QDesktopServices::openUrl(QUrl::fromUserInput(link));
} else if (result == QMessageBox::Ignore) {
conf.ignoredVersion = newversion.toString().toStdString();
@ -816,6 +839,9 @@ void MainWindow::on_action_RCM_ShareQR_triggered(bool checked)
}
void MainWindow::timerEvent(QTimerEvent *event)
{
// Calling base class
QMainWindow::timerEvent(event);
//
Q_UNUSED(event)
auto inbounds = CurrentFullConfig["inbounds"].toArray();
long _totalSpeedUp = 0, _totalSpeedDown = 0, _totalDataUp = 0, _totalDataDown = 0;

View File

@ -11,15 +11,17 @@
#include "QvCoreConfigOperations.hpp"
#include "QvHTTPRequestHelper.hpp"
#include "QvPACHandler.hpp"
#include "QvLogHighlighter.hpp"
#include "ui_w_MainWindow.h"
class MainWindow : public QMainWindow, Ui::MainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
~MainWindow() override;
signals:
void Connect();
void DisConnect();
@ -78,7 +80,9 @@ class MainWindow : public QMainWindow, Ui::MainWindow
protected:
void timerEvent(QTimerEvent *event);
void keyPressEvent(QKeyEvent *e) override;
void timerEvent(QTimerEvent *event) override;
void closeEvent(QCloseEvent *) override;
private:
// Charts
QChartView *speedChartView;
@ -107,9 +111,9 @@ class MainWindow : public QMainWindow, Ui::MainWindow
//
void ShowAndSetConnection(QString currentText, bool SetConnection, bool Apply);
void LoadConnections();
void closeEvent(QCloseEvent *);
//
PACHandler *pacServer;
Highlighter *highlighter;
};
#endif // MAINWINDOW_H

View File

@ -431,7 +431,8 @@
<widget class="QTextBrowser" name="logText">
<property name="font">
<font>
<pointsize>9</pointsize>
<pointsize>8</pointsize>
<italic>false</italic>
</font>
</property>
<property name="verticalScrollBarPolicy">
@ -440,6 +441,13 @@
<property name="lineWrapMode">
<enum>QTextEdit::NoWrap</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Noto Sans';&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
@ -631,7 +639,18 @@
<tabstops>
<tabstop>startButton</tabstop>
<tabstop>stopButton</tabstop>
<tabstop>reconnectButton</tabstop>
<tabstop>clearlogButton</tabstop>
<tabstop>prefrencesBtn</tabstop>
<tabstop>connectionListWidget</tabstop>
<tabstop>importConfigButton</tabstop>
<tabstop>duplicateBtn</tabstop>
<tabstop>removeConfigButton</tabstop>
<tabstop>editConfigButton</tabstop>
<tabstop>editJsonBtn</tabstop>
<tabstop>pingTestBtn</tabstop>
<tabstop>shareBtn</tabstop>
<tabstop>logText</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -1499,7 +1499,8 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; color:#d68952;&quot;&gt;Copyright (c) 2019 dridk (@dridk): X2Struct (Apache)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; color:#d68952;&quot;&gt;Copyright (c) 2011 SCHUTZ Sacha (@dridk): QJsonModel (MIT)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; color:#d68952;&quot;&gt;Copyright (c) 2019 Nikolaos Ftylitakis (@ftylitak): QZXing (Apache2)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; color:#d68952;&quot;&gt;Copyright (c) 2016 Singein (@Singein): ScreenShot (MIT)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; color:#d68952;&quot;&gt;Copyright (c) 2016 Singein (@Singein): ScreenShot (MIT)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; color:#d68952;&quot;&gt;Copyright (c) 2016 Nikhil Marathe (@nikhilm): QHttpServer (MIT)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>

View File

@ -738,6 +738,39 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>addInboundBtn</tabstop>
<tabstop>delInboundBtn</tabstop>
<tabstop>editInboundBtn</tabstop>
<tabstop>addDefaultBtn</tabstop>
<tabstop>inboundsList</tabstop>
<tabstop>addOutboundBtn</tabstop>
<tabstop>delOutboundBtn</tabstop>
<tabstop>editOutboundBtn</tabstop>
<tabstop>insertDirectBtn</tabstop>
<tabstop>insertBlackBtn</tabstop>
<tabstop>outboundsList</tabstop>
<tabstop>routesTable</tabstop>
<tabstop>addRouteBtn</tabstop>
<tabstop>delRouteBtn</tabstop>
<tabstop>netTCPRB</tabstop>
<tabstop>netUDPRB</tabstop>
<tabstop>netBothRB</tabstop>
<tabstop>routeProtocolHTTPCB</tabstop>
<tabstop>routeProtocolTLSCB</tabstop>
<tabstop>routeProtocolBTCB</tabstop>
<tabstop>routePortTxt</tabstop>
<tabstop>enableBalancerCB</tabstop>
<tabstop>routeOutboundSelector</tabstop>
<tabstop>routeUserTxt</tabstop>
<tabstop>sourceIPList</tabstop>
<tabstop>hostList</tabstop>
<tabstop>ipList</tabstop>
<tabstop>balancerSelectionCombo</tabstop>
<tabstop>balancerList</tabstop>
<tabstop>balancerDelBtn</tabstop>
<tabstop>balabcerAddBtn</tabstop>
</tabstops>
<resources/>
<connections>
<connection>

View File

@ -63,6 +63,9 @@
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>startBtn</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -4,11 +4,12 @@
#include <iostream>
#include <QtDebug>
using namespace std;
/*
* Tiny log module.
*/
#define LOG(module, msg) cout << "[" << module << "]: " << msg << endl;
#define XLOG(module, level, msg) LOG(module, level << msg)
#ifdef QT_DEBUG
#define DEBUG(module, msg) LOG("[DEBUG] - " module, msg)
@ -16,18 +17,21 @@ using namespace std;
#define DEBUG(module, msg)
#endif
#define MODULE_INIT "INIT"
#define MODULE_UPDATE "UPDATE"
#define MODULE_VCORE "VCORE"
#define MODULE_CONFIG "CONFIG"
#define MODULE_PROXY "PROXY"
#define MODULE_UI "UI"
#define MODULE_NETWORK "NETWORK"
#define MODULE_FILE "FILE"
#define MODULE_SUBSCRIPTION "SUBSCRIPTION"
#define MODULE_CONNECTION "CONNECTION"
#define MODULE_IMPORT "IMPORT"
#define MODULE_CONNECTION_VMESS "CONNETION-VMESS"
#define MODULE_PLUGIN "PLUGIN"
#define CLOG(value) DEBUG("[CONTENT-LOG]", #value << ":" << value)
#define XLOG(module, level, msg) LOG(module, level << msg)
#define MODULE_INIT "INIT"
#define MODULE_UPDATE "UPDATE"
#define MODULE_VCORE "VCORE"
#define MODULE_CONFIG "CONFIG"
#define MODULE_PROXY "PROXY"
#define MODULE_UI "UI"
#define MODULE_NETWORK "NETWORK"
#define MODULE_FILE "FILE"
#define MODULE_SUBSCRIPTION "SUBSCRIPTION"
#define MODULE_CONNECTION "CONNECTION"
#define MODULE_IMPORT "IMPORT"
#define MODULE_CONNECTION_VMESS "CONNETION-VMESS"
#define MODULE_PLUGIN "PLUGIN"
#endif // QVTINYLOG_H