Commit 5ea99863 authored by flypig's avatar flypig

Merge branch 'jb45380_textswitch' into 'master'

Support VPN ordering by connected status

See merge request !106
parents 72f3ec0e aff8fe1a
......@@ -320,6 +320,7 @@ VpnModel::VpnModel(QObject *parent)
, provisioningOutputPath_(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/system/privileged/vpn-provisioning"))
, bestState_(VpnModel::Idle)
, autoConnect_(false)
, orderByConnected_(false)
{
qDBusRegisterMetaType<PathProperties>();
qDBusRegisterMetaType<PathPropertiesArray>();
......@@ -400,6 +401,30 @@ bool VpnModel::autoConnect() const
return autoConnect_;
}
bool VpnModel::orderByConnected() const
{
return orderByConnected_;
}
void VpnModel::setOrderByConnected(bool orderByConnected)
{
if (orderByConnected != orderByConnected_) {
orderByConnected_ = orderByConnected;
// Update the ordering; only the connected connections need to move
// In practice only one VPN can be connected, so full sort is overkill
const int itemCount(count());
for (int index = 0; index < itemCount; ++index) {
VpnConnection *conn = get<VpnConnection>(index);
if (conn->connected()) {
reorderConnection(conn);
}
}
emit orderByConnectedChanged();
}
}
void VpnModel::createConnection(const QVariantMap &createProperties)
{
const QString path(createProperties.value(QString("path")).toString());
......@@ -851,6 +876,7 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
}
int oldState(conn->state());
bool connectionChanged = false;
if (updateItem(conn, properties)) {
itemChanged(conn);
......@@ -859,6 +885,10 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
if (conn->state() != oldState) {
emit connectionStateChanged(conn->path(), static_cast<int>(conn->state()));
if ((conn->state() == VpnModel::Ready) != (oldState == VpnModel::Ready)) {
emit conn->connectedChanged();
connectionChanged = true;
}
// Check to see if the best state has changed
ConnectionState maxState = Idle;
......@@ -874,23 +904,14 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
}
}
// Keep the items sorted by name. So sort only when updateProperties map contains
// a name e.i. not when "autoConnect" changes. In practice this means that sorting
// is only allowed when a VPN is created. When modifying name of a VPN, the VPN
// Keep the items sorted by name and possibly connected status. So sort
// only when the connection status has changed, or the updateProperties
// map contains a name i.e. not when "autoConnect" changes. In practice
// this means that if orderByConnected_ is false then sorting is only
// allowed when a VPN is created. When modifying name of a VPN, the VPN
// will be first removed and then recreated.
if (itemCount > 1 && updateProperties.contains(QStringLiteral("name"))) {
int index = 0;
for ( ; index < itemCount; ++index) {
const VpnConnection *existing = get<VpnConnection>(index);
if (existing->name() > conn->name()) {
break;
}
}
const int currentIndex = indexOf(conn);
if (index != currentIndex && (index - 1) != currentIndex) {
moveItem(currentIndex, (currentIndex < index ? (index - 1) : index));
}
if (updateProperties.contains(QStringLiteral("name")) || (orderByConnected_ && connectionChanged)) {
reorderConnection(conn);
}
}
......@@ -905,6 +926,29 @@ void VpnModel::updateConnection(VpnConnection *conn, const QVariantMap &updatePr
}
}
void VpnModel::reorderConnection(VpnConnection * conn)
{
const int itemCount(count());
if (itemCount > 1) {
int index = 0;
for ( ; index < itemCount; ++index) {
const VpnConnection *existing = get<VpnConnection>(index);
// Scenario 1 orderByConnected == true: order first by connected, second by name
// Scenario 2 orderByConnected == false: order only by name
if ((orderByConnected_ && (existing->connected() < conn->connected()))
|| ((!orderByConnected_ || (existing->connected() == conn->connected()))
&& (existing->name() > conn->name()))) {
break;
}
}
const int currentIndex = indexOf(conn);
if (index != currentIndex && (index - 1) != currentIndex) {
moveItem(currentIndex, (currentIndex < index ? (index - 1) : index));
}
}
}
QVariantMap VpnModel::processOpenVpnProvisioningFile(QFile &provisioningFile)
{
QVariantMap rv;
......
......@@ -52,6 +52,7 @@ class SYSTEMSETTINGS_EXPORT VpnModel : public ObjectListModel
Q_PROPERTY(int bestState READ bestState NOTIFY bestStateChanged)
Q_PROPERTY(bool autoConnect READ autoConnect NOTIFY autoConnectChanged)
Q_PROPERTY(bool orderByConnected READ orderByConnected WRITE setOrderByConnected NOTIFY orderByConnectedChanged)
public:
enum ConnectionState {
......@@ -69,6 +70,9 @@ public:
int bestState() const;
bool autoConnect() const;
bool orderByConnected() const;
void setOrderByConnected(bool orderByConnected);
Q_INVOKABLE void createConnection(const QVariantMap &properties);
Q_INVOKABLE void modifyConnection(const QString &path, const QVariantMap &properties);
Q_INVOKABLE void deleteConnection(const QString &path);
......@@ -92,6 +96,7 @@ signals:
void bestStateChanged();
void autoConnectChanged();
void connectionStateChanged(const QString &path, int state);
void orderByConnectedChanged();
private:
void fetchVpnList();
......@@ -104,6 +109,7 @@ private:
bool domainInUse(const QString &domain) const;
QString createDefaultDomain() const;
bool isDefaultDomain(const QString &domain) const;
void reorderConnection(VpnConnection * conn);
class CredentialsRepository
{
......@@ -135,6 +141,7 @@ private:
ConnectionState bestState_;
// True if there's one VPN that has autoConnect true
bool autoConnect_;
bool orderByConnected_;
};
class SYSTEMSETTINGS_EXPORT VpnConnection : public QObject
......@@ -157,6 +164,7 @@ class SYSTEMSETTINGS_EXPORT VpnConnection : public QObject
Q_PROPERTY(QVariantList userRoutes READ userRoutes WRITE setUserRoutes NOTIFY userRoutesChanged)
Q_PROPERTY(QVariantList serverRoutes READ serverRoutes WRITE setServerRoutes NOTIFY serverRoutesChanged)
Q_PROPERTY(QVariantMap providerProperties READ providerProperties WRITE setProviderProperties NOTIFY providerPropertiesChanged)
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
public:
VpnConnection(const QString &path);
......@@ -211,6 +219,8 @@ public:
QVariantMap providerProperties() const { return providerProperties_; }
void setProviderProperties(const QVariantMap providerProperties) { updateMember(&VpnConnection::providerProperties_, providerProperties, &VpnConnection::providerPropertiesChanged); }
int connected() const { return state_ == VpnModel::Ready; }
signals:
void nameChanged();
void stateChanged();
......@@ -228,6 +238,7 @@ signals:
void userRoutesChanged();
void serverRoutesChanged();
void providerPropertiesChanged();
void connectedChanged();
private:
template<typename T, typename V>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment