add: added multiple duplicate and sorting support

This commit is contained in:
Qv2ray-dev 2020-03-03 00:34:12 +08:00
parent 11275e1c9e
commit 3df2cea74b
14 changed files with 253 additions and 137 deletions

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583165428350" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2286" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M128 553.984l0-84.010667 512 0 0 84.010667-512 0zM128 256l768 0 0 86.016-768 0 0-86.016zM128 768l0-86.016 256 0 0 86.016-256 0z" p-id="2287" fill="#e6e6e6"></path></svg>

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583165428350" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2286" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M128 553.984l0-84.010667 512 0 0 84.010667-512 0zM128 256l768 0 0 86.016-768 0 0-86.016zM128 768l0-86.016 256 0 0 86.016-256 0z" p-id="2287" fill="#2c2c2c"></path></svg>

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

View File

@ -1 +1 @@
4349 4385

View File

@ -30,5 +30,7 @@
<file>assets/icons/ui_light/stop.png</file> <file>assets/icons/ui_light/stop.png</file>
<file>assets/icons/ui_dark/locate.png</file> <file>assets/icons/ui_dark/locate.png</file>
<file>assets/icons/ui_light/locate.png</file> <file>assets/icons/ui_light/locate.png</file>
<file>assets/icons/ui_dark/sort.png</file>
<file>assets/icons/ui_light/sort.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -227,14 +227,24 @@ namespace Qv2ray::core::handlers
return connections[id].groupId; return connections[id].groupId;
} }
double QvConnectionHandler::GetConnectionLatency(const ConnectionId &id) const uint64_t QvConnectionHandler::GetConnectionTotalData(const ConnectionId &id) const
{ {
if (!connections.contains(id)) if (!connections.contains(id))
{ {
LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString()); LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString());
} }
return connections[id].latency; return connections[id].upLinkData + connections[id].downLinkData;
}
int64_t QvConnectionHandler::GetConnectionLatency(const ConnectionId &id) const
{
if (!connections.contains(id))
{
LOG(MODULE_CORE_HANDLER, "Cannot find id: " + id.toString());
}
return max(connections[id].latency, 0L);
} }
const optional<QString> QvConnectionHandler::RenameConnection(const ConnectionId &id, const QString &newName) const optional<QString> QvConnectionHandler::RenameConnection(const ConnectionId &id, const QString &newName)
{ {

View File

@ -64,7 +64,8 @@ namespace Qv2ray::core::handlers
const QString GetConnectionProtocolString(const ConnectionId &id) const; const QString GetConnectionProtocolString(const ConnectionId &id) const;
const CONFIGROOT GetConnectionRoot(const ConnectionId &id) const; const CONFIGROOT GetConnectionRoot(const ConnectionId &id) const;
const CONFIGROOT GetConnectionRoot(const GroupId &group, const ConnectionId &id) const; const CONFIGROOT GetConnectionRoot(const GroupId &group, const ConnectionId &id) const;
double GetConnectionLatency(const ConnectionId &id) const; int64_t GetConnectionLatency(const ConnectionId &id) const;
uint64_t GetConnectionTotalData(const ConnectionId &id) const;
const tuple<quint64, quint64> GetConnectionUsageAmount(const ConnectionId &id) const; const tuple<quint64, quint64> GetConnectionUsageAmount(const ConnectionId &id) const;
// //
// Misc Connection Operations // Misc Connection Operations

View File

@ -26,15 +26,14 @@
#include <QUrl> #include <QUrl>
#include <QVersionNumber> #include <QVersionNumber>
// MainWindow.cpp --> Main MainWindow source file, handles mostly UI-related
// operations.
#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 = GetItemWidget(connectionListWidget->currentItem()); \
if (widget == nullptr) \ if (widget == nullptr) \
return; return;
#define GetItemWidget(item) (qobject_cast<ConnectionItemWidget *>(connectionListWidget->itemWidget(item, 0))) #define GetItemWidget(item) (qobject_cast<ConnectionItemWidget *>(connectionListWidget->itemWidget(item, 0)))
#define NumericString(i) (QString("%1").arg(i, 15, 10, QLatin1Char('0')))
MainWindow *MainWindow::mwInstance = nullptr; MainWindow *MainWindow::mwInstance = nullptr;
@ -53,7 +52,14 @@ void MainWindow::MWAddConnectionItem_p(const ConnectionId &connection, const Gro
MWAddGroupItem_p(groupId); MWAddGroupItem_p(groupId);
} }
auto groupItem = groupNodes[groupId]; auto groupItem = groupNodes[groupId];
auto connectionItem = make_shared<QTreeWidgetItem>(QStringList{ "", ConnectionManager->GetDisplayName(connection) }); auto connectionItem = make_shared<QTreeWidgetItem>(QStringList{
"", //
ConnectionManager->GetDisplayName(connection), //
NumericString(ConnectionManager->GetConnectionLatency(connection)), //
"IMPORTTIME_NOT_SUPPORTED", //
"LAST_CONNECTED_NOT_SUPPORTED", //
NumericString(ConnectionManager->GetConnectionTotalData(connection)) //
});
connectionNodes[connection] = connectionItem; connectionNodes[connection] = connectionItem;
groupItem->addChild(connectionItem.get()); groupItem->addChild(connectionItem.get());
auto widget = new ConnectionItemWidget(connection, connectionListWidget); auto widget = new ConnectionItemWidget(connection, connectionListWidget);
@ -69,6 +75,16 @@ void MainWindow::MWAddGroupItem_p(const GroupId &groupId)
connectionListWidget->setItemWidget(groupItem.get(), 0, new ConnectionItemWidget(groupId, connectionListWidget)); connectionListWidget->setItemWidget(groupItem.get(), 0, new ConnectionItemWidget(groupId, connectionListWidget));
} }
void MainWindow::SortConnectionList(MW_ITEM_COL byCol, bool asending)
{
connectionListWidget->sortByColumn(MW_ITEM_COL_DISPLAYNAME, Qt::AscendingOrder);
for (auto i = 0; i < connectionListWidget->topLevelItemCount(); i++)
{
connectionListWidget->topLevelItem(i)->sortChildren(byCol, asending ? Qt::AscendingOrder : Qt::DescendingOrder);
}
}
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), hTray(this), tcpingHelper(3, this) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), hTray(this), tcpingHelper(3, this)
{ {
setupUi(this); setupUi(this);
@ -82,11 +98,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), h
// For charts // For charts
speedChartWidget = new SpeedWidget(this); speedChartWidget = new SpeedWidget(this);
speedChart->addWidget(speedChartWidget); speedChart->addWidget(speedChartWidget);
//
this->setWindowIcon(QIcon(":/assets/icons/qv2ray.png")); this->setWindowIcon(QIcon(":/assets/icons/qv2ray.png"));
hTray.setIcon(QIcon(GlobalConfig.uiConfig.useDarkTrayIcon ? ":/assets/icons/ui_dark/tray.png" : ":/assets/icons/ui_light/tray.png")); hTray.setIcon(QIcon(GlobalConfig.uiConfig.useDarkTrayIcon ? ":/assets/icons/ui_dark/tray.png" : ":/assets/icons/ui_light/tray.png"));
//
importConfigButton->setIcon(QICON_R("import.png")); importConfigButton->setIcon(QICON_R("import.png"));
// pingTestBtn->setIcon(QICON_R("ping_gauge.png"));
// shareBtn->setIcon(QICON_R("share.png"));
updownImageBox->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)"); updownImageBox->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)");
updownImageBox_2->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)"); updownImageBox_2->setStyleSheet("image: url(" + QV2RAY_UI_RESOURCES_ROOT + "netspeed_arrow.png)");
// //
@ -109,7 +125,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), h
// //
connect(ConnectionManager, &QvConnectionHandler::OnGroupCreated, this, &MainWindow::OnGroupCreated); connect(ConnectionManager, &QvConnectionHandler::OnGroupCreated, this, &MainWindow::OnGroupCreated);
connect(ConnectionManager, &QvConnectionHandler::OnGroupDeleted, this, &MainWindow::OnGroupDeleted); connect(ConnectionManager, &QvConnectionHandler::OnGroupDeleted, this, &MainWindow::OnGroupDeleted);
//
connect(ConnectionManager, &QvConnectionHandler::OnConnectionRenamed, [&](const ConnectionId &id, const QString &, const QString &newName) {
connectionNodes[id]->setText(MW_ITEM_COL_DISPLAYNAME, newName); //
});
connect(ConnectionManager, &QvConnectionHandler::OnLatencyTestFinished, [&](const ConnectionId &id, const uint avg) {
connectionNodes[id]->setText(MW_ITEM_COL_LATENCY, NumericString(avg)); //
});
// //
connect(infoWidget, &ConnectionInfoWidget::OnEditRequested, this, &MainWindow::OnEditRequested); connect(infoWidget, &ConnectionInfoWidget::OnEditRequested, this, &MainWindow::OnEditRequested);
connect(infoWidget, &ConnectionInfoWidget::OnJsonEditRequested, this, &MainWindow::OnJsonEditRequested); connect(infoWidget, &ConnectionInfoWidget::OnJsonEditRequested, this, &MainWindow::OnJsonEditRequested);
@ -164,12 +186,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), h
QAction *action_RCM_StartThis = new QAction(tr("Connect to this"), this); QAction *action_RCM_StartThis = new QAction(tr("Connect to this"), this);
QAction *action_RCM_RenameThis = new QAction(tr("Rename"), this); QAction *action_RCM_RenameThis = new QAction(tr("Rename"), this);
QAction *action_RCM_DeleteThese = new QAction(tr("Delete Connection"), this); QAction *action_RCM_DeleteThese = new QAction(tr("Delete Connection"), this);
QAction *action_RCM_DuplicateThese = new QAction(QICON_R("duplicate.png"), tr("Duplicate to the Same Group"), this);
QAction *action_RCM_ConvToComplex = new QAction(QICON_R("edit.png"), tr("Edit as Complex Config"), this); QAction *action_RCM_ConvToComplex = new QAction(QICON_R("edit.png"), tr("Edit as Complex Config"), this);
// //
connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered); connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered);
connect(action_RCM_ConvToComplex, &QAction::triggered, this, &MainWindow::on_action_RCM_ConvToComplex_triggered); connect(action_RCM_ConvToComplex, &QAction::triggered, this, &MainWindow::on_action_RCM_ConvToComplex_triggered);
connect(action_RCM_RenameThis, &QAction::triggered, this, &MainWindow::on_action_RCM_RenameThis_triggered); connect(action_RCM_RenameThis, &QAction::triggered, this, &MainWindow::on_action_RCM_RenameThis_triggered);
connect(action_RCM_DeleteThese, &QAction::triggered, this, &MainWindow::on_action_RCM_DeleteThese_triggered); connect(action_RCM_DeleteThese, &QAction::triggered, this, &MainWindow::on_action_RCM_DeleteThese_triggered);
connect(action_RCM_DuplicateThese, &QAction::triggered, this, &MainWindow::on_action_RCM_DuplicateThese_triggered);
// //
// Globally invokable signals. // Globally invokable signals.
connect(this, &MainWindow::Connect, [&] { ConnectionManager->StartConnection(lastConnectedId); }); connect(this, &MainWindow::Connect, [&] { ConnectionManager->StartConnection(lastConnectedId); });
@ -182,11 +206,35 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //, vinstance(), h
connectionListMenu = new QMenu(this); connectionListMenu = new QMenu(this);
connectionListMenu->addAction(action_RCM_StartThis); connectionListMenu->addAction(action_RCM_StartThis);
connectionListMenu->addAction(action_RCM_RenameThis); connectionListMenu->addAction(action_RCM_RenameThis);
connectionListMenu->addAction(action_RCM_DuplicateThese);
connectionListMenu->addAction(action_RCM_DeleteThese); connectionListMenu->addAction(action_RCM_DeleteThese);
connectionListMenu->addAction(action_RCM_ConvToComplex); connectionListMenu->addAction(action_RCM_ConvToComplex);
// //
LOG(MODULE_UI, "Loading data...") sortMenu = new QMenu(this);
auto groups = ConnectionManager->AllGroups(); sortAction_SortByName_Asc = new QAction(tr("By connection name, A-Z"));
sortAction_SortByName_Dsc = new QAction(tr("By connection name, Z-A"));
sortAction_SortByData_Asc = new QAction(tr("By data, Less to more"));
sortAction_SortByData_Dsc = new QAction(tr("By data, More to less"));
sortAction_SortByLatency_Asc = new QAction(tr("By latency, Short to long"));
sortAction_SortByLatency_Dsc = new QAction(tr("By latency, Long to short"));
//
connect(sortAction_SortByName_Asc, &QAction::triggered, [&] { SortConnectionList(MW_ITEM_COL_DISPLAYNAME, true); });
connect(sortAction_SortByName_Dsc, &QAction::triggered, [&] { SortConnectionList(MW_ITEM_COL_DISPLAYNAME, false); });
connect(sortAction_SortByData_Asc, &QAction::triggered, [&] { SortConnectionList(MW_ITEM_COL_DATAUSAGE, true); });
connect(sortAction_SortByData_Dsc, &QAction::triggered, [&] { SortConnectionList(MW_ITEM_COL_DATAUSAGE, false); });
connect(sortAction_SortByLatency_Asc, &QAction::triggered, [&] { SortConnectionList(MW_ITEM_COL_LATENCY, true); });
connect(sortAction_SortByLatency_Dsc, &QAction::triggered, [&] { SortConnectionList(MW_ITEM_COL_LATENCY, false); });
//
sortMenu->addAction(sortAction_SortByName_Asc);
sortMenu->addAction(sortAction_SortByName_Dsc);
sortMenu->addAction(sortAction_SortByData_Asc);
sortMenu->addAction(sortAction_SortByData_Dsc);
sortMenu->addAction(sortAction_SortByLatency_Asc);
sortMenu->addAction(sortAction_SortByLatency_Dsc);
//
sortBtn->setMenu(sortMenu);
//
LOG(MODULE_UI, "Loading data...") auto groups = ConnectionManager->AllGroups();
for (auto group : groups) for (auto group : groups)
{ {
@ -405,7 +453,6 @@ void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint
void MainWindow::on_action_RCM_DeleteThese_triggered() void MainWindow::on_action_RCM_DeleteThese_triggered()
{ {
QvMessageBoxInfo(this, "NOT SUPPORTED", "WIP");
QList<ConnectionId> connlist; QList<ConnectionId> connlist;
for (auto item : connectionListWidget->selectedItems()) for (auto item : connectionListWidget->selectedItems())
@ -678,8 +725,11 @@ void MainWindow::OnStatsAvailable(const ConnectionId &id, const quint64 upS, con
netspeedLabel->setText(totalSpeedUp + NEWLINE + totalSpeedDown); netspeedLabel->setText(totalSpeedUp + NEWLINE + totalSpeedDown);
dataamountLabel->setText(totalDataUp + NEWLINE + totalDataDown); dataamountLabel->setText(totalDataUp + NEWLINE + totalDataDown);
// //
hTray.setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected: ") + ConnectionManager->GetDisplayName(id) + NEWLINE "Up: " + totalSpeedUp + hTray.setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected: ") + //
" Down: " + totalSpeedDown); ConnectionManager->GetDisplayName(id) + NEWLINE "Up: " + totalSpeedUp + " Down: " + totalSpeedDown);
//
// Set data accordingly
connectionNodes[id]->setText(MW_ITEM_COL_DATAUSAGE, NumericString(ConnectionManager->GetConnectionTotalData(id)));
} }
void MainWindow::OnVCoreLogAvailable(const ConnectionId &id, const QString &log) void MainWindow::OnVCoreLogAvailable(const ConnectionId &id, const QString &log)
@ -801,3 +851,37 @@ void MainWindow::on_action_RCM_RenameThis_triggered()
CheckCurrentWidget; CheckCurrentWidget;
widget->BeginRename(); widget->BeginRename();
} }
void MainWindow::on_action_RCM_DuplicateThese_triggered()
{
QList<ConnectionId> connlist;
for (auto item : connectionListWidget->selectedItems())
{
auto widget = GetItemWidget(item);
if (widget->IsConnection())
{
connlist.append(get<1>(widget->Identifier()));
}
}
LOG(MODULE_UI, "Selected " + QSTRN(connlist.count()) + " items")
if (connlist.isEmpty())
{
return;
}
if (connlist.count() > 1 &&
QvMessageBoxAsk(this, tr("Duplicating Connection(s)"), tr("Are you sure to duplicate these connection(s)?")) != QMessageBox::Yes)
{
return;
}
for (auto conn : connlist)
{
ConnectionManager->CreateConnection(ConnectionManager->GetDisplayName(conn) + tr(" (Copy)"), //
ConnectionManager->GetConnectionGroupId(conn), //
ConnectionManager->GetConnectionRoot(conn));
}
}

