Skip to content
This repository was archived by the owner on Apr 28, 2022. It is now read-only.

Commit aff8fe1

Browse files
committed
[nemo-qml-plugin-systemsettings] Support VPN ordering by connected status. Contributes to JB#45380
This change adds the `orderByConnected` flag to VpnModel which, when set, will order VPN connections in the model first by the connection status (connected first, followed by not connected), then by the name alphabetially ascending (case-sensitive). When not set, the previous case-sensitive alphabetic name ordering is used. The new ordering is used when the MDM policy is set to prevent the user from manually connecting or disconnecting the VPNs. In this case, the list of VPNs is presented differently with headers indicating connection status, rather than indicating it using a TextSwitch glassitem.
1 parent 72f3ec0 commit aff8fe1

File tree

2 files changed

+71
-16
lines changed

2 files changed

+71
-16
lines changed

src/vpnmodel.cpp

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ VpnModel::VpnModel(QObject *parent)
320320
, provisioningOutputPath_(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/system/privileged/vpn-provisioning"))
321321
, bestState_(VpnModel::Idle)
322322
, autoConnect_(false)
323+
, orderByConnected_(false)
323324
{
324325
qDBusRegisterMetaType<PathProperties>();
325326
qDBusRegisterMetaType<PathPropertiesArray>();
@@ -400,6 +401,30 @@ bool VpnModel::autoConnect() const
400401
return autoConnect_;
401402
}
402403

404+
bool VpnModel::orderByConnected() const
405+
{
406+
return orderByConnected_;
407+
}
408+
409+
void VpnModel::setOrderByConnected(bool orderByConnected)
410+
{
411+
if (orderByConnected != orderByConnected_) {
412+
orderByConnected_ = orderByConnected;
413+
414+
// Update the ordering; only the connected connections need to move
415+
// In practice only one VPN can be connected, so full sort is overkill
416+
const int itemCount(count());
417+
for (int index = 0; index < itemCount; ++index) {
418+
VpnConnection *conn = get<VpnConnection>(index);
419+
if (conn->connected()) {
420+
reorderConnection(conn);
421+
}
422+
}
423+
424+
emit orderByConnectedChanged();
425+
}
426+
}
427+
403428
void VpnModel::createConnection(const QVariantMap &createProperties)
404429
{
405430
const QString path(createProperties.value(QString("path")).toString());
@@ -851,6 +876,7 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
851876
}
852877

853878
int oldState(conn->state());
879+
bool connectionChanged = false;
854880

855881
if (updateItem(conn, properties)) {
856882
itemChanged(conn);
@@ -859,6 +885,10 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
859885

860886
if (conn->state() != oldState) {
861887
emit connectionStateChanged(conn->path(), static_cast<int>(conn->state()));
888+
if ((conn->state() == VpnModel::Ready) != (oldState == VpnModel::Ready)) {
889+
emit conn->connectedChanged();
890+
connectionChanged = true;
891+
}
862892

863893
// Check to see if the best state has changed
864894
ConnectionState maxState = Idle;
@@ -874,23 +904,14 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
874904
}
875905
}
876906

877-
878-
// Keep the items sorted by name. So sort only when updateProperties map contains
879-
// a name e.i. not when "autoConnect" changes. In practice this means that sorting
880-
// is only allowed when a VPN is created. When modifying name of a VPN, the VPN
907+
// Keep the items sorted by name and possibly connected status. So sort
908+
// only when the connection status has changed, or the updateProperties
909+
// map contains a name i.e. not when "autoConnect" changes. In practice
910+
// this means that if orderByConnected_ is false then sorting is only
911+
// allowed when a VPN is created. When modifying name of a VPN, the VPN
881912
// will be first removed and then recreated.
882-
if (itemCount > 1 && updateProperties.contains(QStringLiteral("name"))) {
883-
int index = 0;
884-
for ( ; index < itemCount; ++index) {
885-
const VpnConnection *existing = get<VpnConnection>(index);
886-
if (existing->name() > conn->name()) {
887-
break;
888-
}
889-
}
890-
const int currentIndex = indexOf(conn);
891-
if (index != currentIndex && (index - 1) != currentIndex) {
892-
moveItem(currentIndex, (currentIndex < index ? (index - 1) : index));
893-
}
913+
if (updateProperties.contains(QStringLiteral("name")) || (orderByConnected_ && connectionChanged)) {
914+
reorderConnection(conn);
894915
}
895916
}
896917

@@ -905,6 +926,29 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
905926
}
906927
}
907928

