summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Grulich <[email protected]>2017-01-06 12:57:33 +0100
committerJan Grulich <[email protected]>2017-01-06 12:57:33 +0100
commit41899a26fcd40df77fac84bbd639d0e40db2ff74 (patch)
tree7800d992e5af95125b058aa00eabd9cd582f0cd9
parent728e955724175718e51964bbdeff2ad224f01e64 (diff)
Add option to export VPN connections
-rwxr-xr-xkcm/kcm.cpp48
-rwxr-xr-xkcm/kcm.h1
-rw-r--r--kcm/qml/ConnectionItem.qml14
-rwxr-xr-xkcm/qml/main.qml21
-rw-r--r--libs/models/kcmidentitymodel.cpp21
-rw-r--r--libs/models/kcmidentitymodel.h3
6 files changed, 96 insertions, 12 deletions
diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp
index 8638d0f..bf143bf 100755
--- a/kcm/kcm.cpp
+++ b/kcm/kcm.cpp
@@ -24,11 +24,14 @@
#include "connectioneditordialog.h"
#include "mobileconnectionwizard.h"
#include "uiutils.h"
+#include "vpnuiplugin.h"
// KDE
#include <KPluginFactory>
#include <KSharedConfig>
#include <kdeclarative/kdeclarative.h>
+#include <KService>
+#include <KServiceTypeTrader>
#include <NetworkManagerQt/ActiveConnection>
#include <NetworkManagerQt/Connection>
@@ -42,6 +45,7 @@
#include <NetworkManagerQt/WirelessDevice>
// Qt
+#include <QFileDialog>
#include <QMenu>
#include <QQmlContext>
#include <QQmlEngine>
@@ -77,6 +81,7 @@ KCMNetworkmanagement::KCMNetworkmanagement(QWidget *parent, const QVariantList &
QObject *rootItem = m_quickView->rootObject();
connect(rootItem, SIGNAL(selectedConnectionChanged(QString)), this, SLOT(onSelectedConnectionChanged(QString)));
connect(rootItem, SIGNAL(requestCreateConnection(int,QString,QString,bool)), this, SLOT(onRequestCreateConnection(int,QString,QString,bool)));
+ connect(rootItem, SIGNAL(requestExportConnection(QString)), this, SLOT(onRequestExportConnection(QString)));
QVBoxLayout *l = new QVBoxLayout(this);
l->addWidget(mainWidget);
@@ -276,6 +281,49 @@ void KCMNetworkmanagement::onRequestCreateConnection(int connectionType, const Q
}
}
+void KCMNetworkmanagement::onRequestExportConnection(const QString &connectionPath)
+{
+ NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(connectionPath);
+ if (!connection) {
+ return;
+ }
+
+ NetworkManager::ConnectionSettings::Ptr connSettings = connection->settings();
+
+ if (connSettings->connectionType() != NetworkManager::ConnectionSettings::Vpn)
+ return;
+
+ NetworkManager::VpnSetting::Ptr vpnSetting = connSettings->setting(NetworkManager::Setting::Vpn).dynamicCast<NetworkManager::VpnSetting>();
+
+ qCDebug(PLASMA_NM) << "Exporting VPN connection" << connection->name() << "type:" << vpnSetting->serviceType();
+
+ QString error;
+ VpnUiPlugin * vpnPlugin = KServiceTypeTrader::createInstanceFromQuery<VpnUiPlugin>(QStringLiteral("PlasmaNetworkManagement/VpnUiPlugin"),
+ QStringLiteral("[X-NetworkManager-Services]=='%1'").arg(vpnSetting->serviceType()),
+ this, QVariantList(), &error);
+
+ if (vpnPlugin) {
+ if (vpnPlugin->suggestedFileName(connSettings).isEmpty()) { // this VPN doesn't support export
+ qCWarning(PLASMA_NM) << "This VPN doesn't support export";
+ return;
+ }
+
+ const QString url = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QDir::separator() + vpnPlugin->suggestedFileName(connSettings);
+ const QString filename = QFileDialog::getSaveFileName(this, i18n("Export VPN Connection"), url, vpnPlugin->supportedFileExtensions());
+ if (!filename.isEmpty()) {
+ if (!vpnPlugin->exportConnectionSettings(connSettings, filename)) {
+ // TODO display failure
+ qCWarning(PLASMA_NM) << "Failed to export VPN connection";
+ } else {
+ // TODO display success
+ }
+ }
+ delete vpnPlugin;
+ } else {
+ qCWarning(PLASMA_NM) << "Error getting VpnUiPlugin for export:" << error;
+ }
+}
+
void KCMNetworkmanagement::onSelectedConnectionChanged(const QString &connectionPath)
{
if (connectionPath.isEmpty()) {
diff --git a/kcm/kcm.h b/kcm/kcm.h
index d0f2f2d..9fc549a 100755
--- a/kcm/kcm.h
+++ b/kcm/kcm.h
@@ -44,6 +44,7 @@ public Q_SLOTS:
private Q_SLOTS:
void onSelectedConnectionChanged(const QString &connectionPath);
void onRequestCreateConnection(int connectionType, const QString &vpnType, const QString &specificType, bool shared);
+ void onRequestExportConnection(const QString &connectionPath);
private:
void addConnection(const NetworkManager::ConnectionSettings::Ptr &connectionSettings);
diff --git a/kcm/qml/ConnectionItem.qml b/kcm/qml/ConnectionItem.qml
index 6e95880..25741f9 100644
--- a/kcm/qml/ConnectionItem.qml
+++ b/kcm/qml/ConnectionItem.qml
@@ -29,7 +29,8 @@ PlasmaComponents.ListItem {
checked: mouseArea.containsMouse || ConnectionPath === connectionView.currentConnectionPath
height: connectionItemBase.height
- signal aboutToRemove(string name, string path)
+ signal aboutToExportConnection(string path)
+ signal aboutToRemoveConnection(string name, string path)
Item {
id: connectionItemBase
@@ -122,9 +123,17 @@ PlasmaComponents.ListItem {
text: i18n("Delete");
onClicked: {
- aboutToRemove(Name, ConnectionPath)
+ aboutToRemoveConnection(Name, ConnectionPath)
}
}
+
+ PlasmaComponents.MenuItem {
+ icon: "document-export"
+ visible: KcmVpnConnectionExportable
+ text: i18n("Export");
+
+ onClicked: aboutToExportConnection(ConnectionPath)
+ }
}
MouseArea {
@@ -135,6 +144,7 @@ PlasmaComponents.ListItem {
onClicked: {
if (mouse.button === Qt.LeftButton) {
+ connectionView.currentConnectionExportable = KcmVpnConnectionExportable
connectionView.currentConnectionName = Name
connectionView.currentConnectionPath = ConnectionPath
} else if (mouse.button == Qt.RightButton) {
diff --git a/kcm/qml/main.qml b/kcm/qml/main.qml
index 93a685c..aa9003c 100755
--- a/kcm/qml/main.qml
+++ b/kcm/qml/main.qml
@@ -33,6 +33,7 @@ Item {
signal selectedConnectionChanged(string connection)
signal requestCreateConnection(int type, string vpnType, string specificType, bool shared)
+ signal requestExportConnection(string connection)
SystemPalette {
id: palette
@@ -71,7 +72,6 @@ Item {
placeholderText: i18n("Type here to search connections...")
onTextChanged: {
- console.error(text)
editorProxyModel.setFilterRegExp(text)
}
}
@@ -90,6 +90,7 @@ Item {
ListView {
id: connectionView
+ property bool currentConnectionExportable: false
property string currentConnectionName
property string currentConnectionPath
@@ -101,11 +102,15 @@ Item {
section.property: "KcmConnectionType"
section.delegate: Header { text: section }
delegate: ConnectionItem {
- onAboutToRemove: {
+ onAboutToRemoveConnection: {
deleteConfirmationDialog.connectionName = name
deleteConfirmationDialog.connectionPath = path
deleteConfirmationDialog.open()
}
+
+ onAboutToExportConnection: {
+ requestExportConnection(path)
+ }
}
onCurrentConnectionPathChanged: {
@@ -148,6 +153,18 @@ Item {
deleteConfirmationDialog.open()
}
}
+
+ PlasmaComponents.ToolButton {
+ id: exportConnectionButton
+
+ enabled: connectionView.currentConnectionExportable
+ iconSource: "document-export"
+ tooltip: i18n("Export selected connection")
+
+ onClicked: {
+ root.requestExportConnection(connectionView.currentConnectionPath)
+ }
+ }
}
MessageDialog {
diff --git a/libs/models/kcmidentitymodel.cpp b/libs/models/kcmidentitymodel.cpp
index a3e01a3..acf6640 100644
--- a/libs/models/kcmidentitymodel.cpp
+++ b/libs/models/kcmidentitymodel.cpp
@@ -30,10 +30,10 @@
#include <KLocalizedString>
-KcmIdentityModel::KcmIdentityModel(QObject* parent)
+KcmIdentityModel::KcmIdentityModel(QObject *parent)
: QIdentityProxyModel(parent)
{
- NetworkModel * baseModel = new NetworkModel(this);
+ NetworkModel *baseModel = new NetworkModel(this);
setSourceModel(baseModel);
}
@@ -41,13 +41,13 @@ KcmIdentityModel::~KcmIdentityModel()
{
}
-Qt::ItemFlags KcmIdentityModel::flags(const QModelIndex& index) const
+Qt::ItemFlags KcmIdentityModel::flags(const QModelIndex &index) const
{
const QModelIndex mappedProxyIndex = index.sibling(index.row(), 0);
return QIdentityProxyModel::flags(mappedProxyIndex) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
-int KcmIdentityModel::columnCount(const QModelIndex& parent) const
+int KcmIdentityModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
@@ -59,10 +59,12 @@ QHash<int, QByteArray> KcmIdentityModel::roleNames() const
QHash<int, QByteArray> roles = QIdentityProxyModel::roleNames();
roles[KcmConnectionIconRole] = "KcmConnectionIcon";
roles[KcmConnectionTypeRole] = "KcmConnectionType";
+ roles[KcmVpnConnectionExportable] = "KcmVpnConnectionExportable";
+
return roles;
}
-QVariant KcmIdentityModel::data(const QModelIndex& index, int role) const
+QVariant KcmIdentityModel::data(const QModelIndex &index, int role) const
{
const QModelIndex sourceIndex = sourceModel()->index(index.row(), 0);
NetworkManager::ConnectionSettings::ConnectionType type = static_cast<NetworkManager::ConnectionSettings::ConnectionType>(sourceModel()->data(sourceIndex, NetworkModel::TypeRole).toInt());
@@ -86,6 +88,11 @@ QVariant KcmIdentityModel::data(const QModelIndex& index, int role) const
return QString("%1 (%2)").arg(tooltip).arg(vpnSetting->serviceType().section('.', -1));
}
return tooltip;
+ } else if (role == KcmVpnConnectionExportable) {
+ if (type == NetworkManager::ConnectionSettings::Vpn && vpnSetting) {
+ return (vpnSetting->serviceType().endsWith(QLatin1String("vpnc")) || vpnSetting->serviceType().endsWith(QLatin1String("openvpn")));
+ }
+ return false;
} else {
return sourceModel()->data(index, role);
}
@@ -93,13 +100,13 @@ QVariant KcmIdentityModel::data(const QModelIndex& index, int role) const
return QVariant();
}
-QModelIndex KcmIdentityModel::index(int row, int column, const QModelIndex& parent) const
+QModelIndex KcmIdentityModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent);
return createIndex(row, column);
}
-QModelIndex KcmIdentityModel::mapToSource(const QModelIndex& proxyIndex) const
+QModelIndex KcmIdentityModel::mapToSource(const QModelIndex &proxyIndex) const
{
if (proxyIndex.column() > 0) {
return QModelIndex();
diff --git a/libs/models/kcmidentitymodel.h b/libs/models/kcmidentitymodel.h
index 6ec0a43..061fe6f 100644
--- a/libs/models/kcmidentitymodel.h
+++ b/libs/models/kcmidentitymodel.h
@@ -33,7 +33,8 @@ public:
enum KcmItemRole {
KcmConnectionIconRole = Qt::UserRole + 100,
- KcmConnectionTypeRole
+ KcmConnectionTypeRole,
+ KcmVpnConnectionExportable
};
QHash< int, QByteArray > roleNames() const Q_DECL_OVERRIDE;