vpn-connections-list-model.cpp
connectivityqt/internal/vpn-connection-list-model-parameters.h
connectivityqt/openvpn-connection.h
connectivityqt/pptp-connection.h
connectivityqt/vpn-connections-list-model.h
VpnConnectionInterface.h
dbus-types.h
QDBusArgument
QDBusObjectPath
QDebug
QList
vpn-connections-list-model.moc
connectivityqt/openvpn-connection.h
connectivityqt/pptp-connection.h
connectivityqt/vpn-connection.h
vpn-connections-list-model.cpp
connectivityqt/vpn-connections-list-model.h
QAbstractItemModel
QDBusArgument
QDBusConnection
QDBusObjectPath
QDebug
QList
QObject
VpnConnectionInterface.h
connectivityqt/internal/vpn-connection-list-model-parameters.h
dbus-types.h
lomiri/util/DefinesPtrs.h
vpn-connections-list-model.moc
connectivityqt

    /*
    *Copyright©2014CanonicalLtd.
    *
    *Thisprogramisfreesoftware:youcanredistributeitand/ormodifyit
    *underthetermsoftheGNULesserGeneralPublicLicenseversion3,
    *aspublishedbytheFreeSoftwareFoundation.
    *
    *Thisprogramisdistributedinthehopethatitwillbeuseful,
    *butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
    *MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
    *GNULesserGeneralPublicLicenseformoredetails.
    *
    *YoushouldhavereceivedacopyoftheGNULesserGeneralPublicLicense
    *alongwiththisprogram.Ifnot,see<http://www.gnu.org/licenses/>.
    *
    *Authors:
    *PeteWoods<pete.woods@canonical.com>
    */

    #include<connectivityqt/internal/vpn-connection-list-model-parameters.h>
    #include<connectivityqt/openvpn-connection.h>
    #include<connectivityqt/pptp-connection.h>
    #include<connectivityqt/vpn-connections-list-model.h>

    #include<VpnConnectionInterface.h>
    #include<dbus-types.h>

    #include<QDBusArgument>
    #include<QDBusObjectPath>
    #include<QDebug>
    #include<QList>

    usingnamespacestd;

    namespaceconnectivityqt
    {

    usingnamespaceinternal;

    classVpnConnectionsListModel::Priv:publicQObject
    {
    Q_OBJECT

    public:
    Priv(VpnConnectionsListModel&parent):
    p(parent)
    {
    }

    voidupdatePaths(constQVariant&value)
    {
    QList<QDBusObjectPath>tmp;
    qvariant_cast<QDBusArgument>(value)>>tmp;
    #ifQT_VERSION<QT_VERSION_CHECK(5,15,0)
    autopaths=tmp.toSet();
    #else
    autopaths=QSet<QDBusObjectPath>(tmp.begin(),tmp.end());
    #endif

    QSet<QDBusObjectPath>current;
    for(constauto&connection:m_vpnConnections)
    {
    current<<connection->path();
    }

    autotoRemove(current);
    toRemove.subtract(paths);

    autotoAdd(paths);
    toAdd.subtract(current);

    QMutableListIterator<VpnConnection::SPtr>i(m_vpnConnections);
    intidx=0;
    while(i.hasNext())
    {
    autovpnConnection(i.next());
    if(toRemove.contains(vpnConnection->path()))
    {
    p.beginRemoveRows(QModelIndex(),idx,idx);
    i.remove();
    p.endRemoveRows();
    }
    else
    {
    ++idx;
    }
    }

    if(!toAdd.isEmpty())
    {
    p.beginInsertRows(QModelIndex(),m_vpnConnections.size(),m_vpnConnections.size()+toAdd.size()-1);
    for(constauto&path:toAdd)
    {
    ComLomiriConnectivity1VpnVpnConnectionInterfacevpnInterface(
    DBusTypes::DBUS_NAME,path.path(),m_propertyCache->connection());

    VpnConnection::SPtrvpnConnection;
    switch(vpnInterface.type())
    {
    caseVpnConnection::Type::OPENVPN:
    vpnConnection.reset(newOpenvpnConnection(path,m_propertyCache->connection()),
    [](QObject*self){self->deleteLater();});
    break;
    default:
    vpnConnection.reset(newPptpConnection(path,m_propertyCache->connection()),
    [](QObject*self){self->deleteLater();});
    break;
    }
    if(vpnConnection)
    {
    m_objectOwner(vpnConnection.get());
    m_vpnConnections<<vpnConnection;
    connect(vpnConnection.get(),&VpnConnection::idChanged,this,&Priv::connectionIdChanged);
    connect(vpnConnection.get(),&VpnConnection::activeChanged,this,&Priv::connectionActiveChanged);
    connect(vpnConnection.get(),&VpnConnection::activatableChanged,this,&Priv::connectionActivatableChanged);
    connect(vpnConnection.get(),&VpnConnection::remove,this,&Priv::removeRequested);
    }
    }
    p.endInsertRows();
    }
    }

    QModelIndexfindVpnConnection(QObject*o)
    {
    autovpnConnection=qobject_cast<VpnConnection*>(o);
    for(autoi=m_vpnConnections.constBegin();i!=m_vpnConnections.constEnd();++i)
    {
    if(i->get()==vpnConnection)
    {
    returnp.index(std::distance(m_vpnConnections.constBegin(),i));
    }
    }
    returnQModelIndex();
    }

    voidremove(constVpnConnection&connection)
    {
    autoreply=m_writeInterface->RemoveVpnConnection(connection.path());
    autowatcher(newQDBusPendingCallWatcher(reply,this));
    connect(watcher,&QDBusPendingCallWatcher::finished,this,&Priv::removeConnectionFinished);
    }

    publicQ_SLOTS:
    voidconnectionIdChanged(constQString&)
    {
    autoidx=findVpnConnection(sender());
    p.dataChanged(idx,idx,{VpnConnectionsListModel::Roles::RoleId});
    }

    voidconnectionActiveChanged(bool)
    {
    autoidx=findVpnConnection(sender());
    p.dataChanged(idx,idx,{VpnConnectionsListModel::Roles::RoleActive});
    }

    voidconnectionActivatableChanged(bool)
    {
    autoidx=findVpnConnection(sender());
    p.dataChanged(idx,idx,{VpnConnectionsListModel::Roles::RoleActivatable});
    }

    voidpropertyChanged(constQString&name,constQVariant&value)
    {
    if(name=="VpnConnections")
    {
    updatePaths(value);
    }
    }

    voidaddConnectionFinished(QDBusPendingCallWatcher*call)
    {
    QDBusPendingReply<QDBusObjectPath>reply=*call;
    if(reply.isError())
    {
    qWarning()<<__PRETTY_FUNCTION__<<reply.error().message();
    }
    else
    {
    QDBusObjectPathpath(reply);
    VpnConnection::SPtrconnection;
    for(constauto&tmp:m_vpnConnections)
    {
    if(tmp->path()==path)
    {
    connection=tmp;
    break;
    }
    }
    if(connection)
    {
    Q_EMITp.addFinished(connection.get());
    }
    else
    {
    qWarning()<<__PRETTY_FUNCTION__<<"Newconnectionwithpath:"<<path.path()<<"couldnotbefound";
    }
    }
    call->deleteLater();
    }

    voidremoveConnectionFinished(QDBusPendingCallWatcher*call)
    {
    QDBusPendingReply<>reply=*call;
    if(reply.isError())
    {
    qWarning()<<__PRETTY_FUNCTION__<<reply.error().message();
    }
    call->deleteLater();
    }

    voidremoveRequested()
    {
    autoconnection=qobject_cast<VpnConnection*>(sender());
    if(connection)
    {
    remove(*connection);
    }
    }

    public:
    VpnConnectionsListModel&p;

    function<void(QObject*)>m_objectOwner;

    shared_ptr<ComLomiriConnectivity1PrivateInterface>m_writeInterface;

    util::DBusPropertyCache::SPtrm_propertyCache;

    QList<VpnConnection::SPtr>m_vpnConnections;
    };

    VpnConnectionsListModel::VpnConnectionsListModel(constinternal::VpnConnectionsListModelParameters&parameters):
    d(newPriv(*this))
    {
    d->m_objectOwner=parameters.objectOwner;
    d->m_writeInterface=parameters.writeInterface;
    d->m_propertyCache=parameters.propertyCache;
    d->updatePaths(d->m_propertyCache->get("VpnConnections"));
    connect(d->m_propertyCache.get(),&util::DBusPropertyCache::propertyChanged,d.get(),&Priv::propertyChanged);
    }

    VpnConnectionsListModel::~VpnConnectionsListModel()
    {
    }

    intVpnConnectionsListModel::columnCount(constQModelIndex&)const
    {
    return1;
    }

    intVpnConnectionsListModel::rowCount(constQModelIndex&)const
    {
    returnd->m_vpnConnections.size();
    }

    QVariantVpnConnectionsListModel::data(constQModelIndex&index,introle)const
    {
    introw(index.row());
    if(row<0||row>=d->m_vpnConnections.size())
    {
    returnQVariant();
    }

    autovpnConnection=d->m_vpnConnections.value(row);

    switch(role)
    {
    caseRoles::RoleId:
    returnvpnConnection->id();
    break;
    caseRoles::RoleActive:
    returnvpnConnection->active();
    break;
    caseRoles::RoleActivatable:
    returnvpnConnection->activatable();
    break;
    caseRoles::RoleType:
    returnstatic_cast<int>(vpnConnection->type());
    break;
    caseRoles::RoleConnection:
    returnQVariant::fromValue(qobject_cast<QObject*>(vpnConnection.get()));
    break;
    default:
    break;
    }

    returnQVariant();
    }

    boolVpnConnectionsListModel::setData(constQModelIndex&index,constQVariant&value,introle)
    {
    introw(index.row());
    if(row<0||row>=d->m_vpnConnections.size())
    {
    returnfalse;
    }

    autovpnConnection=d->m_vpnConnections.value(row);

    switch(role)
    {
    caseRoles::RoleId:
    vpnConnection->setId(value.toString());
    break;
    caseRoles::RoleActive:
    vpnConnection->setActive(value.toBool());
    break;
    default:
    returnfalse;
    returntrue;
    }

    returnfalse;
    }

    Qt::ItemFlagsVpnConnectionsListModel::flags(constQModelIndex&index)const
    {
    introw(index.row());
    if(row<0||row>=d->m_vpnConnections.size())
    {
    returnQt::NoItemFlags;
    }

    returnQAbstractItemModel::flags(index)|Qt::ItemIsEditable;
    }

    voidVpnConnectionsListModel::add(VpnConnection::Typetype)
    {
    autoreply=d->m_writeInterface->AddVpnConnection(static_cast<int>(type));
    autowatcher(newQDBusPendingCallWatcher(reply,this));
    connect(watcher,&QDBusPendingCallWatcher::finished,d.get(),&Priv::addConnectionFinished);
    }

    voidVpnConnectionsListModel::importFile(VpnConnection::Typetype,constQString&filepath)
    {
    autoreply=d->m_writeInterface->ImportVpnConnection(static_cast<int>(type),filepath);
    autowatcher(newQDBusPendingCallWatcher(reply,this));
    connect(watcher,&QDBusPendingCallWatcher::finished,d.get(),&Priv::addConnectionFinished);
    }

    voidVpnConnectionsListModel::remove(VpnConnection*connection)
    {
    d->remove(*connection);
    }

    }

    #include"vpn-connections-list-model.moc"