929+
void VpnModel::reorderConnection(VpnConnection * conn)
930+
{
931+
const int itemCount(count());
932+
933+
if (itemCount > 1) {
934+
int index = 0;
935+
for ( ; index < itemCount; ++index) {
936+
const VpnConnection *existing = get<VpnConnection>(index);
937+
// Scenario 1 orderByConnected == true: order first by connected, second by name
938+
// Scenario 2 orderByConnected == false: order only by name
939+
if ((orderByConnected_ && (existing->connected() < conn->connected()))
940+
|| ((!orderByConnected_ || (existing->connected() == conn->connected()))
941+
&& (existing->name() > conn->name()))) {
942+
break;
943+
}
944+
}
945+
const int currentIndex = indexOf(conn);
946+
if (index != currentIndex && (index - 1) != currentIndex) {
947+
moveItem(currentIndex, (currentIndex < index ? (index - 1) : index));
948+
}
949+
}
950+
}
951+
908952
QVariantMap VpnModel::processOpenVpnProvisioningFile(QFile &provisioningFile)
909953
{
910954
QVariantMap rv;

src/vpnmodel.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class SYSTEMSETTINGS_EXPORT VpnModel : public ObjectListModel
5252

5353
Q_PROPERTY(int bestState READ bestState NOTIFY bestStateChanged)
5454
Q_PROPERTY(bool autoConnect READ autoConnect NOTIFY autoConnectChanged)
55+
Q_PROPERTY(bool orderByConnected READ orderByConnected WRITE setOrderByConnected NOTIFY orderByConnectedChanged)
5556

5657
public:
5758
enum ConnectionState {
@@ -69,6 +70,9 @@ class SYSTEMSETTINGS_EXPORT VpnModel : public ObjectListModel
6970
int bestState() const;
7071
bool autoConnect() const;
7172

73+
bool orderByConnected() const;
74+
void setOrderByConnected(bool orderByConnected);
75+
7276
Q_INVOKABLE void createConnection(const QVariantMap &properties);
7377
Q_INVOKABLE void modifyConnection(const QString &path, const QVariantMap &properties);
7478
Q_INVOKABLE void deleteConnection(const QString &path);
@@ -92,6 +96,7 @@ class SYSTEMSETTINGS_EXPORT VpnModel : public ObjectListModel
9296
void bestStateChanged();
9397
void autoConnectChanged();
9498
void connectionStateChanged(const QString &path, int state);
99+
void orderByConnectedChanged();
95100

96101
private:
97102
void fetchVpnList();
@@ -104,6 +109,7 @@ class SYSTEMSETTINGS_EXPORT VpnModel : public ObjectListModel
104109
bool domainInUse(const QString &domain) const;
105110
QString createDefaultDomain() const;
106111
bool isDefaultDomain(const QString &domain) const;
112+
void reorderConnection(VpnConnection * conn);
107113

108114
class CredentialsRepository
109115
{
@@ -135,6 +141,7 @@ class SYSTEMSETTINGS_EXPORT VpnModel : public ObjectListModel
135141
ConnectionState bestState_;
136142
// True if there's one VPN that has autoConnect true
137143
bool autoConnect_;
144+
bool orderByConnected_;
138145
};
139146

140147
class SYSTEMSETTINGS_EXPORT VpnConnection : public QObject
@@ -157,6 +164,7 @@ class SYSTEMSETTINGS_EXPORT VpnConnection : public QObject
157164
Q_PROPERTY(QVariantList userRoutes READ userRoutes WRITE setUserRoutes NOTIFY userRoutesChanged)
158165
Q_PROPERTY(QVariantList serverRoutes READ serverRoutes WRITE setServerRoutes NOTIFY serverRoutesChanged)
159166
Q_PROPERTY(QVariantMap providerProperties READ providerProperties WRITE setProviderProperties NOTIFY providerPropertiesChanged)
167+
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
160168

161169
public:
162170
VpnConnection(const QString &path);
@@ -211,6 +219,8 @@ class SYSTEMSETTINGS_EXPORT VpnConnection : public QObject
211219
QVariantMap providerProperties() const { return providerProperties_; }
212220
void setProviderProperties(const QVariantMap providerProperties) { updateMember(&VpnConnection::providerProperties_, providerProperties, &VpnConnection::providerPropertiesChanged); }
213221

222+
int connected() const { return state_ == VpnModel::Ready; }
223+
214224
signals:
215225
void nameChanged();
216226
void stateChanged();
@@ -228,6 +238,7 @@ class SYSTEMSETTINGS_EXPORT VpnConnection : public QObject
228238
void userRoutesChanged();
229239
void serverRoutesChanged();
230240
void providerPropertiesChanged();
241+
void connectedChanged();
231242

232243
private:
233244
template<typename T, typename V>

0 commit comments

Comments
 (0)