diff --git a/IconButton.cxx b/IconButton.cxx
index ba41bb6..5728cb8 100644
--- a/IconButton.cxx
+++ b/IconButton.cxx
@@ -1,79 +1,93 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
- Copyright 2018 Martin Koller, kollix@aon.at
+ Copyright 2018 - 2020 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#include
#include
//--------------------------------------------------------------------------------
IconButton::IconButton(QWidget *parent)
: QToolButton(parent)
{
setAutoRaise(true);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
QHBoxLayout *hbox = new QHBoxLayout(this);
iconLabel = new QLabel;
iconLabel->setFixedSize(iconSize());
iconLabel->setContextMenuPolicy(Qt::PreventContextMenu);
hbox->addWidget(iconLabel);
+ icon2Label = new QLabel;
+ icon2Label->setFixedSize(iconSize());
+ icon2Label->setContextMenuPolicy(Qt::PreventContextMenu);
+ icon2Label->hide(); // until an icon is set
+ hbox->addWidget(icon2Label);
+
textLabel = new QLabel;
hbox->addWidget(textLabel);
}
//--------------------------------------------------------------------------------
IconButton::IconButton(QWidget *parent, const QIcon &icon, int theIconSize, const QString &name)
: IconButton(parent)
{
if ( theIconSize != -1 )
setIconSize(QSize(theIconSize, theIconSize));
iconLabel->setFixedSize(iconSize());
iconLabel->setPixmap(icon.pixmap(iconSize()));
textLabel->setText(name);
}
//--------------------------------------------------------------------------------
void IconButton::setText(const QString &txt)
{
textLabel->setText(txt);
}
//--------------------------------------------------------------------------------
void IconButton::setIcon(const QIcon &icon)
{
iconLabel->setPixmap(icon.pixmap(iconSize()));
}
//--------------------------------------------------------------------------------
+void IconButton::setIcon2(const QIcon &icon)
+{
+ icon2Label->setPixmap(icon.pixmap(iconSize()));
+ icon2Label->show();
+}
+
+//--------------------------------------------------------------------------------
+
QSize IconButton::sizeHint() const
{
return layout()->sizeHint();
}
//--------------------------------------------------------------------------------
diff --git a/IconButton.hxx b/IconButton.hxx
index d5ec43b..f72dbd8 100644
--- a/IconButton.hxx
+++ b/IconButton.hxx
@@ -1,47 +1,49 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
- Copyright 2018 Martin Koller, kollix@aon.at
+ Copyright 2018 - 2020 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#ifndef _IconButton_H_
#define _IconButton_H_
#include
#include
// button class to ensure the positioning of the icon and text independent of the style
class IconButton : public QToolButton
{
Q_OBJECT
public:
IconButton(QWidget *parent = nullptr);
IconButton(QWidget *parent, const QIcon &icon, int iconSize, const QString &name);
void setText(const QString &txt);
void setIcon(const QIcon &icon);
+ void setIcon2(const QIcon &icon);
QSize sizeHint() const override;
private:
QLabel *iconLabel = nullptr;
+ QLabel *icon2Label = nullptr;
QLabel *textLabel = nullptr;
};
#endif
diff --git a/NetworkList.cxx b/NetworkList.cxx
index 6d61590..cc07171 100644
--- a/NetworkList.cxx
+++ b/NetworkList.cxx
@@ -1,366 +1,424 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
- Copyright 2017 - 2019 Martin Koller, kollix@aon.at
+ Copyright 2017 - 2020 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#include
+#include
+
//--------------------------------------------------------------------------------
-NetworkButton::NetworkButton(NetworkManager::Connection::Ptr c, NetworkManager::Device::Ptr dev)
+NetworkButton::NetworkButton(NetworkManager::Connection::Ptr c, NetworkManager::Device::Ptr dev,
+ NetworkManager::AccessPoint::Ptr accessPoint)
: connection(c), device(dev)
{
setCheckable(true);
if ( connection )
{
for (const NetworkManager::ActiveConnection::Ptr &ac : NetworkManager::activeConnections())
{
if ( ac->uuid() == c->uuid() )
{
setChecked(true);
break;
}
}
-
- connect(this, &NetworkButton::toggled, this, &NetworkButton::toggleNetworkStatus);
}
- else
- setEnabled(false);
+ else if ( accessPoint )
+ {
+ ssid = accessPoint->ssid();
+ rawSsid = accessPoint->rawSsid();
+ wpaFlags = accessPoint->wpaFlags();
+ }
+
+ connect(this, &NetworkButton::toggled, this, &NetworkButton::toggleNetworkStatus);
}
//--------------------------------------------------------------------------------
void NetworkButton::toggleNetworkStatus(bool on)
{
if ( on )
{
+ if ( !connection ) // no connection yet -> create one
+ {
+ // the connMap content was "reverse-engineered" by using qdbusviewer and the result of getting
+ // GetSettings of one of theSettings.Connection elements
+
+ NMVariantMapMap connMap;
+ QVariantMap map;
+ map.insert("id", ssid);
+
+ // ensure to not need root password by creating only for the current user
+ struct passwd *pwd = getpwuid(geteuid());
+ if ( pwd )
+ map.insert("permissions", QStringList(QString("user:") + QString::fromUtf8(pwd->pw_name)));
+
+ connMap.insert("connection", map);
+
+ QVariantMap wirelessMap;
+ wirelessMap.insert("ssid", rawSsid);
+
+ if ( wpaFlags )
+ {
+ wirelessMap.insert("security", "802-11-wireless-security");
+
+ QVariantMap security;
+ if ( wpaFlags & NetworkManager::AccessPoint::KeyMgmtPsk )
+ security.insert("key-mgmt", QString("wpa-psk"));
+ else if ( wpaFlags & NetworkManager::AccessPoint::KeyMgmtSAE )
+ security.insert("key-mgmt", QString("sae"));
+ else
+ {
+ // TODO: other types - find value names
+ }
+
+ connMap.insert("802-11-wireless-security", security);
+ }
+
+ connMap.insert("802-11-wireless", wirelessMap);
+
+ QDBusPendingReply call =
+ NetworkManager::addAndActivateConnection(connMap, device->uni(), QString());
+
+ /*
+ QDBusPendingCallWatcher *pendingCallWatcher = new QDBusPendingCallWatcher(call, this);
+ connect(pendingCallWatcher, &QDBusPendingCallWatcher::finished, this,
+ [this](QDBusPendingCallWatcher *w)
+ {
+ w->deleteLater();
+ QDBusPendingReply reply = *w;
+ qDebug() << reply.error();
+ }
+ );
+ */
+
+ // without closing our popup, the user can not enter the password in the password dialog which appears
+ window()->close();
+
+ return;
+ }
+
switch ( connection->settings()->connectionType() )
{
case NetworkManager::ConnectionSettings::Wired:
{
NetworkManager::activateConnection(connection->path(), connection->settings()->interfaceName(), QString());
break;
}
case NetworkManager::ConnectionSettings::Wireless:
{
NetworkManager::activateConnection(connection->path(), device->uni(), QString());
break;
}
case NetworkManager::ConnectionSettings::Vpn:
{
NetworkManager::ActiveConnection::Ptr conn(NetworkManager::primaryConnection());
if ( conn && !conn->devices().isEmpty() )
NetworkManager::activateConnection(connection->path(), conn->devices()[0], QString());
break;
}
default: ; // TODO
}
}
- else
+ else if ( connection )
{
for (const NetworkManager::ActiveConnection::Ptr &ac : NetworkManager::activeConnections())
{
if ( ac->uuid() == connection->uuid() )
{
NetworkManager::deactivateConnection(ac->path());
break;
}
}
}
}
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
NetworkList::NetworkList(QWidget *parent)
: QFrame(parent)
{
setWindowFlags(windowFlags() | Qt::Popup);
setFrameShape(QFrame::StyledPanel);
QVBoxLayout *vbox = new QVBoxLayout(this);
hbox = new QHBoxLayout;
vbox->addLayout(hbox);
network = new QToolButton;
network->setIcon(QIcon::fromTheme("network-wired"));
network->setToolTip(i18n("Enable Networking"));
network->setCheckable(true);
connect(network, &QToolButton::clicked, [](bool on) { NetworkManager::setNetworkingEnabled(on); });
connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &NetworkList::statusUpdate);
hbox->addWidget(network);
wireless = new QToolButton;
wireless->setIcon(QIcon::fromTheme("network-wireless"));
wireless->setToolTip(i18n("Enable Wireless Networking"));
wireless->setCheckable(true);
connect(wireless, &QToolButton::clicked, [](bool on) { NetworkManager::setWirelessEnabled(on); });
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &NetworkList::statusUpdate);
hbox->addWidget(wireless);
statusUpdate();
hbox->addStretch();
QToolButton *configure = new QToolButton;
configure->setIcon(QIcon::fromTheme("configure"));
configure->setToolTip(i18n("Configure Network Connections"));
connect(configure, &QToolButton::clicked, this, &NetworkList::openConfigureDialog);
hbox->addWidget(configure);
// show connections
QWidget *widget = new QWidget;
connectionsVbox = new QVBoxLayout(widget);
connectionsVbox->setContentsMargins(QMargins());
connectionsVbox->setSizeConstraint(QLayout::SetMinAndMaxSize);
scroll = new QScrollArea;
scroll->setWidgetResizable(true);
scroll->setWidget(widget);
vbox->addWidget(scroll);
fillConnections();
QTimer *checkConnectionsTimer = new QTimer(this);
checkConnectionsTimer->setInterval(1000);
connect(checkConnectionsTimer, &QTimer::timeout, this, &NetworkList::fillConnections);
checkConnectionsTimer->start();
}
//--------------------------------------------------------------------------------
void NetworkList::openConfigureDialog()
{
// newer plasma has already a KCM
KService::Ptr service = KService::serviceByDesktopName("kcm_networkmanagement");
if ( service )
KRun::runApplication(*service, QList(), this);
else
KRun::run("kde5-nm-connection-editor", QList(), this);
close();
}
//--------------------------------------------------------------------------------
void NetworkList::statusUpdate()
{
network->setChecked(NetworkManager::isNetworkingEnabled());
wireless->setChecked(NetworkManager::isWirelessEnabled());
}
//--------------------------------------------------------------------------------
void NetworkList::fillConnections()
{
if ( underMouse() ) // avoid to delete the widget we are possibly hovering over
return;
QLayoutItem *child;
while ( (child = connectionsVbox->takeAt(0)) )
{
delete child->widget();
delete child;
}
NetworkManager::Connection::List allConnections = NetworkManager::listConnections();
// show VPN networks on top
for (const NetworkManager::Connection::Ptr c : allConnections)
{
if ( !c->isValid() )
continue;
if ( c->settings()->connectionType() == NetworkManager::ConnectionSettings::Vpn )
{
NetworkButton *vpn = new NetworkButton(c);
vpn->setText(c->name());
vpn->setIcon(QIcon::fromTheme("security-high"));
connectionsVbox->addWidget(vpn);
vpn->show();
}
}
// wired networks
for (const NetworkManager::Connection::Ptr c : allConnections)
{
if ( !c->isValid() )
continue;
if ( (c->settings()->connectionType() == NetworkManager::ConnectionSettings::Wired) &&
!c->uuid().isEmpty() )
{
NetworkButton *net = new NetworkButton(c);
net->setText(c->name());
net->setIcon(QIcon::fromTheme("network-wired"));
connectionsVbox->addWidget(net);
net->show();
}
}
// show available wifi networks
if ( NetworkManager::isWirelessEnabled() )
{
for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces())
{
if ( device->type() != NetworkManager::Device::Wifi )
continue;
NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast();
for (const NetworkManager::WirelessNetwork::Ptr &network : wifiDevice->networks())
{
NetworkManager::AccessPoint::Ptr accessPoint = network->referenceAccessPoint();
if ( !accessPoint )
continue;
// check if we have a connection for this SSID
- bool haveConnection = false;
NetworkManager::Connection::Ptr conn;
for (const NetworkManager::Connection::Ptr c : allConnections)
{
if ( c->isValid() && (c->settings()->connectionType() == NetworkManager::ConnectionSettings::Wireless) )
{
NetworkManager::Setting::Ptr setting = c->settings()->setting(NetworkManager::Setting::Wireless);
NetworkManager::WirelessSetting::Ptr s = setting.staticCast();
if ( s->ssid() == network->ssid() )
{
- haveConnection = true;
conn = c;
break;
}
}
}
- if ( haveConnection )
+ NetworkButton *net;
+
+ if ( conn )
{
- NetworkButton *net = new NetworkButton(conn, device);
+ net = new NetworkButton(conn, device);
net->setText(QString("%1 (%2%)").arg(conn->name()).arg(network->signalStrength()));
- net->setIcon(QIcon::fromTheme("network-wireless"));
- connectionsVbox->addWidget(net);
- net->show();
}
else
{
- NetworkButton *net = new NetworkButton;
+ net = new NetworkButton(nullptr, device, accessPoint);
net->setText(QString("%1 (%2%)").arg(network->ssid()).arg(network->signalStrength()));
- net->setIcon(QIcon::fromTheme("network-wireless"));
- net->setEnabled(false); // TODO: allow to add a new connection. See NetworkManager::addAndActivateConnection
- connectionsVbox->addWidget(net);
- net->show();
}
- /*
- NetworkManager::WirelessSecurityType security =
- NetworkManager::findBestWirelessSecurity(wifiDevice->wirelessCapabilities(), true,
- wifiDevice->mode() == NetworkManager::WirelessDevice::Adhoc,
- accessPoint->capabilities(), accessPoint->wpaFlags(), accessPoint->rsnFlags());
+ net->setIcon(QIcon::fromTheme("network-wireless"));
- if ( (security != NetworkManager::UnknownSecurity) && (security != NetworkManager::NoneSecurity) )
- net->setIcon(QIcon::fromTheme("object-locked"));
+ if ( accessPoint->wpaFlags() )
+ net->setIcon2(QIcon::fromTheme("object-locked"));
else
- net->setIcon(QIcon::fromTheme("object-unlocked"));
- */
+ net->setIcon2(QIcon::fromTheme("object-unlocked"));
+
+ connectionsVbox->addWidget(net);
+ net->show();
}
}
}
#if 0
// TEST
static int count = 15;
for (int i = 0; i < count; i++)
{
NetworkButton *net = new NetworkButton();
net->setText(QString("dummy %1").arg(i));
net->setIcon(QIcon::fromTheme("network-wired"));
connectionsVbox->addWidget(net);
net->show();
}
count -= 3;
if ( count <= 0 ) count = 15;
#endif
connectionsVbox->addStretch();
adjustSize();
emit changed();
}
//--------------------------------------------------------------------------------
QSize NetworkList::sizeHint() const
{
QWidget *w = scroll->widget();
QSize s;
s.setHeight(frameWidth() +
contentsMargins().top() +
layout()->contentsMargins().top() +
hbox->sizeHint().height() +
((layout()->spacing() == -1) ? style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing) : layout()->spacing()) +
scroll->frameWidth() +
scroll->contentsMargins().top() +
w->sizeHint().height() +
scroll->contentsMargins().bottom() +
scroll->frameWidth() +
layout()->contentsMargins().bottom() +
contentsMargins().bottom() +
frameWidth()
);
s.setWidth(frameWidth() +
contentsMargins().left() +
layout()->contentsMargins().left() +
scroll->frameWidth() +
scroll->contentsMargins().left() +
w->sizeHint().width() +
scroll->verticalScrollBar()->sizeHint().width() +
scroll->contentsMargins().right() +
scroll->frameWidth() +
layout()->contentsMargins().right() +
contentsMargins().right() +
frameWidth()
);
return s;
}
//--------------------------------------------------------------------------------
diff --git a/NetworkList.hxx b/NetworkList.hxx
index a9c7ecb..b1b6644 100644
--- a/NetworkList.hxx
+++ b/NetworkList.hxx
@@ -1,75 +1,80 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Copyright 2017 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
liquidshell is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with liquidshell. If not, see .
*/
#ifndef _NetworkList_H_
#define _NetworkList_H_
#include
#include
#include
#include
#include
class NetworkList : public QFrame
{
Q_OBJECT
public:
NetworkList(QWidget *parent);
QSize sizeHint() const override;
Q_SIGNALS:
void changed();
private Q_SLOTS:
void statusUpdate();
void fillConnections();
void openConfigureDialog();
private:
QToolButton *network, *wireless;
QVBoxLayout *connectionsVbox;
QHBoxLayout *hbox;
QScrollArea *scroll;
};
//--------------------------------------------------------------------------------
#include
+#include
#include
class NetworkButton : public IconButton
{
Q_OBJECT
public:
- NetworkButton(NetworkManager::Connection::Ptr c = NetworkManager::Connection::Ptr(),
- NetworkManager::Device::Ptr dev = NetworkManager::Device::Ptr());
+ NetworkButton(NetworkManager::Connection::Ptr c = nullptr,
+ NetworkManager::Device::Ptr dev = nullptr,
+ NetworkManager::AccessPoint::Ptr accessPoint = nullptr);
private Q_SLOTS:
void toggleNetworkStatus(bool on);
private:
NetworkManager::Connection::Ptr connection;
NetworkManager::Device::Ptr device;
+ QByteArray rawSsid;
+ QString ssid;
+ NetworkManager::AccessPoint::WpaFlags wpaFlags;
};
#endif