mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 10:50:23 +08:00
update: use model/view for ConnectionList
This commit is contained in:
parent
7def1c8854
commit
b33c76a556
@ -68,6 +68,9 @@ set(_QV2RAY_UI_SOURCES
|
|||||||
${QV2RAY_QWIDGETS_UI_BASEDIR}/styles/StyleManager.cpp
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/styles/StyleManager.cpp
|
||||||
${QV2RAY_QWIDGETS_UI_BASEDIR}/styles/StyleManager.cpp
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/styles/StyleManager.cpp
|
||||||
${QV2RAY_QWIDGETS_UI_BASEDIR}/styles/StyleManager.hpp
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/styles/StyleManager.hpp
|
||||||
|
# Models
|
||||||
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/models/ConnectionModelHelper.cpp
|
||||||
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/models/ConnectionModelHelper.hpp
|
||||||
# UI Widgets
|
# UI Widgets
|
||||||
${QV2RAY_QWIDGETS_UI_BASEDIR}/widgets/ConnectionInfoWidget.hpp
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/widgets/ConnectionInfoWidget.hpp
|
||||||
${QV2RAY_QWIDGETS_UI_BASEDIR}/widgets/ConnectionInfoWidget.cpp
|
${QV2RAY_QWIDGETS_UI_BASEDIR}/widgets/ConnectionInfoWidget.cpp
|
||||||
|
@ -1 +1 @@
|
|||||||
5946
|
5947
|
||||||
|
@ -35,12 +35,15 @@
|
|||||||
|
|
||||||
#define VIEWABLE 120
|
#define VIEWABLE 120
|
||||||
|
|
||||||
|
// table of supposed nice steps for grid marks to get nice looking quarters of scale
|
||||||
|
const static double roundingTable[] = { 1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8 };
|
||||||
|
|
||||||
SpeedWidget::SpeedWidget(QWidget *parent) : QGraphicsView(parent)
|
SpeedWidget::SpeedWidget(QWidget *parent) : QGraphicsView(parent)
|
||||||
{
|
{
|
||||||
UpdateSpeedPlotSettings();
|
UpdateSpeedPlotSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpeedWidget::AddPointData(QMap<SpeedWidget::GraphID, long> data)
|
void SpeedWidget::AddPointData(QMap<SpeedWidget::GraphType, long> data)
|
||||||
{
|
{
|
||||||
SpeedWidget::PointData point;
|
SpeedWidget::PointData point;
|
||||||
point.x = QDateTime::currentMSecsSinceEpoch() / 1000;
|
point.x = QDateTime::currentMSecsSinceEpoch() / 1000;
|
||||||
@ -50,11 +53,11 @@ void SpeedWidget::AddPointData(QMap<SpeedWidget::GraphID, long> data)
|
|||||||
point.y[id] = data;
|
point.y[id] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_datahalfMin.push_back(point);
|
dataCollection.push_back(point);
|
||||||
|
|
||||||
while (m_datahalfMin.length() > VIEWABLE)
|
while (dataCollection.length() > VIEWABLE)
|
||||||
{
|
{
|
||||||
m_datahalfMin.removeFirst();
|
dataCollection.removeFirst();
|
||||||
}
|
}
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
@ -93,12 +96,6 @@ int friendlyUnitPrecision(const SizeUnit unit)
|
|||||||
default: return 3;
|
default: return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
// table of supposed nice steps for grid marks to get nice looking quarters
|
|
||||||
// of scale
|
|
||||||
const static double roundingTable[] = { 1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8 };
|
|
||||||
struct SplittedValue
|
struct SplittedValue
|
||||||
{
|
{
|
||||||
double arg;
|
double arg;
|
||||||
@ -159,7 +156,6 @@ namespace
|
|||||||
const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0;
|
const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0;
|
||||||
return QLocale::system().toString(argValue, 'f', precision) + " " + unitString(unit, true);
|
return QLocale::system().toString(argValue, 'f', precision) + " " + unitString(unit, true);
|
||||||
}
|
}
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void SpeedWidget::UpdateSpeedPlotSettings()
|
void SpeedWidget::UpdateSpeedPlotSettings()
|
||||||
{
|
{
|
||||||
@ -168,9 +164,12 @@ void SpeedWidget::UpdateSpeedPlotSettings()
|
|||||||
if (!Graph.colorConfig.contains(x)) \
|
if (!Graph.colorConfig.contains(x)) \
|
||||||
Graph.colorConfig[x] = y;
|
Graph.colorConfig[x] = y;
|
||||||
|
|
||||||
_X_(API_INBOUND, (QvPair<QvGraphPenConfig>{ { 134, 196, 63, 1.5f, Qt::SolidLine }, { 50, 153, 255, 1.5f, Qt::SolidLine } }));
|
const static QvPair<QvGraphPenConfig> defaultPen{ { 134, 196, 63, 1.5f, Qt::SolidLine }, { 50, 153, 255, 1.5f, Qt::SolidLine } };
|
||||||
|
const static QvPair<QvGraphPenConfig> directPen{ { 0, 210, 240, 1.5f, Qt::DotLine }, { 235, 220, 42, 1.5f, Qt::DotLine } };
|
||||||
|
|
||||||
|
_X_(API_INBOUND, defaultPen);
|
||||||
_X_(API_OUTBOUND_PROXY, Graph.colorConfig[API_INBOUND]);
|
_X_(API_OUTBOUND_PROXY, Graph.colorConfig[API_INBOUND]);
|
||||||
_X_(API_OUTBOUND_DIRECT, (QvPair<QvGraphPenConfig>{ { 0, 210, 240, 1.5f, Qt::DotLine }, { 235, 220, 42, 1.5f, Qt::DotLine } }));
|
_X_(API_OUTBOUND_DIRECT, directPen);
|
||||||
|
|
||||||
const auto getPen = [](const QvGraphPenConfig &conf) {
|
const auto getPen = [](const QvGraphPenConfig &conf) {
|
||||||
QPen p{ { conf.R, conf.G, conf.B } };
|
QPen p{ { conf.R, conf.G, conf.B } };
|
||||||
@ -200,7 +199,7 @@ void SpeedWidget::UpdateSpeedPlotSettings()
|
|||||||
|
|
||||||
void SpeedWidget::Clear()
|
void SpeedWidget::Clear()
|
||||||
{
|
{
|
||||||
m_datahalfMin.clear();
|
dataCollection.clear();
|
||||||
m_properties.clear();
|
m_properties.clear();
|
||||||
UpdateSpeedPlotSettings();
|
UpdateSpeedPlotSettings();
|
||||||
replot();
|
replot();
|
||||||
@ -215,9 +214,9 @@ quint64 SpeedWidget::maxYValue()
|
|||||||
quint64 maxYValue = 0;
|
quint64 maxYValue = 0;
|
||||||
|
|
||||||
for (int id = 0; id < NB_GRAPHS; ++id)
|
for (int id = 0; id < NB_GRAPHS; ++id)
|
||||||
for (int i = m_datahalfMin.size() - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j)
|
for (int i = dataCollection.size() - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j)
|
||||||
if (m_datahalfMin[i].y[id] > maxYValue)
|
if (dataCollection[i].y[id] > maxYValue)
|
||||||
maxYValue = m_datahalfMin[i].y[id];
|
maxYValue = dataCollection[i].y[id];
|
||||||
|
|
||||||
return maxYValue;
|
return maxYValue;
|
||||||
}
|
}
|
||||||
@ -288,10 +287,10 @@ void SpeedWidget::paintEvent(QPaintEvent *)
|
|||||||
{
|
{
|
||||||
QVector<QPoint> points;
|
QVector<QPoint> points;
|
||||||
|
|
||||||
for (int i = static_cast<int>(m_datahalfMin.size()) - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j)
|
for (int i = static_cast<int>(dataCollection.size()) - 1, j = 0; (i >= 0) && (j <= VIEWABLE); --i, ++j)
|
||||||
{
|
{
|
||||||
const int newX = rect.right() - j * xTickSize;
|
const int newX = rect.right() - j * xTickSize;
|
||||||
const int newY = rect.bottom() - m_datahalfMin[i].y[id] * yMultiplier;
|
const int newY = rect.bottom() - dataCollection[i].y[id] * yMultiplier;
|
||||||
points.push_back({ newX, newY });
|
points.push_back({ newX, newY });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class SpeedWidget : public QGraphicsView
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum GraphID
|
enum GraphType
|
||||||
{
|
{
|
||||||
INBOUND_UP,
|
INBOUND_UP,
|
||||||
INBOUND_DOWN,
|
INBOUND_DOWN,
|
||||||
@ -59,7 +59,7 @@ class SpeedWidget : public QGraphicsView
|
|||||||
|
|
||||||
explicit SpeedWidget(QWidget *parent = nullptr);
|
explicit SpeedWidget(QWidget *parent = nullptr);
|
||||||
void UpdateSpeedPlotSettings();
|
void UpdateSpeedPlotSettings();
|
||||||
void AddPointData(QMap<SpeedWidget::GraphID, long> data);
|
void AddPointData(QMap<SpeedWidget::GraphType, long> data);
|
||||||
void Clear();
|
void Clear();
|
||||||
void replot();
|
void replot();
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ class SpeedWidget : public QGraphicsView
|
|||||||
};
|
};
|
||||||
|
|
||||||
quint64 maxYValue();
|
quint64 maxYValue();
|
||||||
QList<PointData> m_datahalfMin;
|
QList<PointData> dataCollection;
|
||||||
|
|
||||||
QMap<GraphID, GraphProperties> m_properties;
|
QMap<GraphType, GraphProperties> m_properties;
|
||||||
};
|
};
|
||||||
|
163
src/ui/widgets/models/ConnectionModelHelper.cpp
Normal file
163
src/ui/widgets/models/ConnectionModelHelper.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#include "ConnectionModelHelper.hpp"
|
||||||
|
|
||||||
|
#include "core/handler/ConfigHandler.hpp"
|
||||||
|
#include "ui/widgets/widgets/ConnectionItemWidget.hpp"
|
||||||
|
|
||||||
|
#define NumericString(i) (QString("%1").arg(i, 30, 10, QLatin1Char('0')))
|
||||||
|
|
||||||
|
ConnectionListHelper::ConnectionListHelper(QTreeView *view, QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
parentView = view;
|
||||||
|
model = new QStandardItemModel();
|
||||||
|
view->setModel(model);
|
||||||
|
for (const auto &group : ConnectionManager->AllGroups())
|
||||||
|
{
|
||||||
|
addGroupItem(group);
|
||||||
|
for (const auto &connection : ConnectionManager->Connections(group))
|
||||||
|
{
|
||||||
|
addConnectionItem({ connection, group });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto renamedLambda = [&](const ConnectionId &id, const QString &, const QString &newName) {
|
||||||
|
for (const auto &gid : ConnectionManager->GetGroupId(id))
|
||||||
|
{
|
||||||
|
ConnectionGroupPair pair{ id, gid };
|
||||||
|
if (pairs.contains(pair))
|
||||||
|
pairs[pair]->setData(newName, ROLE_DISPLAYNAME);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto latencyLambda = [&](const ConnectionId &id, const int avg) {
|
||||||
|
for (const auto &gid : ConnectionManager->GetGroupId(id))
|
||||||
|
{
|
||||||
|
ConnectionGroupPair pair{ id, gid };
|
||||||
|
if (pairs.contains(pair))
|
||||||
|
pairs[pair]->setData(NumericString(avg), ROLE_LATENCY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto statsLambda = [&](const ConnectionGroupPair &id, const QMap<StatisticsType, QvStatsSpeedData> &data) {
|
||||||
|
if (connections.contains(id.connectionId))
|
||||||
|
{
|
||||||
|
for (const auto &index : connections[id.connectionId])
|
||||||
|
index->setData(NumericString(GetConnectionTotalData(id.connectionId)), ROLE_DATA_USAGE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnConnectionRemovedFromGroup, this, &ConnectionListHelper::OnConnectionDeleted);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnConnectionCreated, this, &ConnectionListHelper::OnConnectionCreated);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnConnectionLinkedWithGroup, this, &ConnectionListHelper::OnConnectionLinkedWithGroup);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnGroupCreated, this, &ConnectionListHelper::OnGroupCreated);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnGroupDeleted, this, &ConnectionListHelper::OnGroupDeleted);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnConnectionRenamed, renamedLambda);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnLatencyTestFinished, latencyLambda);
|
||||||
|
connect(ConnectionManager, &QvConfigHandler::OnStatsAvailable, statsLambda);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionListHelper::~ConnectionListHelper()
|
||||||
|
{
|
||||||
|
delete model;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::Sort(ConnectionInfoRole role, Qt::SortOrder order)
|
||||||
|
{
|
||||||
|
model->setSortRole(role);
|
||||||
|
model->sort(0, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::Filter(const QString &key)
|
||||||
|
{
|
||||||
|
for (const auto &groupId : ConnectionManager->AllGroups())
|
||||||
|
{
|
||||||
|
const auto groupItem = model->indexFromItem(groups[groupId]);
|
||||||
|
bool isTotallyHide = true;
|
||||||
|
for (const auto &connectionId : ConnectionManager->Connections(groupId))
|
||||||
|
{
|
||||||
|
const auto connectionItem = model->indexFromItem(pairs[{ connectionId, groupId }]);
|
||||||
|
const auto willTotallyHide = static_cast<ConnectionItemWidget *>(parentView->indexWidget(connectionItem))->NameMatched(key);
|
||||||
|
parentView->setRowHidden(connectionItem.row(), connectionItem.parent(), !willTotallyHide);
|
||||||
|
isTotallyHide &= willTotallyHide;
|
||||||
|
}
|
||||||
|
parentView->indexWidget(groupItem)->setHidden(isTotallyHide);
|
||||||
|
if (!isTotallyHide)
|
||||||
|
parentView->expand(groupItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStandardItem *ConnectionListHelper::addConnectionItem(const ConnectionGroupPair &id)
|
||||||
|
{
|
||||||
|
// Create Standard Item
|
||||||
|
auto connectionItem = new QStandardItem();
|
||||||
|
connectionItem->setData(GetDisplayName(id.connectionId), ConnectionInfoRole::ROLE_DISPLAYNAME);
|
||||||
|
connectionItem->setData(NumericString(GetConnectionLatency(id.connectionId)), ConnectionInfoRole::ROLE_LATENCY);
|
||||||
|
connectionItem->setData(NumericString(GetConnectionTotalData(id.connectionId)), ConnectionInfoRole::ROLE_DATA_USAGE);
|
||||||
|
//
|
||||||
|
// Find groups
|
||||||
|
const auto groupIndex = groups.contains(id.groupId) ? groups[id.groupId] : addGroupItem(id.groupId);
|
||||||
|
// Append into model
|
||||||
|
groupIndex->appendRow(connectionItem);
|
||||||
|
const auto connectionIndex = connectionItem->index();
|
||||||
|
//
|
||||||
|
auto widget = new ConnectionItemWidget(id, parentView);
|
||||||
|
connect(widget, &ConnectionItemWidget::RequestWidgetFocus, [widget, connectionIndex, this]() {
|
||||||
|
parentView->setCurrentIndex(connectionIndex);
|
||||||
|
parentView->scrollTo(connectionIndex);
|
||||||
|
});
|
||||||
|
//
|
||||||
|
parentView->setIndexWidget(connectionIndex, widget);
|
||||||
|
pairs[id] = connectionItem;
|
||||||
|
connections[id.connectionId].append(connectionItem);
|
||||||
|
return connectionItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStandardItem *ConnectionListHelper::addGroupItem(const GroupId &groupId)
|
||||||
|
{
|
||||||
|
// Create Item
|
||||||
|
const auto item = new QStandardItem();
|
||||||
|
// Set item into model
|
||||||
|
model->appendRow(item);
|
||||||
|
// Get item index
|
||||||
|
const auto index = item->index();
|
||||||
|
parentView->setIndexWidget(index, new ConnectionItemWidget(groupId, parentView));
|
||||||
|
groups[groupId] = item;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::OnConnectionCreated(const ConnectionGroupPair &id, const QString &)
|
||||||
|
{
|
||||||
|
addConnectionItem(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::OnConnectionDeleted(const ConnectionGroupPair &id)
|
||||||
|
{
|
||||||
|
auto item = pairs.take(id);
|
||||||
|
const auto index = model->indexFromItem(item);
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
model->removeRow(index.row(), index.parent());
|
||||||
|
connections[id.connectionId].removeAll(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::OnConnectionLinkedWithGroup(const ConnectionGroupPair &pairId)
|
||||||
|
{
|
||||||
|
addConnectionItem(pairId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::OnGroupCreated(const GroupId &id, const QString &)
|
||||||
|
{
|
||||||
|
addGroupItem(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionListHelper::OnGroupDeleted(const GroupId &id, const QList<ConnectionId> &connections)
|
||||||
|
{
|
||||||
|
for (const auto &conn : connections)
|
||||||
|
{
|
||||||
|
const ConnectionGroupPair pair{ conn, id };
|
||||||
|
OnConnectionDeleted(pair);
|
||||||
|
}
|
||||||
|
const auto item = groups.take(id);
|
||||||
|
const auto index = model->indexFromItem(item);
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
model->removeRow(index.row(), index.parent());
|
||||||
|
}
|
59
src/ui/widgets/models/ConnectionModelHelper.hpp
Normal file
59
src/ui/widgets/models/ConnectionModelHelper.hpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "base/Qv2rayBase.hpp"
|
||||||
|
|
||||||
|
#include <QStandardItem>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
namespace Qv2ray::ui::widgets::models
|
||||||
|
{
|
||||||
|
enum ConnectionInfoRole
|
||||||
|
{
|
||||||
|
// 10 -> Magic value.
|
||||||
|
ROLE_DISPLAYNAME = Qt::UserRole + 10,
|
||||||
|
ROLE_LATENCY,
|
||||||
|
ROLE_IMPORTTIME,
|
||||||
|
ROLE_LAST_CONNECTED_TIME,
|
||||||
|
ROLE_DATA_USAGE
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConnectionListHelper : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ConnectionListHelper(QTreeView *parentView, QObject *parent = nullptr);
|
||||||
|
~ConnectionListHelper();
|
||||||
|
void Sort(ConnectionInfoRole, Qt::SortOrder);
|
||||||
|
void Filter(const QString &);
|
||||||
|
|
||||||
|
inline QModelIndex GetConnectionPairIndex(const ConnectionGroupPair &id) const
|
||||||
|
{
|
||||||
|
return model->indexFromItem(pairs[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QModelIndex GetGroupIndex(const GroupId &id) const
|
||||||
|
{
|
||||||
|
return model->indexFromItem(groups[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStandardItem *addConnectionItem(const ConnectionGroupPair &id);
|
||||||
|
QStandardItem *addGroupItem(const GroupId &groupId);
|
||||||
|
void OnGroupCreated(const GroupId &id, const QString &displayName);
|
||||||
|
void OnGroupDeleted(const GroupId &id, const QList<ConnectionId> &connections);
|
||||||
|
void OnConnectionCreated(const ConnectionGroupPair &Id, const QString &displayName);
|
||||||
|
void OnConnectionDeleted(const ConnectionGroupPair &Id);
|
||||||
|
void OnConnectionLinkedWithGroup(const ConnectionGroupPair &id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTreeView *parentView;
|
||||||
|
QStandardItemModel *model;
|
||||||
|
//
|
||||||
|
QHash<GroupId, QStandardItem *> groups;
|
||||||
|
QHash<ConnectionGroupPair, QStandardItem *> pairs;
|
||||||
|
QHash<ConnectionId, QList<QStandardItem *>> connections;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Qv2ray::ui::widgets::models
|
||||||
|
|
||||||
|
using namespace Qv2ray::ui::widgets::models;
|
@ -20,12 +20,13 @@
|
|||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
|
||||||
#define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING
|
#define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING
|
||||||
|
|
||||||
#define CheckCurrentWidget \
|
#define CheckCurrentWidget \
|
||||||
auto widget = GetItemWidget(connectionListWidget->currentItem()); \
|
auto widget = GetIndexWidget(connectionTreeView->currentIndex()); \
|
||||||
if (widget == nullptr) \
|
if (widget == nullptr) \
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#define GetItemWidget(item) (qobject_cast<ConnectionItemWidget *>(connectionListWidget->itemWidget(item, 0)))
|
#define GetIndexWidget(item) (qobject_cast<ConnectionItemWidget *>(connectionTreeView->indexWidget(item)))
|
||||||
#define NumericString(i) (QString("%1").arg(i, 30, 10, QLatin1Char('0')))
|
#define NumericString(i) (QString("%1").arg(i, 30, 10, QLatin1Char('0')))
|
||||||
|
|
||||||
#define PLUGIN_BUTTON_PROPERTY_KEY "plugin_list_index"
|
#define PLUGIN_BUTTON_PROPERTY_KEY "plugin_list_index"
|
||||||
@ -46,43 +47,9 @@ QvMessageBusSlotImpl(MainWindow)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::MWAddConnectionItem_p(const ConnectionGroupPair &id)
|
void MainWindow::SortConnectionList(ConnectionInfoRole byCol, bool asending)
|
||||||
{
|
{
|
||||||
if (!groupNodes.contains(id.groupId))
|
modelHelper->Sort(byCol, asending ? Qt::AscendingOrder : Qt::DescendingOrder);
|
||||||
{
|
|
||||||
MWAddGroupItem_p(id.groupId);
|
|
||||||
}
|
|
||||||
auto groupItem = groupNodes.value(id.groupId);
|
|
||||||
auto connectionItem = std::make_shared<QTreeWidgetItem>(QStringList{
|
|
||||||
"", //
|
|
||||||
GetDisplayName(id.connectionId), //
|
|
||||||
NumericString(GetConnectionLatency(id.connectionId)), //
|
|
||||||
"IMPORTTIME_NOT_SUPPORTED", //
|
|
||||||
"LAST_CONNECTED_NOT_SUPPORTED", //
|
|
||||||
NumericString(GetConnectionTotalData(id.connectionId)) //
|
|
||||||
});
|
|
||||||
connectionNodes.insert(id, connectionItem);
|
|
||||||
groupItem->addChild(connectionItem.get());
|
|
||||||
auto widget = new ConnectionItemWidget(id, connectionListWidget);
|
|
||||||
connect(widget, &ConnectionItemWidget::RequestWidgetFocus, this, &MainWindow::OnConnectionWidgetFocusRequested);
|
|
||||||
connectionListWidget->setItemWidget(connectionItem.get(), 0, widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::MWAddGroupItem_p(const GroupId &groupId)
|
|
||||||
{
|
|
||||||
auto groupItem = std::make_shared<QTreeWidgetItem>(QStringList{ "", GetDisplayName(groupId) });
|
|
||||||
groupNodes.insert(groupId, groupItem);
|
|
||||||
connectionListWidget->addTopLevelItem(groupItem.get());
|
|
||||||
connectionListWidget->setItemWidget(groupItem.get(), 0, new ConnectionItemWidget(groupId, connectionListWidget));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::SortConnectionList(MW_ITEM_COL byCol, bool asending)
|
|
||||||
{
|
|
||||||
connectionListWidget->sortByColumn(MW_ITEM_COL_NAME, Qt::AscendingOrder);
|
|
||||||
for (auto i = 0; i < connectionListWidget->topLevelItemCount(); i++)
|
|
||||||
{
|
|
||||||
connectionListWidget->topLevelItem(i)->sortChildren(byCol, asending ? Qt::AscendingOrder : Qt::DescendingOrder);
|
|
||||||
}
|
|
||||||
on_locateBtn_clicked();
|
on_locateBtn_clicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,8 +75,10 @@ void MainWindow::OnRecentConnectionsMenuReadyToShow()
|
|||||||
for (const auto &conn : GlobalConfig.uiConfig.recentConnections)
|
for (const auto &conn : GlobalConfig.uiConfig.recentConnections)
|
||||||
{
|
{
|
||||||
if (ConnectionManager->IsValidId(conn))
|
if (ConnectionManager->IsValidId(conn))
|
||||||
tray_RecentConnectionsMenu->addAction(GetDisplayName(conn.connectionId) + " (" + GetDisplayName(conn.groupId) + ")",
|
{
|
||||||
[=]() { emit ConnectionManager->StartConnection(conn); });
|
const auto name = GetDisplayName(conn.connectionId) + " (" + GetDisplayName(conn.groupId) + ")";
|
||||||
|
tray_RecentConnectionsMenu->addAction(name, [=]() { emit ConnectionManager->StartConnection(conn); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +96,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
speedChartWidget = new SpeedWidget(this);
|
speedChartWidget = new SpeedWidget(this);
|
||||||
speedChart->addWidget(speedChartWidget);
|
speedChart->addWidget(speedChartWidget);
|
||||||
//
|
//
|
||||||
|
modelHelper = new ConnectionListHelper(connectionTreeView);
|
||||||
|
//
|
||||||
this->setWindowIcon(QIcon(":/assets/icons/qv2ray.png"));
|
this->setWindowIcon(QIcon(":/assets/icons/qv2ray.png"));
|
||||||
updateColorScheme();
|
updateColorScheme();
|
||||||
UpdateActionTranslations();
|
UpdateActionTranslations();
|
||||||
@ -144,34 +115,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
connect(ConnectionManager, &QvConfigHandler::OnStatsAvailable, this, &MainWindow::OnStatsAvailable);
|
connect(ConnectionManager, &QvConfigHandler::OnStatsAvailable, this, &MainWindow::OnStatsAvailable);
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnKernelLogAvailable, this, &MainWindow::OnVCoreLogAvailable);
|
connect(ConnectionManager, &QvConfigHandler::OnKernelLogAvailable, this, &MainWindow::OnVCoreLogAvailable);
|
||||||
//
|
//
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnConnectionRemovedFromGroup, this, &MainWindow::OnConnectionDeleted);
|
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnConnectionCreated, this, &MainWindow::OnConnectionCreated);
|
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnConnectionLinkedWithGroup, this, &MainWindow::OnConnectionLinkedWithGroup);
|
|
||||||
//
|
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnGroupCreated, this, &MainWindow::OnGroupCreated);
|
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnGroupDeleted, this, &MainWindow::OnGroupDeleted);
|
|
||||||
//
|
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnSubscriptionAsyncUpdateFinished, [](const GroupId &gid) {
|
connect(ConnectionManager, &QvConfigHandler::OnSubscriptionAsyncUpdateFinished, [](const GroupId &gid) {
|
||||||
QvWidgetApplication->ShowTrayMessage(tr("Subscription \"%1\" has been updated").arg(GetDisplayName(gid))); //
|
QvWidgetApplication->ShowTrayMessage(tr("Subscription \"%1\" has been updated").arg(GetDisplayName(gid))); //
|
||||||
});
|
});
|
||||||
//
|
//
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnConnectionRenamed, [this](const ConnectionId &id, const QString &, const QString &newName) {
|
|
||||||
for (const auto &gid : ConnectionManager->GetGroupId(id))
|
|
||||||
{
|
|
||||||
ConnectionGroupPair pair{ id, gid };
|
|
||||||
if (connectionNodes.contains(pair))
|
|
||||||
connectionNodes.value(pair)->setText(MW_ITEM_COL_NAME, newName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(ConnectionManager, &QvConfigHandler::OnLatencyTestFinished, [this](const ConnectionId &id, const int avg) {
|
|
||||||
for (const auto &gid : ConnectionManager->GetGroupId(id))
|
|
||||||
{
|
|
||||||
ConnectionGroupPair pair{ id, gid };
|
|
||||||
if (connectionNodes.contains(pair))
|
|
||||||
connectionNodes.value(pair)->setText(MW_ITEM_COL_PING, NumericString(avg)); //
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//
|
|
||||||
connect(infoWidget, &ConnectionInfoWidget::OnEditRequested, this, &MainWindow::OnEditRequested);
|
connect(infoWidget, &ConnectionInfoWidget::OnEditRequested, this, &MainWindow::OnEditRequested);
|
||||||
connect(infoWidget, &ConnectionInfoWidget::OnJsonEditRequested, this, &MainWindow::OnEditJsonRequested);
|
connect(infoWidget, &ConnectionInfoWidget::OnJsonEditRequested, this, &MainWindow::OnEditJsonRequested);
|
||||||
//
|
//
|
||||||
@ -209,7 +156,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
//
|
//
|
||||||
connect(tray_action_ToggleVisibility, &QAction::triggered, this, &MainWindow::MWToggleVisibility);
|
connect(tray_action_ToggleVisibility, &QAction::triggered, this, &MainWindow::MWToggleVisibility);
|
||||||
connect(tray_action_Preferences, &QAction::triggered, this, &MainWindow::on_preferencesBtn_clicked);
|
connect(tray_action_Preferences, &QAction::triggered, this, &MainWindow::on_preferencesBtn_clicked);
|
||||||
connect(tray_action_Start, &QAction::triggered, [this] { ConnectionManager->StartConnection(lastConnectedIdentifier); });
|
connect(tray_action_Start, &QAction::triggered, [this] { ConnectionManager->StartConnection(lastConnected); });
|
||||||
connect(tray_action_Stop, &QAction::triggered, ConnectionManager, &QvConfigHandler::StopConnection);
|
connect(tray_action_Stop, &QAction::triggered, ConnectionManager, &QvConfigHandler::StopConnection);
|
||||||
connect(tray_action_Restart, &QAction::triggered, ConnectionManager, &QvConfigHandler::RestartConnection);
|
connect(tray_action_Restart, &QAction::triggered, ConnectionManager, &QvConfigHandler::RestartConnection);
|
||||||
connect(tray_action_Quit, &QAction::triggered, this, &MainWindow::Action_Exit);
|
connect(tray_action_Quit, &QAction::triggered, this, &MainWindow::Action_Exit);
|
||||||
@ -300,39 +247,38 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
sortMenu->addAction(sortAction_SortByPing_Asc);
|
sortMenu->addAction(sortAction_SortByPing_Asc);
|
||||||
sortMenu->addAction(sortAction_SortByPing_Dsc);
|
sortMenu->addAction(sortAction_SortByPing_Dsc);
|
||||||
//
|
//
|
||||||
connect(sortAction_SortByName_Asc, &QAction::triggered, [this] { SortConnectionList(MW_ITEM_COL_NAME, true); });
|
connect(sortAction_SortByName_Asc, &QAction::triggered, [this] { SortConnectionList(ROLE_DISPLAYNAME, true); });
|
||||||
connect(sortAction_SortByName_Dsc, &QAction::triggered, [this] { SortConnectionList(MW_ITEM_COL_NAME, false); });
|
connect(sortAction_SortByName_Dsc, &QAction::triggered, [this] { SortConnectionList(ROLE_DISPLAYNAME, false); });
|
||||||
connect(sortAction_SortByData_Asc, &QAction::triggered, [this] { SortConnectionList(MW_ITEM_COL_DATA, true); });
|
connect(sortAction_SortByData_Asc, &QAction::triggered, [this] { SortConnectionList(ROLE_DATA_USAGE, true); });
|
||||||
connect(sortAction_SortByData_Dsc, &QAction::triggered, [this] { SortConnectionList(MW_ITEM_COL_DATA, false); });
|
connect(sortAction_SortByData_Dsc, &QAction::triggered, [this] { SortConnectionList(ROLE_DATA_USAGE, false); });
|
||||||
connect(sortAction_SortByPing_Asc, &QAction::triggered, [this] { SortConnectionList(MW_ITEM_COL_PING, true); });
|
connect(sortAction_SortByPing_Asc, &QAction::triggered, [this] { SortConnectionList(ROLE_LATENCY, true); });
|
||||||
connect(sortAction_SortByPing_Dsc, &QAction::triggered, [this] { SortConnectionList(MW_ITEM_COL_PING, false); });
|
connect(sortAction_SortByPing_Dsc, &QAction::triggered, [this] { SortConnectionList(ROLE_LATENCY, false); });
|
||||||
//
|
//
|
||||||
sortBtn->setMenu(sortMenu);
|
sortBtn->setMenu(sortMenu);
|
||||||
//
|
//
|
||||||
graphWidgetMenu->addAction(action_RCM_CopyGraph);
|
graphWidgetMenu->addAction(action_RCM_CopyGraph);
|
||||||
connect(action_RCM_CopyGraph, &QAction::triggered, this, &MainWindow::Action_CopyGraphAsImage);
|
connect(action_RCM_CopyGraph, &QAction::triggered, this, &MainWindow::Action_CopyGraphAsImage);
|
||||||
//
|
//
|
||||||
LOG(MODULE_UI, "Loading data...")
|
|
||||||
for (const auto &group : ConnectionManager->AllGroups())
|
|
||||||
{
|
|
||||||
MWAddGroupItem_p(group);
|
|
||||||
for (const auto &connection : ConnectionManager->Connections(group)) MWAddConnectionItem_p({ connection, group });
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Find and start if there is an auto-connection
|
// Find and start if there is an auto-connection
|
||||||
const auto connectionStarted = StartAutoConnectionEntry();
|
const auto connectionStarted = StartAutoConnectionEntry();
|
||||||
if (!connectionStarted && connectionListWidget->topLevelItemCount() > 0)
|
|
||||||
|
if (!connectionStarted && !ConnectionManager->Connections().isEmpty())
|
||||||
{
|
{
|
||||||
ReloadRecentConnectionList();
|
|
||||||
// Select the first connection.
|
// Select the first connection.
|
||||||
const auto &topLevelItem = connectionListWidget->topLevelItem(0);
|
const auto groups = ConnectionManager->AllGroups();
|
||||||
const auto &item = (topLevelItem->childCount() > 0) ? topLevelItem->child(0) : topLevelItem;
|
if (!groups.isEmpty())
|
||||||
connectionListWidget->setCurrentItem(item);
|
{
|
||||||
on_connectionListWidget_itemClicked(item, 0);
|
const auto connections = ConnectionManager->Connections(groups.first());
|
||||||
|
if (!connections.empty())
|
||||||
|
{
|
||||||
|
const auto index = modelHelper->GetConnectionPairIndex({ connections.first(), groups.first() });
|
||||||
|
on_connectionTreeView_clicked(index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReloadRecentConnectionList();
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
tray_action_ToggleVisibility->setText(!connectionStarted ? tr("Hide") : tr("Show"));
|
|
||||||
if (!connectionStarted)
|
if (!connectionStarted)
|
||||||
MWShowWindow();
|
MWShowWindow();
|
||||||
else
|
else
|
||||||
@ -423,7 +369,7 @@ void MainWindow::timerEvent(QTimerEvent *event)
|
|||||||
|
|
||||||
void MainWindow::keyPressEvent(QKeyEvent *e)
|
void MainWindow::keyPressEvent(QKeyEvent *e)
|
||||||
{
|
{
|
||||||
if (focusWidget() == connectionListWidget)
|
if (focusWidget() == connectionTreeView)
|
||||||
{
|
{
|
||||||
CheckCurrentWidget;
|
CheckCurrentWidget;
|
||||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)
|
||||||
@ -435,7 +381,7 @@ void MainWindow::keyPressEvent(QKeyEvent *e)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connectionListWidget->expandItem(connectionListWidget->currentItem());
|
connectionTreeView->expand(connectionTreeView->currentIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e->key() == Qt::Key_F2)
|
else if (e->key() == Qt::Key_F2)
|
||||||
@ -450,7 +396,7 @@ void MainWindow::keyPressEvent(QKeyEvent *e)
|
|||||||
|
|
||||||
if (e->key() == Qt::Key_Escape)
|
if (e->key() == Qt::Key_Escape)
|
||||||
{
|
{
|
||||||
auto widget = GetItemWidget(connectionListWidget->currentItem());
|
auto widget = GetIndexWidget(connectionTreeView->currentIndex());
|
||||||
// Check if this key was accpted by the ConnectionItemWidget
|
// Check if this key was accpted by the ConnectionItemWidget
|
||||||
if (widget && widget->IsRenaming())
|
if (widget && widget->IsRenaming())
|
||||||
{
|
{
|
||||||
@ -481,10 +427,10 @@ void MainWindow::keyReleaseEvent(QKeyEvent *e)
|
|||||||
// Workaround of QtWidget not grabbing KeyDown and KeyUp in keyPressEvent
|
// Workaround of QtWidget not grabbing KeyDown and KeyUp in keyPressEvent
|
||||||
if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)
|
if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)
|
||||||
{
|
{
|
||||||
if (focusWidget() == connectionListWidget)
|
if (focusWidget() == connectionTreeView)
|
||||||
{
|
{
|
||||||
CheckCurrentWidget;
|
CheckCurrentWidget;
|
||||||
on_connectionListWidget_itemClicked(connectionListWidget->currentItem(), 0);
|
on_connectionTreeView_clicked(connectionTreeView->currentIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -500,6 +446,7 @@ void MainWindow::Action_Start()
|
|||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
|
delete modelHelper;
|
||||||
for (auto &widget : pluginWidgets) widget->accept();
|
for (auto &widget : pluginWidgets) widget->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,14 +481,14 @@ void MainWindow::on_clearlogButton_clicked()
|
|||||||
{
|
{
|
||||||
masterLogBrowser->document()->clear();
|
masterLogBrowser->document()->clear();
|
||||||
}
|
}
|
||||||
void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint &pos)
|
void MainWindow::on_connectionTreeView_customContextMenuRequested(const QPoint &pos)
|
||||||
{
|
{
|
||||||
Q_UNUSED(pos)
|
Q_UNUSED(pos)
|
||||||
auto _pos = QCursor::pos();
|
auto _pos = QCursor::pos();
|
||||||
auto item = connectionListWidget->itemAt(connectionListWidget->mapFromGlobal(_pos));
|
auto item = connectionTreeView->indexAt(connectionTreeView->mapFromGlobal(_pos));
|
||||||
if (item != nullptr)
|
if (item.isValid())
|
||||||
{
|
{
|
||||||
bool isConnection = GetItemWidget(item)->IsConnection();
|
bool isConnection = GetIndexWidget(item)->IsConnection();
|
||||||
// Disable connection-specific settings.
|
// Disable connection-specific settings.
|
||||||
action_RCM_Start->setEnabled(isConnection);
|
action_RCM_Start->setEnabled(isConnection);
|
||||||
action_RCM_SetAutoConnection->setEnabled(isConnection);
|
action_RCM_SetAutoConnection->setEnabled(isConnection);
|
||||||
@ -551,7 +498,7 @@ void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint
|
|||||||
action_RCM_RenameConnection->setEnabled(isConnection);
|
action_RCM_RenameConnection->setEnabled(isConnection);
|
||||||
action_RCM_DuplicateConnection->setEnabled(isConnection);
|
action_RCM_DuplicateConnection->setEnabled(isConnection);
|
||||||
action_RCM_UpdateSubscription->setEnabled(!isConnection);
|
action_RCM_UpdateSubscription->setEnabled(!isConnection);
|
||||||
action_RCM_RealLatencyTest->setEnabled(isConnection && ConnectionManager->IsConnected(GetItemWidget(item)->Identifier()));
|
action_RCM_RealLatencyTest->setEnabled(isConnection && ConnectionManager->IsConnected(GetIndexWidget(item)->Identifier()));
|
||||||
connectionListRCM_Menu->popup(_pos);
|
connectionListRCM_Menu->popup(_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -560,9 +507,9 @@ void MainWindow::Action_DeleteConnections()
|
|||||||
{
|
{
|
||||||
QList<ConnectionGroupPair> connlist;
|
QList<ConnectionGroupPair> connlist;
|
||||||
|
|
||||||
for (const auto &item : connectionListWidget->selectedItems())
|
for (const auto &item : connectionTreeView->selectionModel()->selectedIndexes())
|
||||||
{
|
{
|
||||||
auto widget = GetItemWidget(item);
|
auto widget = GetIndexWidget(item);
|
||||||
if (widget)
|
if (widget)
|
||||||
{
|
{
|
||||||
const auto identifier = widget->Identifier();
|
const auto identifier = widget->Identifier();
|
||||||
@ -640,18 +587,6 @@ void MainWindow::on_subsButton_clicked()
|
|||||||
GroupManager().exec();
|
GroupManager().exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
|
|
||||||
{
|
|
||||||
Q_UNUSED(column)
|
|
||||||
auto widget = GetItemWidget(item);
|
|
||||||
if (widget == nullptr)
|
|
||||||
return;
|
|
||||||
if (widget->IsConnection())
|
|
||||||
{
|
|
||||||
widget->BeginConnection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::OnDisconnected(const ConnectionGroupPair &id)
|
void MainWindow::OnDisconnected(const ConnectionGroupPair &id)
|
||||||
{
|
{
|
||||||
Q_UNUSED(id)
|
Q_UNUSED(id)
|
||||||
@ -660,7 +595,7 @@ void MainWindow::OnDisconnected(const ConnectionGroupPair &id)
|
|||||||
tray_action_Stop->setEnabled(false);
|
tray_action_Stop->setEnabled(false);
|
||||||
tray_action_Restart->setEnabled(false);
|
tray_action_Restart->setEnabled(false);
|
||||||
tray_SystemProxyMenu->setEnabled(false);
|
tray_SystemProxyMenu->setEnabled(false);
|
||||||
lastConnectedIdentifier = id;
|
lastConnected = id;
|
||||||
locateBtn->setEnabled(false);
|
locateBtn->setEnabled(false);
|
||||||
if (!GlobalConfig.uiConfig.quietMode)
|
if (!GlobalConfig.uiConfig.quietMode)
|
||||||
{
|
{
|
||||||
@ -684,7 +619,7 @@ void MainWindow::OnConnected(const ConnectionGroupPair &id)
|
|||||||
tray_action_Stop->setEnabled(true);
|
tray_action_Stop->setEnabled(true);
|
||||||
tray_action_Restart->setEnabled(true);
|
tray_action_Restart->setEnabled(true);
|
||||||
tray_SystemProxyMenu->setEnabled(true);
|
tray_SystemProxyMenu->setEnabled(true);
|
||||||
lastConnectedIdentifier = id;
|
lastConnected = id;
|
||||||
locateBtn->setEnabled(true);
|
locateBtn->setEnabled(true);
|
||||||
on_clearlogButton_clicked();
|
on_clearlogButton_clicked();
|
||||||
speedChartWidget->Clear();
|
speedChartWidget->Clear();
|
||||||
@ -710,68 +645,9 @@ void MainWindow::OnConnected(const ConnectionGroupPair &id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnConnectionWidgetFocusRequested(const ConnectionItemWidget *_widget)
|
|
||||||
{
|
|
||||||
if (_widget == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto _item_ : connectionListWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard | Qt::MatchRecursive))
|
|
||||||
{
|
|
||||||
if (GetItemWidget(_item_) == _widget)
|
|
||||||
{
|
|
||||||
LOG(MODULE_UI, "Setting current item.")
|
|
||||||
connectionListWidget->setCurrentItem(_item_);
|
|
||||||
connectionListWidget->scrollToItem(_item_);
|
|
||||||
// Click it to show details.
|
|
||||||
on_connectionListWidget_itemClicked(_item_, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_connectionFilterTxt_textEdited(const QString &arg1)
|
void MainWindow::on_connectionFilterTxt_textEdited(const QString &arg1)
|
||||||
{
|
{
|
||||||
// No recursive since we only need top level item
|
modelHelper->Filter(arg1);
|
||||||
for (auto _top_item_ : connectionListWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard))
|
|
||||||
{
|
|
||||||
// auto topWidget = GetItemWidget(_top_item_);
|
|
||||||
bool isTotallyHide = true;
|
|
||||||
|
|
||||||
for (auto i = 0; i < _top_item_->childCount(); i++)
|
|
||||||
{
|
|
||||||
auto _child_ = _top_item_->child(i);
|
|
||||||
|
|
||||||
if (GetItemWidget(_child_)->NameMatched(arg1))
|
|
||||||
{
|
|
||||||
LOG(MODULE_UI, "Setting current item.")
|
|
||||||
// Show the child
|
|
||||||
_child_->setHidden(false);
|
|
||||||
// If any one of the children matches, the parent should not be hidden.
|
|
||||||
isTotallyHide = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_child_->setHidden(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_top_item_->setHidden(isTotallyHide);
|
|
||||||
|
|
||||||
if (!isTotallyHide)
|
|
||||||
{
|
|
||||||
connectionListWidget->expandItem(_top_item_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_connectionListWidget_itemClicked(QTreeWidgetItem *item, int column)
|
|
||||||
{
|
|
||||||
Q_UNUSED(column)
|
|
||||||
auto widget = GetItemWidget(item);
|
|
||||||
if (widget == nullptr)
|
|
||||||
return;
|
|
||||||
infoWidget->ShowDetails(widget->Identifier());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnStatsAvailable(const ConnectionGroupPair &id, const QMap<StatisticsType, QvStatsSpeedData> &data)
|
void MainWindow::OnStatsAvailable(const ConnectionGroupPair &id, const QMap<StatisticsType, QvStatsSpeedData> &data)
|
||||||
@ -781,13 +657,13 @@ void MainWindow::OnStatsAvailable(const ConnectionGroupPair &id, const QMap<Stat
|
|||||||
// This may not be, or may not precisely be, speed per second if the backend
|
// This may not be, or may not precisely be, speed per second if the backend
|
||||||
// has "any" latency. (Hope not...)
|
// has "any" latency. (Hope not...)
|
||||||
//
|
//
|
||||||
QMap<SpeedWidget::GraphID, long> pointData;
|
QMap<SpeedWidget::GraphType, long> pointData;
|
||||||
bool isOutbound = GlobalConfig.uiConfig.graphConfig.useOutboundStats;
|
bool isOutbound = GlobalConfig.uiConfig.graphConfig.useOutboundStats;
|
||||||
bool hasDirect = isOutbound && GlobalConfig.uiConfig.graphConfig.hasDirectStats;
|
bool hasDirect = isOutbound && GlobalConfig.uiConfig.graphConfig.hasDirectStats;
|
||||||
for (const auto &type : data.keys())
|
for (const auto &[type, data] : data.toStdMap())
|
||||||
{
|
{
|
||||||
const auto upSpeed = data[type].first.first;
|
const auto upSpeed = data.first.first;
|
||||||
const auto downSpeed = data[type].first.second;
|
const auto downSpeed = data.first.second;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case API_INBOUND:
|
case API_INBOUND:
|
||||||
@ -829,12 +705,6 @@ void MainWindow::OnStatsAvailable(const ConnectionGroupPair &id, const QMap<Stat
|
|||||||
//
|
//
|
||||||
qvAppTrayIcon->setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected: ") + GetDisplayName(id.connectionId) + //
|
qvAppTrayIcon->setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected: ") + GetDisplayName(id.connectionId) + //
|
||||||
NEWLINE "Up: " + totalSpeedUp + " Down: " + totalSpeedDown);
|
NEWLINE "Up: " + totalSpeedUp + " Down: " + totalSpeedDown);
|
||||||
//
|
|
||||||
// Set data accordingly
|
|
||||||
if (connectionNodes.contains(id))
|
|
||||||
{
|
|
||||||
connectionNodes.value(id)->setText(MW_ITEM_COL_DATA, NumericString(GetConnectionTotalData(id.connectionId)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnVCoreLogAvailable(const ConnectionGroupPair &id, const QString &log)
|
void MainWindow::OnVCoreLogAvailable(const ConnectionGroupPair &id, const QString &log)
|
||||||
@ -903,34 +773,6 @@ void MainWindow::OnEditJsonRequested(const ConnectionId &id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnConnectionCreated(const ConnectionGroupPair &id, const QString &displayName)
|
|
||||||
{
|
|
||||||
Q_UNUSED(displayName)
|
|
||||||
MWAddConnectionItem_p(id);
|
|
||||||
}
|
|
||||||
void MainWindow::OnConnectionDeleted(const ConnectionGroupPair &id)
|
|
||||||
{
|
|
||||||
auto child = connectionNodes.take(id);
|
|
||||||
groupNodes.value(id.groupId)->removeChild(child.get());
|
|
||||||
}
|
|
||||||
void MainWindow::OnConnectionLinkedWithGroup(const ConnectionGroupPair &pairId)
|
|
||||||
{
|
|
||||||
MWAddConnectionItem_p(pairId);
|
|
||||||
}
|
|
||||||
void MainWindow::OnGroupCreated(const GroupId &id, const QString &displayName)
|
|
||||||
{
|
|
||||||
Q_UNUSED(displayName)
|
|
||||||
MWAddGroupItem_p(id);
|
|
||||||
}
|
|
||||||
void MainWindow::OnGroupDeleted(const GroupId &id, const QList<ConnectionId> &connections)
|
|
||||||
{
|
|
||||||
for (const auto &conn : connections)
|
|
||||||
{
|
|
||||||
groupNodes.value(id)->removeChild(connectionNodes.value({ conn, id }).get());
|
|
||||||
}
|
|
||||||
groupNodes.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::OnLogScrollbarValueChanged(int value)
|
void MainWindow::OnLogScrollbarValueChanged(int value)
|
||||||
{
|
{
|
||||||
if (masterLogBrowser->verticalScrollBar()->maximum() == value)
|
if (masterLogBrowser->verticalScrollBar()->maximum() == value)
|
||||||
@ -944,9 +786,10 @@ void MainWindow::on_locateBtn_clicked()
|
|||||||
auto id = KernelInstance->CurrentConnection();
|
auto id = KernelInstance->CurrentConnection();
|
||||||
if (!id.isEmpty())
|
if (!id.isEmpty())
|
||||||
{
|
{
|
||||||
connectionListWidget->setCurrentItem(connectionNodes.value(id).get());
|
const auto index = modelHelper->GetConnectionPairIndex(id);
|
||||||
connectionListWidget->scrollToItem(connectionNodes.value(id).get());
|
connectionTreeView->setCurrentIndex(index);
|
||||||
on_connectionListWidget_itemClicked(connectionNodes.value(id).get(), 0);
|
connectionTreeView->scrollTo(index);
|
||||||
|
on_connectionTreeView_clicked(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,9 +803,9 @@ void MainWindow::Action_DuplicateConnection()
|
|||||||
{
|
{
|
||||||
QList<ConnectionGroupPair> connlist;
|
QList<ConnectionGroupPair> connlist;
|
||||||
|
|
||||||
for (const auto &item : connectionListWidget->selectedItems())
|
for (const auto &item : connectionTreeView->selectionModel()->selectedIndexes())
|
||||||
{
|
{
|
||||||
auto widget = GetItemWidget(item);
|
auto widget = GetIndexWidget(item);
|
||||||
if (widget->IsConnection())
|
if (widget->IsConnection())
|
||||||
{
|
{
|
||||||
connlist.append(widget->Identifier());
|
connlist.append(widget->Identifier());
|
||||||
@ -1012,14 +855,14 @@ void MainWindow::on_clearChartBtn_clicked()
|
|||||||
speedChartWidget->Clear();
|
speedChartWidget->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
// void MainWindow::on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
||||||
{
|
//{
|
||||||
Q_UNUSED(previous)
|
// Q_UNUSED(previous)
|
||||||
if (current != nullptr && !isExiting)
|
// if (current != nullptr && !isExiting)
|
||||||
{
|
// {
|
||||||
on_connectionListWidget_itemClicked(current, 0);
|
// on_connectionListWidget_itemClicked(current, 0);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void MainWindow::on_masterLogBrowser_textChanged()
|
void MainWindow::on_masterLogBrowser_textChanged()
|
||||||
{
|
{
|
||||||
@ -1031,10 +874,10 @@ void MainWindow::on_masterLogBrowser_textChanged()
|
|||||||
|
|
||||||
void MainWindow::Action_SetAutoConnection()
|
void MainWindow::Action_SetAutoConnection()
|
||||||
{
|
{
|
||||||
auto current = connectionListWidget->currentItem();
|
auto current = connectionTreeView->currentIndex();
|
||||||
if (current != nullptr)
|
if (current.isValid())
|
||||||
{
|
{
|
||||||
auto widget = GetItemWidget(current);
|
auto widget = GetIndexWidget(current);
|
||||||
const auto identifier = widget->Identifier();
|
const auto identifier = widget->Identifier();
|
||||||
GlobalConfig.autoStartId = identifier;
|
GlobalConfig.autoStartId = identifier;
|
||||||
GlobalConfig.autoStartBehavior = AUTO_CONNECTION_FIXED;
|
GlobalConfig.autoStartBehavior = AUTO_CONNECTION_FIXED;
|
||||||
@ -1048,10 +891,10 @@ void MainWindow::Action_SetAutoConnection()
|
|||||||
|
|
||||||
void MainWindow::Action_ResetStats()
|
void MainWindow::Action_ResetStats()
|
||||||
{
|
{
|
||||||
auto current = connectionListWidget->currentItem();
|
auto current = connectionTreeView->currentIndex();
|
||||||
if (current != nullptr)
|
if (current.isValid())
|
||||||
{
|
{
|
||||||
auto widget = GetItemWidget(current);
|
auto widget = GetIndexWidget(current);
|
||||||
if (widget)
|
if (widget)
|
||||||
{
|
{
|
||||||
if (widget->IsConnection())
|
if (widget->IsConnection())
|
||||||
@ -1064,10 +907,10 @@ void MainWindow::Action_ResetStats()
|
|||||||
|
|
||||||
void MainWindow::Action_UpdateSubscription()
|
void MainWindow::Action_UpdateSubscription()
|
||||||
{
|
{
|
||||||
auto current = connectionListWidget->currentItem();
|
auto current = connectionTreeView->currentIndex();
|
||||||
if (current != nullptr)
|
if (current.isValid())
|
||||||
{
|
{
|
||||||
auto widget = GetItemWidget(current);
|
auto widget = GetIndexWidget(current);
|
||||||
if (widget)
|
if (widget)
|
||||||
{
|
{
|
||||||
if (widget->IsConnection())
|
if (widget->IsConnection())
|
||||||
@ -1083,11 +926,11 @@ void MainWindow::Action_UpdateSubscription()
|
|||||||
|
|
||||||
void MainWindow::Action_TestLatency()
|
void MainWindow::Action_TestLatency()
|
||||||
{
|
{
|
||||||
for (const auto ¤t : connectionListWidget->selectedItems())
|
for (const auto ¤t : connectionTreeView->selectionModel()->selectedIndexes())
|
||||||
{
|
{
|
||||||
if (!current)
|
if (!current.isValid())
|
||||||
continue;
|
continue;
|
||||||
const auto widget = GetItemWidget(current);
|
const auto widget = GetIndexWidget(current);
|
||||||
if (!widget)
|
if (!widget)
|
||||||
continue;
|
continue;
|
||||||
if (widget->IsConnection())
|
if (widget->IsConnection())
|
||||||
@ -1099,11 +942,11 @@ void MainWindow::Action_TestLatency()
|
|||||||
|
|
||||||
void MainWindow::Action_TestRealLatency()
|
void MainWindow::Action_TestRealLatency()
|
||||||
{
|
{
|
||||||
for (const auto ¤t : connectionListWidget->selectedItems())
|
for (const auto ¤t : connectionTreeView->selectionModel()->selectedIndexes())
|
||||||
{
|
{
|
||||||
if (!current)
|
if (!current.isValid())
|
||||||
continue;
|
continue;
|
||||||
const auto widget = GetItemWidget(current);
|
const auto widget = GetIndexWidget(current);
|
||||||
if (!widget)
|
if (!widget)
|
||||||
continue;
|
continue;
|
||||||
if (widget->IsConnection())
|
if (widget->IsConnection())
|
||||||
@ -1134,8 +977,8 @@ void MainWindow::on_newConnectionBtn_clicked()
|
|||||||
outboundsList.push_back(outboundEntry);
|
outboundsList.push_back(outboundEntry);
|
||||||
CONFIGROOT root;
|
CONFIGROOT root;
|
||||||
root.insert("outbounds", outboundsList);
|
root.insert("outbounds", outboundsList);
|
||||||
const auto item = connectionListWidget->currentItem();
|
const auto item = connectionTreeView->currentIndex();
|
||||||
const auto id = item ? DefaultGroupId : GetItemWidget(item)->Identifier().groupId;
|
const auto id = item.isValid() ? DefaultGroupId : GetIndexWidget(item)->Identifier().groupId;
|
||||||
ConnectionManager->CreateConnection(root, alias, id);
|
ConnectionManager->CreateConnection(root, alias, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1147,15 +990,15 @@ void MainWindow::on_newComplexConnectionBtn_clicked()
|
|||||||
bool isChanged = w.result() == QDialog::Accepted;
|
bool isChanged = w.result() == QDialog::Accepted;
|
||||||
if (isChanged)
|
if (isChanged)
|
||||||
{
|
{
|
||||||
const auto item = connectionListWidget->currentItem();
|
const auto item = connectionTreeView->currentIndex();
|
||||||
const auto id = item ? DefaultGroupId : GetItemWidget(item)->Identifier().groupId;
|
const auto id = item.isValid() ? DefaultGroupId : GetIndexWidget(item)->Identifier().groupId;
|
||||||
ConnectionManager->CreateConnection(root, QJsonIO::GetValue(root, "outbounds", 0, "tag").toString(), id);
|
ConnectionManager->CreateConnection(root, QJsonIO::GetValue(root, "outbounds", 0, "tag").toString(), id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_collapseGroupsBtn_clicked()
|
void MainWindow::on_collapseGroupsBtn_clicked()
|
||||||
{
|
{
|
||||||
connectionListWidget->collapseAll();
|
connectionTreeView->collapseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Action_CopyRecentLogs()
|
void MainWindow::Action_CopyRecentLogs()
|
||||||
@ -1174,3 +1017,20 @@ void MainWindow::Action_CopyRecentLogs()
|
|||||||
}
|
}
|
||||||
qApp->clipboard()->setText(result.join(NEWLINE));
|
qApp->clipboard()->setText(result.join(NEWLINE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_connectionTreeView_doubleClicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
auto widget = GetIndexWidget(index);
|
||||||
|
if (widget == nullptr)
|
||||||
|
return;
|
||||||
|
if (widget->IsConnection())
|
||||||
|
widget->BeginConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_connectionTreeView_clicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
auto widget = GetIndexWidget(index);
|
||||||
|
if (widget == nullptr)
|
||||||
|
return;
|
||||||
|
infoWidget->ShowDetails(widget->Identifier());
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "ui/common/QvMessageBus.hpp"
|
#include "ui/common/QvMessageBus.hpp"
|
||||||
#include "ui/common/speedchart/speedwidget.hpp"
|
#include "ui/common/speedchart/speedwidget.hpp"
|
||||||
#include "ui/widgets/common/WidgetUIBase.hpp"
|
#include "ui/widgets/common/WidgetUIBase.hpp"
|
||||||
|
#include "ui/widgets/models/ConnectionModelHelper.hpp"
|
||||||
#include "ui/widgets/widgets/ConnectionInfoWidget.hpp"
|
#include "ui/widgets/widgets/ConnectionInfoWidget.hpp"
|
||||||
#include "ui/widgets/widgets/ConnectionItemWidget.hpp"
|
#include "ui/widgets/widgets/ConnectionItemWidget.hpp"
|
||||||
#include "ui_w_MainWindow.h"
|
#include "ui_w_MainWindow.h"
|
||||||
@ -17,15 +18,6 @@ namespace Qv2rayPlugin
|
|||||||
class QvPluginMainWindowWidget;
|
class QvPluginMainWindowWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MW_ITEM_COL
|
|
||||||
{
|
|
||||||
MW_ITEM_COL_NAME = 1,
|
|
||||||
MW_ITEM_COL_PING = 2,
|
|
||||||
MW_ITEM_COL_IMPORTTIME = 3,
|
|
||||||
MW_ITEM_COL_LASTCONNETED = 4,
|
|
||||||
MW_ITEM_COL_DATA = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
class MainWindow
|
class MainWindow
|
||||||
: public QMainWindow
|
: public QMainWindow
|
||||||
, Ui::MainWindow
|
, Ui::MainWindow
|
||||||
@ -47,25 +39,29 @@ class MainWindow
|
|||||||
void on_activatedTray(QSystemTrayIcon::ActivationReason reason);
|
void on_activatedTray(QSystemTrayIcon::ActivationReason reason);
|
||||||
void on_preferencesBtn_clicked();
|
void on_preferencesBtn_clicked();
|
||||||
void on_clearlogButton_clicked();
|
void on_clearlogButton_clicked();
|
||||||
void on_connectionListWidget_customContextMenuRequested(const QPoint &pos);
|
void on_connectionTreeView_customContextMenuRequested(const QPoint &pos);
|
||||||
void on_importConfigButton_clicked();
|
void on_importConfigButton_clicked();
|
||||||
void on_subsButton_clicked();
|
void on_subsButton_clicked();
|
||||||
//
|
//
|
||||||
void on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
|
||||||
void on_connectionFilterTxt_textEdited(const QString &arg1);
|
void on_connectionFilterTxt_textEdited(const QString &arg1);
|
||||||
void on_connectionListWidget_itemClicked(QTreeWidgetItem *item, int column);
|
|
||||||
void on_locateBtn_clicked();
|
void on_locateBtn_clicked();
|
||||||
//
|
//
|
||||||
void on_chartVisibilityBtn_clicked();
|
void on_chartVisibilityBtn_clicked();
|
||||||
void on_logVisibilityBtn_clicked();
|
void on_logVisibilityBtn_clicked();
|
||||||
void on_clearChartBtn_clicked();
|
void on_clearChartBtn_clicked();
|
||||||
void on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
|
||||||
void on_masterLogBrowser_textChanged();
|
void on_masterLogBrowser_textChanged();
|
||||||
//
|
//
|
||||||
void on_pluginsBtn_clicked();
|
void on_pluginsBtn_clicked();
|
||||||
void on_collapseGroupsBtn_clicked();
|
void on_collapseGroupsBtn_clicked();
|
||||||
void on_newConnectionBtn_clicked();
|
void on_newConnectionBtn_clicked();
|
||||||
void on_newComplexConnectionBtn_clicked();
|
void on_newComplexConnectionBtn_clicked();
|
||||||
|
//
|
||||||
|
// void on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||||
|
// void on_connectionListWidget_itemClicked(QTreeWidgetItem *item, int column);
|
||||||
|
// void on_connectionListWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||||
|
|
||||||
|
void on_connectionTreeView_doubleClicked(const QModelIndex &index);
|
||||||
|
void on_connectionTreeView_clicked(const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Do not declare as slots, we connect them manually.
|
// Do not declare as slots, we connect them manually.
|
||||||
@ -86,8 +82,6 @@ class MainWindow
|
|||||||
void Action_CopyGraphAsImage();
|
void Action_CopyGraphAsImage();
|
||||||
void Action_CopyRecentLogs();
|
void Action_CopyRecentLogs();
|
||||||
|
|
||||||
void OnConnectionWidgetFocusRequested(const ConnectionItemWidget *widget);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MWToggleVisibility();
|
void MWToggleVisibility();
|
||||||
void OnEditRequested(const ConnectionId &id);
|
void OnEditRequested(const ConnectionId &id);
|
||||||
@ -98,14 +92,7 @@ class MainWindow
|
|||||||
void OnStatsAvailable(const ConnectionGroupPair &id, const QMap<StatisticsType, QvStatsSpeedData> &data);
|
void OnStatsAvailable(const ConnectionGroupPair &id, const QMap<StatisticsType, QvStatsSpeedData> &data);
|
||||||
void OnVCoreLogAvailable(const ConnectionGroupPair &id, const QString &log);
|
void OnVCoreLogAvailable(const ConnectionGroupPair &id, const QString &log);
|
||||||
//
|
//
|
||||||
void OnConnectionCreated(const ConnectionGroupPair &Id, const QString &displayName);
|
void SortConnectionList(ConnectionInfoRole byCol, bool asending);
|
||||||
void OnConnectionDeleted(const ConnectionGroupPair &Id);
|
|
||||||
void OnConnectionLinkedWithGroup(const ConnectionGroupPair &id);
|
|
||||||
//
|
|
||||||
void OnGroupCreated(const GroupId &id, const QString &displayName);
|
|
||||||
void OnGroupDeleted(const GroupId &id, const QList<ConnectionId> &connections);
|
|
||||||
//
|
|
||||||
void SortConnectionList(MW_ITEM_COL byCol, bool asending);
|
|
||||||
//
|
//
|
||||||
void ReloadRecentConnectionList();
|
void ReloadRecentConnectionList();
|
||||||
void OnRecentConnectionsMenuReadyToShow();
|
void OnRecentConnectionsMenuReadyToShow();
|
||||||
@ -122,8 +109,6 @@ class MainWindow
|
|||||||
void closeEvent(QCloseEvent *) override;
|
void closeEvent(QCloseEvent *) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<GroupId, std::shared_ptr<QTreeWidgetItem>> groupNodes;
|
|
||||||
QHash<ConnectionGroupPair, std::shared_ptr<QTreeWidgetItem>> connectionNodes;
|
|
||||||
// Charts
|
// Charts
|
||||||
SpeedWidget *speedChartWidget;
|
SpeedWidget *speedChartWidget;
|
||||||
SyntaxHighlighter *vCoreLogHighlighter;
|
SyntaxHighlighter *vCoreLogHighlighter;
|
||||||
@ -179,7 +164,7 @@ class MainWindow
|
|||||||
int qvLogTimerId = -1;
|
int qvLogTimerId = -1;
|
||||||
bool qvLogAutoScoll = true;
|
bool qvLogAutoScoll = true;
|
||||||
//
|
//
|
||||||
ConnectionGroupPair lastConnectedIdentifier;
|
ConnectionGroupPair lastConnected;
|
||||||
void MWSetSystemProxy();
|
void MWSetSystemProxy();
|
||||||
void MWClearSystemProxy();
|
void MWClearSystemProxy();
|
||||||
void MWShowWindow();
|
void MWShowWindow();
|
||||||
@ -189,8 +174,7 @@ class MainWindow
|
|||||||
//
|
//
|
||||||
void updateColorScheme();
|
void updateColorScheme();
|
||||||
//
|
//
|
||||||
void MWAddConnectionItem_p(const ConnectionGroupPair &id);
|
|
||||||
void MWAddGroupItem_p(const GroupId &groupId);
|
|
||||||
//
|
|
||||||
QList<Qv2rayPlugin::QvPluginMainWindowWidget *> pluginWidgets;
|
QList<Qv2rayPlugin::QvPluginMainWindowWidget *> pluginWidgets;
|
||||||
|
//
|
||||||
|
Qv2ray::ui::widgets::models::ConnectionListHelper *modelHelper;
|
||||||
};
|
};
|
||||||
|
@ -135,7 +135,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeWidget" name="connectionListWidget">
|
<widget class="QTreeView" name="connectionTreeView">
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -154,26 +154,12 @@
|
|||||||
<property name="sortingEnabled">
|
<property name="sortingEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="animated">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="allColumnsShowFocus">
|
<property name="allColumnsShowFocus">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="headerHidden">
|
<property name="headerHidden">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="expandsOnDoubleClick">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="headerShowSortIndicator" stdset="0">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">1</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -568,7 +554,6 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>connectionListWidget</tabstop>
|
|
||||||
<tabstop>importConfigButton</tabstop>
|
<tabstop>importConfigButton</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user