View File

@ -17,6 +17,15 @@
#include "ui/widgets/ConnectionInfoWidget.hpp" #include "ui/widgets/ConnectionInfoWidget.hpp"
#include "ui/widgets/ConnectionItemWidget.hpp" #include "ui/widgets/ConnectionItemWidget.hpp"
enum MW_ITEM_COL
{
MW_ITEM_COL_DISPLAYNAME = 1,
MW_ITEM_COL_LATENCY = 2,
MW_ITEM_COL_IMPORTTIME = 3,
MW_ITEM_COL_LASTCONNETED = 4,
MW_ITEM_COL_DATAUSAGE = 5
};
class MainWindow class MainWindow
: public QMainWindow : public QMainWindow
, Ui::MainWindow , Ui::MainWindow
@ -77,11 +86,14 @@ class MainWindow
void on_action_RCM_ConvToComplex_triggered(); void on_action_RCM_ConvToComplex_triggered();
void on_action_RCM_RenameThis_triggered(); void on_action_RCM_RenameThis_triggered();
void on_action_RCM_DeleteThese_triggered(); void on_action_RCM_DeleteThese_triggered();
void on_action_RCM_DuplicateThese_triggered();
// //
void on_connectionListWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); 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_connectionListWidget_itemClicked(QTreeWidgetItem *item, int column);
void on_locateBtn_clicked(); void on_locateBtn_clicked();
//
void SortConnectionList(MW_ITEM_COL byCol, bool asending);
private: private:
QHash<GroupId, shared_ptr<QTreeWidgetItem>> groupNodes; QHash<GroupId, shared_ptr<QTreeWidgetItem>> groupNodes;
@ -115,6 +127,14 @@ class MainWindow
QAction *action_Tray_SetSystemProxy; QAction *action_Tray_SetSystemProxy;
QAction *action_Tray_ClearSystemProxy; QAction *action_Tray_ClearSystemProxy;
// //
QMenu *sortMenu;
QAction *sortAction_SortByName_Asc;
QAction *sortAction_SortByName_Dsc;
QAction *sortAction_SortByLatency_Asc;
QAction *sortAction_SortByLatency_Dsc;
QAction *sortAction_SortByData_Asc;
QAction *sortAction_SortByData_Dsc;
//
// Extra Headers For w_MainWindow_extra.cpp Handling V2ray Connectivities. // Extra Headers For w_MainWindow_extra.cpp Handling V2ray Connectivities.
ConnectionId lastConnectedId; ConnectionId lastConnectedId;
void MWSetSystemProxy(); void MWSetSystemProxy();

View File

@ -86,16 +86,6 @@
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLineEdit" name="connectionFilterTxt">
<property name="placeholderText">
<string>Search</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QToolButton" name="locateBtn"> <widget class="QToolButton" name="locateBtn">
<property name="enabled"> <property name="enabled">
@ -113,43 +103,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2"> <item row="0" column="0">
<widget class="QTreeWidget" name="connectionListWidget"> <widget class="QLineEdit" name="connectionFilterTxt">
<property name="contextMenuPolicy"> <property name="placeholderText">
<enum>Qt::CustomContextMenu</enum> <string>Search</string>
</property> </property>
<property name="editTriggers"> <property name="clearButtonEnabled">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="animated">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
@ -204,6 +165,62 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="2">
<widget class="QToolButton" name="sortBtn">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/assets/icons/ui_light/sort.png</normaloff>:/assets/icons/ui_light/sort.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QTreeWidget" name="connectionListWidget">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="animated">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</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>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QScrollArea" name="scrollArea"> <widget class="QScrollArea" name="scrollArea">

View File

@ -8,7 +8,6 @@
ConnectionInfoWidget::ConnectionInfoWidget(QWidget *parent) : QWidget(parent) ConnectionInfoWidget::ConnectionInfoWidget(QWidget *parent) : QWidget(parent)
{ {
setupUi(this); setupUi(this);
duplicateBtn->setIcon(QICON_R("duplicate.png"));
deleteBtn->setIcon(QICON_R("delete.png")); deleteBtn->setIcon(QICON_R("delete.png"));
editBtn->setIcon(QICON_R("edit.png")); editBtn->setIcon(QICON_R("edit.png"));
editJsonBtn->setIcon(QICON_R("json.png")); editJsonBtn->setIcon(QICON_R("json.png"));
@ -32,20 +31,24 @@ void ConnectionInfoWidget::ShowDetails(const tuple<GroupId, ConnectionId> &_iden
editBtn->setEnabled(isConnection); editBtn->setEnabled(isConnection);
editJsonBtn->setEnabled(isConnection); editJsonBtn->setEnabled(isConnection);
connectBtn->setEnabled(isConnection); connectBtn->setEnabled(isConnection);
duplicateBtn->setEnabled(isConnection);
stackedWidget->setCurrentIndex(isConnection ? 0 : 1); stackedWidget->setCurrentIndex(isConnection ? 0 : 1);
if (isConnection) if (isConnection)
{ {
bool isComplexConfig = IsComplexConfig(ConnectionManager->GetConnectionRoot(connectionId));
qrLabel->setVisible(!isComplexConfig);
//
auto shareLink = ConvertConfigToString(connectionId);
//
shareLinkTxt->setText(isComplexConfig ? tr("(Complex Connection Config)") : shareLink);
protocolLabel->setText(isComplexConfig ? tr("N/A") : ConnectionManager->GetConnectionProtocolString(connectionId));
//
groupLabel->setText(ConnectionManager->GetDisplayName(groupId, 175)); groupLabel->setText(ConnectionManager->GetDisplayName(groupId, 175));
protocolLabel->setText(ConnectionManager->GetConnectionProtocolString(connectionId));
auto [protocol, host, port] = ConnectionManager->GetConnectionData(connectionId); auto [protocol, host, port] = ConnectionManager->GetConnectionData(connectionId);
Q_UNUSED(protocol) Q_UNUSED(protocol)
addressLabel->setText(host); addressLabel->setText(host);
portLabel->setNum(port); portLabel->setNum(port);
// //
auto shareLink = ConvertConfigToString(connectionId);
shareLinkTxt->setText(shareLink);
shareLinkTxt->setCursorPosition(0); shareLinkTxt->setCursorPosition(0);
// //
QZXingEncoderConfig conf; QZXingEncoderConfig conf;
@ -145,16 +148,6 @@ void ConnectionInfoWidget::OnDisConnected(const ConnectionId &id)
} }
} }
void ConnectionInfoWidget::on_duplicateBtn_clicked()
{
if (connectionId != NullConnectionId)
{
ConnectionManager->CreateConnection(ConnectionManager->GetDisplayName(connectionId) + tr(" (Copy)"),
ConnectionManager->GetConnectionGroupId(connectionId),
ConnectionManager->GetConnectionRoot(connectionId));
}
}
void ConnectionInfoWidget::on_latencyBtn_clicked() void ConnectionInfoWidget::on_latencyBtn_clicked()
{ {
if (connectionId != NullConnectionId) if (connectionId != NullConnectionId)

View File

@ -20,19 +20,17 @@ class ConnectionInfoWidget
void OnEditRequested(const ConnectionId &id); void OnEditRequested(const ConnectionId &id);
void OnJsonEditRequested(const ConnectionId &id); void OnJsonEditRequested(const ConnectionId &id);
protected:
bool eventFilter(QObject *object, QEvent *event) override;
private slots: private slots:
void on_connectBtn_clicked(); void on_connectBtn_clicked();
void on_editBtn_clicked(); void on_editBtn_clicked();
void on_editJsonBtn_clicked(); void on_editJsonBtn_clicked();
void on_deleteBtn_clicked(); void on_deleteBtn_clicked();
protected:
bool eventFilter(QObject *object, QEvent *event) override;
private slots:
void OnConnected(const ConnectionId &id); void OnConnected(const ConnectionId &id);
void OnDisConnected(const ConnectionId &id); void OnDisConnected(const ConnectionId &id);
void on_duplicateBtn_clicked();
void on_latencyBtn_clicked(); void on_latencyBtn_clicked();
private: private:

View File

@ -58,6 +58,48 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QToolButton" name="connectBtn">
<property name="toolTip">
<string>Connect/Disconnect</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/connect.png</normaloff>:/assets/icons/ui_light/connect.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="editBtn">
<property name="toolTip">
<string>Edit Connection</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/edit.png</normaloff>:/assets/icons/ui_light/edit.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="editJsonBtn">
<property name="toolTip">
<string>Edit Connection as JSON</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/json.png</normaloff>:/assets/icons/ui_light/json.png</iconset>
</property>
</widget>
</item>
<item> <item>
<widget class="QToolButton" name="latencyBtn"> <widget class="QToolButton" name="latencyBtn">
<property name="toolTip"> <property name="toolTip">
@ -86,62 +128,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QToolButton" name="editJsonBtn">
<property name="toolTip">
<string>Edit Connection as JSON</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/json.png</normaloff>:/assets/icons/ui_light/json.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="editBtn">
<property name="toolTip">
<string>Edit Connection</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/edit.png</normaloff>:/assets/icons/ui_light/edit.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="duplicateBtn">
<property name="toolTip">
<string>Duplicate Connection</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/duplicate.png</normaloff>:/assets/icons/ui_light/duplicate.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="connectBtn">
<property name="toolTip">
<string>Connect/Disconnect</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources.qrc">
<normaloff>:/assets/icons/ui_light/connect.png</normaloff>:/assets/icons/ui_light/connect.png</iconset>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -264,7 +250,7 @@
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="shareLinkLabel">
<property name="text"> <property name="text">
<string>Link</string> <string>Link</string>
</property> </property>
@ -323,6 +309,9 @@
<property name="toolTip"> <property name="toolTip">
<string>QR Code</string> <string>QR Code</string>
</property> </property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>