mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Move cellularnetwork kcm to plasma-nm
This commit is contained in:
parent
9a35cca1b6
commit
cfdb1ae516
24 changed files with 0 additions and 3941 deletions
|
|
@ -2,7 +2,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
add_subdirectory(mobileshell)
|
||||
add_subdirectory(cellularnetwork)
|
||||
add_subdirectory(info)
|
||||
add_subdirectory(powermanagement)
|
||||
add_subdirectory(time)
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
kcmutils_add_qml_kcm(kcm_cellular_network)
|
||||
|
||||
target_sources(kcm_cellular_network PRIVATE
|
||||
cellularnetworksettings.cpp
|
||||
modem.cpp
|
||||
modemdetails.cpp
|
||||
sim.cpp
|
||||
mobileproviders.cpp
|
||||
profilesettings.cpp
|
||||
)
|
||||
target_link_libraries(kcm_cellular_network PRIVATE
|
||||
Qt::DBus
|
||||
Qt::Gui
|
||||
Qt::Quick
|
||||
Qt::Qml
|
||||
Qt::Xml
|
||||
Plasma::Plasma
|
||||
KF6::I18n
|
||||
KF6::NetworkManagerQt
|
||||
KF6::ModemManagerQt
|
||||
KF6::KCMUtilsQuick
|
||||
QCoro::DBus
|
||||
)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
$XGETTEXT `find . -name \*.cpp -o -name \*.qml` -o $podir/kcm_cellular_network.pot
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
||||
SPDX-FileCopyrightText: 2020-2021 Devin Lin <espidev@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "cellularnetworksettings.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginFactory>
|
||||
#include <KUser>
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
K_PLUGIN_CLASS_WITH_JSON(CellularNetworkSettings, "kcm_cellular_network.json")
|
||||
|
||||
CellularNetworkSettings *CellularNetworkSettings::staticInst = nullptr;
|
||||
|
||||
CellularNetworkSettings::CellularNetworkSettings(QObject *parent, const KPluginMetaData &metaData)
|
||||
: KQuickConfigModule(parent, metaData)
|
||||
, m_modemList{}
|
||||
, m_simList{}
|
||||
{
|
||||
setButtons({});
|
||||
|
||||
CellularNetworkSettings::staticInst = this;
|
||||
|
||||
qmlRegisterType<ProfileSettings>("cellularnetworkkcm", 1, 0, "ProfileSettings");
|
||||
qmlRegisterType<Modem>("cellularnetworkkcm", 1, 0, "Modem");
|
||||
qmlRegisterType<ModemDetails>("cellularnetworkkcm", 1, 0, "ModemDetails");
|
||||
qmlRegisterType<AvailableNetwork>("cellularnetworkkcm", 1, 0, "AvailableNetwork");
|
||||
qmlRegisterType<Sim>("cellularnetworkkcm", 1, 0, "Sim");
|
||||
qmlRegisterType<InlineMessage>("cellularnetworkkcm", 1, 0, "InlineMessage");
|
||||
|
||||
// find modems
|
||||
updateModemList();
|
||||
|
||||
connect(ModemManager::notifier(), &ModemManager::Notifier::modemAdded, this, &CellularNetworkSettings::updateModemList);
|
||||
connect(ModemManager::notifier(), &ModemManager::Notifier::modemRemoved, this, &CellularNetworkSettings::updateModemList);
|
||||
}
|
||||
|
||||
CellularNetworkSettings *CellularNetworkSettings::instance()
|
||||
{
|
||||
return CellularNetworkSettings::staticInst;
|
||||
}
|
||||
|
||||
Modem *CellularNetworkSettings::selectedModem()
|
||||
{
|
||||
// TODO: we are currently assuming there is a single modem
|
||||
if (m_modemList.count() > 0) {
|
||||
return m_modemList[0];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QList<Modem *> CellularNetworkSettings::modems()
|
||||
{
|
||||
return m_modemList;
|
||||
}
|
||||
|
||||
QList<Sim *> CellularNetworkSettings::sims()
|
||||
{
|
||||
return m_simList;
|
||||
}
|
||||
|
||||
bool CellularNetworkSettings::modemFound()
|
||||
{
|
||||
return !m_modemList.empty();
|
||||
}
|
||||
|
||||
void CellularNetworkSettings::updateModemList()
|
||||
{
|
||||
// loop over every modem
|
||||
for (ModemManager::ModemDevice::Ptr device : ModemManager::modemDevices()) {
|
||||
ModemManager::Modem::Ptr modem = device->modemInterface();
|
||||
|
||||
qDebug() << QStringLiteral("Found modem:") << device->uni();
|
||||
|
||||
m_modemList.push_back(new Modem(this, device, modem));
|
||||
|
||||
// update sims list if modem's list changes
|
||||
connect(m_modemList[m_modemList.size() - 1], &Modem::simsChanged, this, [this]() -> void {
|
||||
fillSims();
|
||||
});
|
||||
}
|
||||
|
||||
if (m_modemList.empty()) {
|
||||
qDebug() << QStringLiteral("No modems found.");
|
||||
}
|
||||
|
||||
// fill sim list
|
||||
fillSims();
|
||||
|
||||
// update the currently selected modem
|
||||
Q_EMIT selectedModemChanged();
|
||||
}
|
||||
|
||||
void CellularNetworkSettings::fillSims()
|
||||
{
|
||||
for (auto p : m_simList) {
|
||||
delete p;
|
||||
}
|
||||
m_simList.clear();
|
||||
|
||||
qDebug() << QStringLiteral("Scanning SIMs list...");
|
||||
for (auto modem : m_modemList) {
|
||||
auto sims = modem->sims();
|
||||
for (auto sim : sims) {
|
||||
qDebug() << QStringLiteral("Found SIM") << sim->uni() << sim->imsi();
|
||||
m_simList.push_back(sim);
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT simsChanged();
|
||||
}
|
||||
|
||||
QList<InlineMessage *> CellularNetworkSettings::messages()
|
||||
{
|
||||
return m_messages;
|
||||
}
|
||||
|
||||
void CellularNetworkSettings::addMessage(InlineMessage::Type type, QString msg)
|
||||
{
|
||||
m_messages.push_back(new InlineMessage{this, type, msg});
|
||||
Q_EMIT messagesChanged();
|
||||
}
|
||||
|
||||
void CellularNetworkSettings::removeMessage(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_messages.size()) {
|
||||
m_messages.removeAt(index);
|
||||
Q_EMIT messagesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
InlineMessage::InlineMessage(QObject *parent, Type type, QString message)
|
||||
: QObject{parent}
|
||||
, m_type{type}
|
||||
, m_message{message}
|
||||
{
|
||||
}
|
||||
|
||||
InlineMessage::Type InlineMessage::type()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
QString InlineMessage::message()
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
#include "cellularnetworksettings.moc"
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
||||
SPDX-FileCopyrightText: 2020-2021 Devin Lin <espidev@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <KQuickConfigModule>
|
||||
|
||||
#include "mobileproviders.h"
|
||||
#include "modem.h"
|
||||
#include "modemdetails.h"
|
||||
#include "sim.h"
|
||||
|
||||
#include <NetworkManagerQt/CdmaSetting>
|
||||
#include <NetworkManagerQt/ConnectionSettings>
|
||||
#include <NetworkManagerQt/GsmSetting>
|
||||
#include <NetworkManagerQt/Manager>
|
||||
#include <NetworkManagerQt/ModemDevice>
|
||||
#include <NetworkManagerQt/Settings>
|
||||
|
||||
#include <ModemManagerQt/GenericTypes>
|
||||
#include <ModemManagerQt/Manager>
|
||||
#include <ModemManagerQt/ModemDevice>
|
||||
|
||||
class Sim;
|
||||
class Modem;
|
||||
class MobileProviders;
|
||||
|
||||
class InlineMessage : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int type READ type NOTIFY typeChanged)
|
||||
Q_PROPERTY(QString message READ message NOTIFY messageChanged)
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
Information,
|
||||
Positive,
|
||||
Warning,
|
||||
Error,
|
||||
};
|
||||
|
||||
InlineMessage(QObject *parent = nullptr, Type type = Information, QString message = "");
|
||||
|
||||
Type type();
|
||||
QString message();
|
||||
|
||||
Q_SIGNALS:
|
||||
void typeChanged();
|
||||
void messageChanged();
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
QString m_message;
|
||||
};
|
||||
|
||||
class CellularNetworkSettings : public KQuickConfigModule
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool modemFound READ modemFound NOTIFY modemFoundChanged)
|
||||
Q_PROPERTY(Modem *selectedModem READ selectedModem NOTIFY selectedModemChanged)
|
||||
Q_PROPERTY(QList<Sim *> sims READ sims NOTIFY simsChanged)
|
||||
Q_PROPERTY(QList<InlineMessage *> messages READ messages NOTIFY messagesChanged)
|
||||
|
||||
public:
|
||||
CellularNetworkSettings(QObject *parent, const KPluginMetaData &metaData);
|
||||
|
||||
static CellularNetworkSettings *instance();
|
||||
|
||||
Modem *selectedModem();
|
||||
QList<Modem *> modems();
|
||||
QList<Sim *> sims();
|
||||
|
||||
bool modemFound();
|
||||
|
||||
QList<InlineMessage *> messages();
|
||||
void addMessage(InlineMessage::Type type, QString msg);
|
||||
Q_INVOKABLE void removeMessage(int index);
|
||||
|
||||
Q_SIGNALS:
|
||||
void modemFoundChanged();
|
||||
void selectedModemChanged();
|
||||
void simsChanged();
|
||||
void messagesChanged();
|
||||
|
||||
private:
|
||||
void updateModemList();
|
||||
void fillSims();
|
||||
|
||||
QList<Modem *> m_modemList;
|
||||
QList<Sim *> m_simList;
|
||||
|
||||
QList<InlineMessage *> m_messages;
|
||||
|
||||
static CellularNetworkSettings *staticInst;
|
||||
};
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
{
|
||||
"Categories": "Qt;KDE;X-KDE-settings-system;",
|
||||
"KPlugin": {
|
||||
"Description": "Management of cellular networks",
|
||||
"Description[ca@valencia]": "Gestió de xarxes de telefonia mòbil",
|
||||
"Description[ca]": "Gestió de xarxes de telefonia mòbil",
|
||||
"Description[cs]": "Spravovat vaše mobilní sítě",
|
||||
"Description[de]": "Verwaltung von Mobilfunknetzen",
|
||||
"Description[en_GB]": "Management of cellular networks",
|
||||
"Description[eo]": "Administrado de ĉelaj retoj",
|
||||
"Description[es]": "Gestión de redes móviles",
|
||||
"Description[eu]": "Mugikorrerako sareen kudeaketa",
|
||||
"Description[fi]": "Matkapuhelinverkkojen hallinta",
|
||||
"Description[fr]": "Gestion de réseaux cellulaires",
|
||||
"Description[gl]": "Xestión de redes móbiles.",
|
||||
"Description[he]": "ניהול רשתות סלולריות",
|
||||
"Description[hu]": "Mobilhálózatok kezelése",
|
||||
"Description[ia]": "Gestion de retes cellular",
|
||||
"Description[is]": "Umsjón farsímaneta",
|
||||
"Description[it]": "Gestione delle reti cellulari",
|
||||
"Description[ka]": "ფიჭური ქსელების მართვა",
|
||||
"Description[ko]": "모바일 네트워크 관리",
|
||||
"Description[lv]": "Pārvaldīt mobilos tīklus",
|
||||
"Description[nl]": "Beheer van cellulaire netwerken",
|
||||
"Description[nn]": "Handsaming av mobilnettverk",
|
||||
"Description[pa]": "ਸੈਲੂਲਰ ਨੈੱਟਵਰਕਾਂ ਦਾ ਇੰਤਜ਼ਾਮ",
|
||||
"Description[pl]": "Zarządzanie sieciami komórkowymi",
|
||||
"Description[pt_BR]": "Gerenciamento de redes celulares",
|
||||
"Description[ru]": "Управление сетями сотовой связи",
|
||||
"Description[sa]": "सेलुलरजालस्य प्रबन्धनम्",
|
||||
"Description[sk]": "Správa mobilných sietí",
|
||||
"Description[sl]": "Upravljanje celičnih omrežij",
|
||||
"Description[sv]": "Hantering av mobilnät",
|
||||
"Description[tr]": "Hücresel ağların yönetimi",
|
||||
"Description[uk]": "Керування стільниковими мережами",
|
||||
"Description[x-test]": "xxManagement of cellular networksxx",
|
||||
"Description[zh_CN]": "管理移动网络",
|
||||
"Description[zh_TW]": "行動網路的管理",
|
||||
"FormFactors": [
|
||||
"handset",
|
||||
"tablet",
|
||||
"mediacenter"
|
||||
],
|
||||
"Icon": "smartphone",
|
||||
"Name": "Cellular Network",
|
||||
"Name[ar]": "شبكة خليوية",
|
||||
"Name[ca@valencia]": "Xarxa de telefonia mòbil",
|
||||
"Name[ca]": "Xarxa de telefonia mòbil",
|
||||
"Name[cs]": "Mobilní síť",
|
||||
"Name[de]": "Mobilfunknetz",
|
||||
"Name[en_GB]": "Cellular Network",
|
||||
"Name[eo]": "Ĉela Reto",
|
||||
"Name[es]": "Red móvil",
|
||||
"Name[eu]": "Mugikorrerako sarea",
|
||||
"Name[fi]": "Matkapuhelinverkko",
|
||||
"Name[fr]": "Réseau cellulaire",
|
||||
"Name[gl]": "Rede móbil",
|
||||
"Name[he]": "רשת סלולרית",
|
||||
"Name[hu]": "Mobilhálózat",
|
||||
"Name[ia]": "Rete Cellular",
|
||||
"Name[is]": "Farsímakerfi",
|
||||
"Name[it]": "Rete cellulare",
|
||||
"Name[ka]": "ფიჭური ქსელი",
|
||||
"Name[ko]": "모바일 네트워크",
|
||||
"Name[lv]": "Mobilais tīkls",
|
||||
"Name[nl]": "Cellulair netwerk",
|
||||
"Name[nn]": "Mobilnettverk",
|
||||
"Name[pa]": "ਸੈਲੂਲਰ ਨੈੱਟਵਰਕ",
|
||||
"Name[pl]": "Sieć komórkowa",
|
||||
"Name[pt_BR]": "Rede celular",
|
||||
"Name[ru]": "Сеть сотовой связи",
|
||||
"Name[sa]": "सेलुलर नेटवर्क",
|
||||
"Name[sk]": "Mobilná sieť",
|
||||
"Name[sl]": "Celično omrežje",
|
||||
"Name[sv]": "Mobilnät",
|
||||
"Name[ta]": "கைபேசி பிணையம்",
|
||||
"Name[tr]": "Hücresel Ağ",
|
||||
"Name[uk]": "Стільникова мережа",
|
||||
"Name[x-test]": "xxCellular Networkxx",
|
||||
"Name[zh_CN]": "移动网络",
|
||||
"Name[zh_TW]": "行動網路"
|
||||
},
|
||||
"X-KDE-Keywords": "mobile,data,network",
|
||||
"X-KDE-Keywords[ca@valencia]": "mòbil,dades,xarxa",
|
||||
"X-KDE-Keywords[ca]": "mòbil,dades,xarxa",
|
||||
"X-KDE-Keywords[cs]": "mobilní,data,síť",
|
||||
"X-KDE-Keywords[en_GB]": "mobile,data,network",
|
||||
"X-KDE-Keywords[es]": "móvil,datos,red",
|
||||
"X-KDE-Keywords[eu]": "mugikorra,telefono mugikorra,datuak,sarea",
|
||||
"X-KDE-Keywords[fi]": "mobiili,data,mobiilidata,verkko",
|
||||
"X-KDE-Keywords[fr]": "mobile, data, réseau",
|
||||
"X-KDE-Keywords[gl]": "móbil,datos,rede",
|
||||
"X-KDE-Keywords[he]": "נייד,נתונים,רשת,פס רחב",
|
||||
"X-KDE-Keywords[hu]": "mobil,adat,hálózat",
|
||||
"X-KDE-Keywords[ia]": "mobile,data,network",
|
||||
"X-KDE-Keywords[it]": "mobile,dati,rete",
|
||||
"X-KDE-Keywords[ka]": "mobile,data,network,მობილური ინტერნეტი,ქსელი",
|
||||
"X-KDE-Keywords[ko]": "mobile,data,network,모바일,데이터,네트워크",
|
||||
"X-KDE-Keywords[lv]": "mobilie,dati,tīkls",
|
||||
"X-KDE-Keywords[nl]": "mobiel,gegevens,netwerk",
|
||||
"X-KDE-Keywords[nn]": "mobil,mobilt,data,nettverk",
|
||||
"X-KDE-Keywords[pl]": "komórkowa,mobilna,dane,sieć",
|
||||
"X-KDE-Keywords[ru]": "mobile,data,network,мобильный,данные,сеть",
|
||||
"X-KDE-Keywords[sa]": "मोबाइल,डेटा,जाल",
|
||||
"X-KDE-Keywords[sl]": "mobilnik,podatki,omrežje",
|
||||
"X-KDE-Keywords[sv]": "mobil,data,nätverk",
|
||||
"X-KDE-Keywords[tr]": "mobil,cep,taşınabilir,veri,ağ",
|
||||
"X-KDE-Keywords[uk]": "mobile,data,network,мобільний,дані,мережа",
|
||||
"X-KDE-Keywords[x-test]": "xxmobilexx,xxdataxx,xxnetworkxx",
|
||||
"X-KDE-Keywords[zh_CN]": "mobile,data,network,yidong,shuju,wangluo,fengwo,shouji,liuliang,移动,数据,流量,网络,蜂窝,手机",
|
||||
"X-KDE-Keywords[zh_TW]": "行動,資料,網路",
|
||||
"X-KDE-System-Settings-Parent-Category": "network",
|
||||
"X-KDE-Weight": 70
|
||||
}
|
||||
|
|
@ -1,336 +0,0 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2010-2012 Lamarque Souza <lamarque@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#include "mobileproviders.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QLocale>
|
||||
#include <QRegularExpression>
|
||||
#include <QTextStream>
|
||||
|
||||
const QString MobileProviders::ProvidersFile = QStringLiteral("/usr/share/mobile-broadband-provider-info/serviceproviders.xml");
|
||||
|
||||
// adapted from https://invent.kde.org/plasma/plasma-nm/-/blob/master/libs/editor/mobileproviders.cpp
|
||||
// we only use gsm, ignore cdma
|
||||
|
||||
bool localeAwareCompare(const QString &one, const QString &two)
|
||||
{
|
||||
return one.localeAwareCompare(two) < 0;
|
||||
}
|
||||
|
||||
MobileProviders::MobileProviders()
|
||||
{
|
||||
for (int c = 1; c <= QLocale::LastCountry; c++) {
|
||||
const auto country = static_cast<QLocale::Territory>(c);
|
||||
QLocale locale(QLocale::AnyLanguage, country);
|
||||
if (locale.territory() == country) {
|
||||
const QString localeName = locale.name();
|
||||
const auto idx = localeName.indexOf(QLatin1Char('_'));
|
||||
if (idx != -1) {
|
||||
const QString countryCode = localeName.mid(idx + 1);
|
||||
QString countryName = locale.nativeTerritoryName();
|
||||
if (countryName.isEmpty()) {
|
||||
countryName = QLocale::territoryToString(country);
|
||||
}
|
||||
mCountries.insert(countryCode, countryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
mError = Success;
|
||||
|
||||
QFile file2(ProvidersFile);
|
||||
|
||||
if (file2.open(QIODevice::ReadOnly)) {
|
||||
if (mDocProviders.setContent(&file2)) {
|
||||
docElement = mDocProviders.documentElement();
|
||||
|
||||
if (docElement.isNull()) {
|
||||
qWarning() << ProvidersFile << ": document is null";
|
||||
mError = ProvidersIsNull;
|
||||
} else {
|
||||
if (docElement.isNull() || docElement.tagName() != "serviceproviders") {
|
||||
qWarning() << ProvidersFile << ": wrong format";
|
||||
mError = ProvidersWrongFormat;
|
||||
} else {
|
||||
if (docElement.attribute("format") != "2.0") {
|
||||
qWarning() << ProvidersFile << ": mobile broadband provider database format '" << docElement.attribute("format") << "' not supported.";
|
||||
mError = ProvidersFormatNotSupported;
|
||||
} else {
|
||||
// qCDebug(PLASMA_NM) << "Everything is alright so far";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file2.close();
|
||||
} else {
|
||||
qWarning() << "Error opening providers file" << ProvidersFile;
|
||||
mError = ProvidersMissing;
|
||||
}
|
||||
}
|
||||
|
||||
MobileProviders::~MobileProviders()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList MobileProviders::getCountryList() const
|
||||
{
|
||||
QStringList temp = mCountries.values();
|
||||
std::sort(temp.begin(), temp.end(), localeAwareCompare);
|
||||
return temp;
|
||||
}
|
||||
|
||||
QString MobileProviders::countryFromLocale() const
|
||||
{
|
||||
const QString localeName = QLocale().name();
|
||||
const auto idx = localeName.indexOf(QLatin1Char('_'));
|
||||
if (idx != -1) {
|
||||
return localeName.mid(idx + 1);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList MobileProviders::getApns(const QString &provider)
|
||||
{
|
||||
mApns.clear();
|
||||
mNetworkIds.clear();
|
||||
if (!mProvidersGsm.contains(provider)) {
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QDomNode n = mProvidersGsm[provider];
|
||||
|
||||
while (!n.isNull()) {
|
||||
QDomElement e = n.toElement(); // <gsm | cdma>
|
||||
|
||||
if (!e.isNull() && e.tagName().toLower() == "gsm") {
|
||||
QDomNode n2 = e.firstChild();
|
||||
while (!n2.isNull()) {
|
||||
QDomElement e2 = n2.toElement(); // <apn | network-id>
|
||||
|
||||
if (!e2.isNull() && e2.tagName().toLower() == "apn") {
|
||||
bool isInternet = true;
|
||||
QDomNode n3 = e2.firstChild();
|
||||
while (!n3.isNull()) {
|
||||
QDomElement e3 = n3.toElement(); // <usage>
|
||||
if (!e3.isNull() && e3.tagName().toLower() == "usage" && !e3.attribute("type").isNull()
|
||||
&& e3.attribute("type").toLower() != "internet") {
|
||||
// qCDebug(PLASMA_NM) << "apn" << e2.attribute("value") << "ignored because of usage" << e3.attribute("type");
|
||||
isInternet = false;
|
||||
break;
|
||||
}
|
||||
n3 = n3.nextSibling();
|
||||
}
|
||||
if (isInternet) {
|
||||
mApns.insert(e2.attribute("value"), e2.firstChild());
|
||||
}
|
||||
} else if (!e2.isNull() && e2.tagName().toLower() == "network-id") {
|
||||
mNetworkIds.append(e2.attribute("mcc") + '-' + e2.attribute("mnc"));
|
||||
}
|
||||
|
||||
n2 = n2.nextSibling();
|
||||
}
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
|
||||
QStringList temp = mApns.keys();
|
||||
temp.sort();
|
||||
return temp;
|
||||
}
|
||||
|
||||
ProviderData MobileProviders::parseProvider(const QDomNode &providerNode)
|
||||
{
|
||||
ProviderData result;
|
||||
|
||||
QMap<QString, QString> localizedProviderNames;
|
||||
|
||||
QDomNode c = providerNode.firstChild(); // <name | gsm | cdma>
|
||||
bool hasGsm = false;
|
||||
|
||||
while (!c.isNull()) {
|
||||
QDomElement ce = c.toElement();
|
||||
|
||||
if (ce.tagName().toLower() == QLatin1String("gsm")) {
|
||||
QDomNode gsmNode = c.firstChild();
|
||||
|
||||
while (!gsmNode.isNull()) {
|
||||
QDomElement gsmElement = gsmNode.toElement();
|
||||
|
||||
if (gsmElement.tagName().toLower() == QLatin1String("network-id")) {
|
||||
result.mccmncs.append(gsmElement.attribute("mcc") + gsmElement.attribute("mnc"));
|
||||
}
|
||||
gsmNode = gsmNode.nextSibling();
|
||||
}
|
||||
|
||||
hasGsm = true;
|
||||
} else if (ce.tagName().toLower() == QLatin1String("name")) {
|
||||
QString lang = ce.attribute("xml:lang");
|
||||
if (lang.isEmpty()) {
|
||||
lang = "en"; // English is default
|
||||
} else {
|
||||
lang = lang.toLower();
|
||||
lang.remove(QRegularExpression(QStringLiteral("\\-.*$"))); // Remove everything after '-' in xml:lang attribute.
|
||||
}
|
||||
localizedProviderNames.insert(lang, ce.text());
|
||||
}
|
||||
|
||||
c = c.nextSibling();
|
||||
}
|
||||
|
||||
result.name = getNameByLocale(localizedProviderNames);
|
||||
|
||||
const QString name = result.name;
|
||||
if (hasGsm) {
|
||||
mProvidersGsm.insert(name, providerNode.firstChild());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList MobileProviders::getProvidersFromMCCMNC(const QString &targetMccMnc)
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
QDomNode n = docElement.firstChild();
|
||||
|
||||
while (!n.isNull()) {
|
||||
QDomElement e = n.toElement(); // <country ...>
|
||||
|
||||
if (!e.isNull()) {
|
||||
QDomNode n2 = e.firstChild();
|
||||
while (!n2.isNull()) {
|
||||
QDomElement e2 = n2.toElement(); // <provider ...>
|
||||
|
||||
if (!e2.isNull() && e2.tagName().toLower() == "provider") {
|
||||
ProviderData data = parseProvider(e2);
|
||||
|
||||
if (data.mccmncs.contains(targetMccMnc)) {
|
||||
result << data.name;
|
||||
}
|
||||
}
|
||||
n2 = n2.nextSibling();
|
||||
}
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList MobileProviders::getNetworkIds(const QString &provider)
|
||||
{
|
||||
if (mNetworkIds.isEmpty()) {
|
||||
getApns(provider);
|
||||
}
|
||||
return mNetworkIds;
|
||||
}
|
||||
|
||||
QVariantMap MobileProviders::getApnInfo(const QString &apn)
|
||||
{
|
||||
QVariantMap temp;
|
||||
QDomNode n = mApns[apn];
|
||||
QStringList dnsList;
|
||||
QMap<QString, QString> localizedPlanNames;
|
||||
|
||||
while (!n.isNull()) {
|
||||
QDomElement e = n.toElement(); // <name|username|password|dns(*)>
|
||||
|
||||
if (!e.isNull()) {
|
||||
if (e.tagName().toLower() == "name") {
|
||||
QString lang = e.attribute("xml:lang");
|
||||
if (lang.isEmpty()) {
|
||||
lang = "en"; // English is default
|
||||
} else {
|
||||
lang = lang.toLower();
|
||||
lang.remove(QRegularExpression(QStringLiteral("\\-.*$"))); // Remove everything after '-' in xml:lang attribute.
|
||||
}
|
||||
localizedPlanNames.insert(lang, e.text());
|
||||
} else if (e.tagName().toLower() == "username") {
|
||||
temp.insert("username", e.text());
|
||||
} else if (e.tagName().toLower() == "password") {
|
||||
temp.insert("password", e.text());
|
||||
} else if (e.tagName().toLower() == "dns") {
|
||||
dnsList.append(e.text());
|
||||
} else if (e.tagName().toLower() == "usage") {
|
||||
temp.insert("usageType", e.attribute("type"));
|
||||
}
|
||||
}
|
||||
|
||||
n = n.nextSibling();
|
||||
}
|
||||
|
||||
QString name = getNameByLocale(localizedPlanNames);
|
||||
if (!name.isEmpty()) {
|
||||
temp.insert("name", QVariant::fromValue(name));
|
||||
}
|
||||
temp.insert("number", getGsmNumber());
|
||||
temp.insert("apn", apn);
|
||||
temp.insert("dnsList", dnsList);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
QVariantMap MobileProviders::getCdmaInfo(const QString &provider)
|
||||
{
|
||||
if (!mProvidersCdma.contains(provider)) {
|
||||
return QVariantMap();
|
||||
}
|
||||
|
||||
QVariantMap temp;
|
||||
QDomNode n = mProvidersCdma[provider];
|
||||
QStringList sidList;
|
||||
|
||||
while (!n.isNull()) {
|
||||
QDomElement e = n.toElement(); // <gsm or cdma ...>
|
||||
|
||||
if (!e.isNull() && e.tagName().toLower() == "cdma") {
|
||||
QDomNode n2 = e.firstChild();
|
||||
while (!n2.isNull()) {
|
||||
QDomElement e2 = n2.toElement(); // <name | username | password | sid>
|
||||
|
||||
if (!e2.isNull()) {
|
||||
if (e2.tagName().toLower() == "username") {
|
||||
temp.insert("username", e2.text());
|
||||
} else if (e2.tagName().toLower() == "password") {
|
||||
temp.insert("password", e2.text());
|
||||
} else if (e2.tagName().toLower() == "sid") {
|
||||
sidList.append(e2.text());
|
||||
}
|
||||
}
|
||||
|
||||
n2 = n2.nextSibling();
|
||||
}
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
|
||||
temp.insert("number", getCdmaNumber());
|
||||
temp.insert("sidList", sidList);
|
||||
return temp;
|
||||
}
|
||||
|
||||
QString MobileProviders::getNameByLocale(const QMap<QString, QString> &localizedNames) const
|
||||
{
|
||||
QString name;
|
||||
const QStringList locales = QLocale().uiLanguages();
|
||||
for (const QString &locale : locales) {
|
||||
QString language = locale.split(QLatin1Char('-')).at(0);
|
||||
|
||||
if (localizedNames.contains(language)) {
|
||||
return localizedNames[language];
|
||||
}
|
||||
}
|
||||
|
||||
name = localizedNames["en"];
|
||||
|
||||
// Use any language if no proper localized name were found.
|
||||
if (name.isEmpty() && !localizedNames.isEmpty()) {
|
||||
name = localizedNames.constBegin().value();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2010-2012 Lamarque Souza <lamarque@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#ifndef PLASMA_NM_MOBILE_PROVIDERS_H
|
||||
#define PLASMA_NM_MOBILE_PROVIDERS_H
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QHash>
|
||||
#include <QStringList>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <NetworkManagerQt/ConnectionSettings>
|
||||
|
||||
// adapted from https://invent.kde.org/plasma/plasma-nm/-/blob/master/libs/editor/mobileproviders.h
|
||||
// we only use gsm, ignore cdma
|
||||
|
||||
struct ProviderData {
|
||||
QStringList mccmncs;
|
||||
QString name;
|
||||
};
|
||||
|
||||
class Q_DECL_EXPORT MobileProviders
|
||||
{
|
||||
public:
|
||||
static const QString ProvidersFile;
|
||||
|
||||
enum ErrorCodes {
|
||||
Success,
|
||||
CountryCodesMissing,
|
||||
ProvidersMissing,
|
||||
ProvidersIsNull,
|
||||
ProvidersWrongFormat,
|
||||
ProvidersFormatNotSupported,
|
||||
};
|
||||
|
||||
MobileProviders();
|
||||
~MobileProviders();
|
||||
|
||||
QStringList getCountryList() const;
|
||||
QString countryFromLocale() const;
|
||||
QString getCountryName(const QString &key) const
|
||||
{
|
||||
return mCountries.value(key);
|
||||
}
|
||||
QStringList getApns(const QString &provider);
|
||||
QStringList getNetworkIds(const QString &provider);
|
||||
QVariantMap getApnInfo(const QString &apn);
|
||||
QVariantMap getCdmaInfo(const QString &provider);
|
||||
QStringList getProvidersFromMCCMNC(const QString &mccmnc);
|
||||
QString getGsmNumber() const
|
||||
{
|
||||
return QString("*99#");
|
||||
}
|
||||
QString getCdmaNumber() const
|
||||
{
|
||||
return QString("#777");
|
||||
}
|
||||
inline ErrorCodes getError()
|
||||
{
|
||||
return mError;
|
||||
}
|
||||
|
||||
private:
|
||||
ProviderData parseProvider(const QDomNode &providerNode);
|
||||
|
||||
QHash<QString, QString> mCountries;
|
||||
QHash<QString, QString> mMccMncToName;
|
||||
QMap<QString, QDomNode> mProvidersGsm;
|
||||
QMap<QString, QDomNode> mProvidersCdma;
|
||||
QMap<QString, QDomNode> mApns;
|
||||
QStringList mNetworkIds;
|
||||
QDomDocument mDocProviders;
|
||||
QDomElement docElement;
|
||||
ErrorCodes mError;
|
||||
QString getNameByLocale(const QMap<QString, QString> &names) const;
|
||||
};
|
||||
|
||||
#endif // PLASMA_NM_MOBILE_PROVIDERS_H
|
||||
|
|
@ -1,549 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021-2022 Devin Lin <espidev@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "modem.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KUser>
|
||||
#include <QDBusReply>
|
||||
|
||||
#include <QCoroDBusPendingReply>
|
||||
|
||||
Modem::Modem(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
}
|
||||
|
||||
Modem::Modem(QObject *parent, ModemManager::ModemDevice::Ptr mmModem, ModemManager::Modem::Ptr mmInterface)
|
||||
: QObject{parent}
|
||||
, m_mmModem{mmModem}
|
||||
, m_nmModem{nullptr}
|
||||
, m_mmInterface{mmInterface}
|
||||
{
|
||||
// TODO multi-sim support
|
||||
m_sims = {new Sim{this, this, m_mmModem->sim(), m_mmInterface, m_mm3gppDevice}};
|
||||
|
||||
connect(m_mmModem.data(), &ModemManager::ModemDevice::simAdded, this, &Modem::simsChanged);
|
||||
connect(m_mmModem.data(), &ModemManager::ModemDevice::simAdded, this, &Modem::hasSimChanged);
|
||||
connect(m_mmModem.data(), &ModemManager::ModemDevice::simRemoved, this, &Modem::simsChanged);
|
||||
connect(m_mmModem.data(), &ModemManager::ModemDevice::simRemoved, this, &Modem::hasSimChanged);
|
||||
|
||||
if (m_mmModem->sim()) {
|
||||
connect(m_mmModem->sim().get(), &ModemManager::Sim::simIdentifierChanged, this, &Modem::hasSimChanged);
|
||||
}
|
||||
|
||||
connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionAdded, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionRemoved, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionRemoved, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &Modem::findNetworkManagerDevice);
|
||||
connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &Modem::findNetworkManagerDevice);
|
||||
|
||||
// this is guaranteed to be a GSM modem
|
||||
m_mm3gppDevice = m_mmModem->interface(ModemManager::ModemDevice::GsmInterface).objectCast<ModemManager::Modem3gpp>();
|
||||
|
||||
// if no sim is inserted, m_mm3gppDevice is nullptr
|
||||
if (m_mm3gppDevice) {
|
||||
m_mm3gppDevice->setTimeout(60000); // scanning networks likely takes longer than the default timeout
|
||||
}
|
||||
|
||||
// find networkmanager modem, if it exists
|
||||
findNetworkManagerDevice();
|
||||
|
||||
// we need to initialize it after m_mm3gppDevice has been set
|
||||
m_details = new ModemDetails(this, this);
|
||||
}
|
||||
|
||||
void Modem::findNetworkManagerDevice()
|
||||
{
|
||||
m_nmModem = nullptr;
|
||||
|
||||
// find networkmanager modem device
|
||||
for (NetworkManager::Device::Ptr nmDevice : NetworkManager::networkInterfaces()) {
|
||||
if (nmDevice->udi() == m_mmModem->uni()) {
|
||||
m_nmModem = nmDevice.objectCast<NetworkManager::ModemDevice>();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_nmModem) {
|
||||
connect(m_nmModem.data(), &NetworkManager::Device::autoconnectChanged, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(m_nmModem.data(), &NetworkManager::Device::stateChanged, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(m_nmModem.data(), &NetworkManager::Device::availableConnectionAppeared, this, &Modem::mobileDataEnabledChanged);
|
||||
connect(m_nmModem.data(), &NetworkManager::Device::availableConnectionDisappeared, this, &Modem::mobileDataEnabledChanged);
|
||||
|
||||
connect(m_nmModem.data(), &NetworkManager::ModemDevice::availableConnectionChanged, this, [this]() -> void {
|
||||
refreshProfiles();
|
||||
});
|
||||
connect(m_nmModem.data(), &NetworkManager::ModemDevice::activeConnectionChanged, this, [this]() -> void {
|
||||
refreshProfiles();
|
||||
Q_EMIT activeConnectionUniChanged();
|
||||
});
|
||||
connect(m_nmModem.data(), &NetworkManager::ModemDevice::stateChanged, this, [this](auto newstate, auto oldstate, auto reason) -> void {
|
||||
qDebug() << QStringLiteral("Modem") << m_nmModem->uni() << QStringLiteral("changed state:") << nmDeviceStateStr(oldstate) << QStringLiteral("->")
|
||||
<< nmDeviceStateStr(newstate) << QStringLiteral("due to:") << reason;
|
||||
});
|
||||
|
||||
// add connection profiles
|
||||
refreshProfiles();
|
||||
}
|
||||
|
||||
Q_EMIT nmModemChanged();
|
||||
Q_EMIT mobileDataEnabledChanged();
|
||||
Q_EMIT mobileDataSupportedChanged();
|
||||
}
|
||||
|
||||
ModemDetails *Modem::modemDetails() const
|
||||
{
|
||||
return m_details;
|
||||
}
|
||||
|
||||
QString Modem::displayId() const
|
||||
{
|
||||
// in the form /org/freedesktop/ModemManager1/Modem/0
|
||||
QStringList uniSplit = uni().split("/");
|
||||
return uniSplit.count() == 0 ? QStringLiteral("(empty)") : QString(uniSplit[uniSplit.size() - 1]);
|
||||
}
|
||||
|
||||
QString Modem::uni() const
|
||||
{
|
||||
return m_mmInterface->uni();
|
||||
}
|
||||
|
||||
QString Modem::activeConnectionUni() const
|
||||
{
|
||||
if (m_nmModem && m_nmModem->activeConnection() && m_nmModem->activeConnection()->connection()) {
|
||||
return m_nmModem->activeConnection()->connection()->uuid();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QCoro::Task<void> Modem::reset()
|
||||
{
|
||||
qDebug() << QStringLiteral("Resetting the modem...");
|
||||
|
||||
QDBusReply<void> reply = co_await m_mmInterface->reset();
|
||||
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << QStringLiteral("Error resetting the modem:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error resetting the modem: %1", reply.error().message()));
|
||||
}
|
||||
}
|
||||
|
||||
bool Modem::mobileDataSupported() const
|
||||
{
|
||||
return m_nmModem && hasSim();
|
||||
}
|
||||
|
||||
bool Modem::needsAPNAdded() const
|
||||
{
|
||||
return m_nmModem && mobileDataSupported() && m_nmModem->availableConnections().count() == 0;
|
||||
}
|
||||
|
||||
bool Modem::mobileDataEnabled() const
|
||||
{
|
||||
// if wwan is globally disabled
|
||||
if (!NetworkManager::isWwanEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no modem -> no mobile data -> report disabled
|
||||
if (!m_nmModem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// mobile data already activated -> report enabled
|
||||
if (m_nmModem->state() == NetworkManager::Device::Activated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// autoconnect disabled on the entire modem -> report disabled
|
||||
if (!m_nmModem->autoconnect()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// at least one connection set to autoconnect -> report enabled
|
||||
for (NetworkManager::Connection::Ptr con : m_nmModem->availableConnections()) {
|
||||
if (con->settings()->autoconnect()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// modem, but no connection, set to autoconnect -> report disabled
|
||||
return false;
|
||||
}
|
||||
|
||||
void Modem::setMobileDataEnabled(bool enabled)
|
||||
{
|
||||
// ensure that wwan is on
|
||||
if (enabled && !NetworkManager::isWwanEnabled()) {
|
||||
NetworkManager::setWwanEnabled(true);
|
||||
}
|
||||
|
||||
if (!m_nmModem) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
// enable mobile data...
|
||||
|
||||
m_nmModem->setAutoconnect(true);
|
||||
|
||||
// activate the connection that was last used
|
||||
QDateTime latestTimestamp;
|
||||
NetworkManager::Connection::Ptr latestCon;
|
||||
for (NetworkManager::Connection::Ptr con : m_nmModem->availableConnections()) {
|
||||
QDateTime timestamp = con->settings()->timestamp();
|
||||
// if con was not used yet, skip it, otherwise:
|
||||
// if we have no latestTimestamp yet, con is the latest
|
||||
// otherwise, compare the timestamps
|
||||
// in case of a tie, use the first connection that was found
|
||||
if (!timestamp.isNull() && (latestTimestamp.isNull() || timestamp > latestTimestamp)) {
|
||||
latestTimestamp = timestamp;
|
||||
latestCon = con;
|
||||
}
|
||||
}
|
||||
|
||||
// if we found the last used connection
|
||||
if (!latestCon.isNull()) {
|
||||
// set it to autoconnect and connect it immediately
|
||||
latestCon->settings()->setAutoconnect(true);
|
||||
latestCon->update(latestCon->settings()->toMap());
|
||||
NetworkManager::activateConnection(latestCon->path(), m_nmModem->uni(), "");
|
||||
}
|
||||
|
||||
} else {
|
||||
// disable mobile data...
|
||||
|
||||
// we do not call NetworkManager::setWwanEnabled(false), because it turns off cellular
|
||||
|
||||
// turn off autoconnect
|
||||
m_nmModem->setAutoconnect(false);
|
||||
// we need to also set all connections to not autoconnect (#182)
|
||||
for (NetworkManager::Connection::Ptr con : m_nmModem->availableConnections()) {
|
||||
con->settings()->setAutoconnect(false);
|
||||
con->update(con->settings()->toMap());
|
||||
}
|
||||
|
||||
// disconnect network
|
||||
m_nmModem->disconnectInterface();
|
||||
}
|
||||
}
|
||||
|
||||
bool Modem::isRoaming() const
|
||||
{
|
||||
if (!m_nmModem || !m_nmModem->activeConnection() || !m_nmModem->activeConnection()->connection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto connection = m_nmModem->activeConnection()->connection();
|
||||
NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).dynamicCast<NetworkManager::GsmSetting>();
|
||||
|
||||
return gsmSetting ? !gsmSetting->homeOnly() : false;
|
||||
}
|
||||
|
||||
QCoro::Task<void> Modem::setIsRoaming(bool roaming)
|
||||
{
|
||||
if (!m_nmModem || !m_nmModem->activeConnection() || !m_nmModem->activeConnection()->connection()) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
auto connection = m_nmModem->activeConnection()->connection();
|
||||
|
||||
NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).dynamicCast<NetworkManager::GsmSetting>();
|
||||
if (gsmSetting) {
|
||||
gsmSetting->setHomeOnly(!roaming); // set roaming setting
|
||||
|
||||
QDBusReply<void> reply = co_await connection->update(connection->settings()->toMap());
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error updating connection settings for") << connection->uuid() << QStringLiteral(":") << reply.error().message()
|
||||
<< QStringLiteral(".");
|
||||
CellularNetworkSettings::instance()->addMessage(
|
||||
InlineMessage::Error,
|
||||
i18n("Error updating connection settings for %1: %2.", connection->uuid(), reply.error().message()));
|
||||
} else {
|
||||
qDebug() << QStringLiteral("Successfully updated connection settings") << connection->uuid() << QStringLiteral(".");
|
||||
}
|
||||
}
|
||||
|
||||
// the connection uni has changed, refresh the profiles list
|
||||
refreshProfiles();
|
||||
Q_EMIT activeConnectionUniChanged();
|
||||
}
|
||||
|
||||
bool Modem::hasSim() const
|
||||
{
|
||||
if (!m_mmModem) {
|
||||
return false;
|
||||
}
|
||||
return m_mmModem && m_mmModem->sim() && m_mmModem->sim()->uni() != QStringLiteral("/");
|
||||
}
|
||||
|
||||
QList<ProfileSettings *> &Modem::profileList()
|
||||
{
|
||||
return m_profileList;
|
||||
}
|
||||
|
||||
void Modem::refreshProfiles()
|
||||
{
|
||||
m_profileList.clear();
|
||||
|
||||
if (!m_nmModem) {
|
||||
Q_EMIT profileListChanged();
|
||||
qWarning() << "No NetworkManager modem found, cannot refresh profiles.";
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto connection : m_nmModem->availableConnections()) {
|
||||
for (auto setting : connection->settings()->settings()) {
|
||||
if (setting.dynamicCast<NetworkManager::GsmSetting>()) {
|
||||
m_profileList.append(new ProfileSettings(this, setting.dynamicCast<NetworkManager::GsmSetting>(), connection));
|
||||
}
|
||||
}
|
||||
}
|
||||
Q_EMIT profileListChanged();
|
||||
}
|
||||
|
||||
QCoro::Task<void> Modem::activateProfile(const QString &connectionUni)
|
||||
{
|
||||
if (!m_nmModem) {
|
||||
qWarning() << "Cannot activate profile since there is no NetworkManager modem";
|
||||
co_return;
|
||||
}
|
||||
|
||||
qDebug() << QStringLiteral("Activating profile on modem") << m_nmModem->uni() << QStringLiteral("for connection") << connectionUni << ".";
|
||||
|
||||
// cache roaming setting
|
||||
bool roaming = isRoaming();
|
||||
|
||||
NetworkManager::Connection::Ptr con;
|
||||
|
||||
// disable autoconnect for all other connections
|
||||
for (auto connection : m_nmModem->availableConnections()) {
|
||||
if (connection->uuid() == connectionUni) {
|
||||
connection->settings()->setAutoconnect(true);
|
||||
con = connection;
|
||||
} else {
|
||||
connection->settings()->setAutoconnect(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!con) {
|
||||
qDebug() << QStringLiteral("Connection") << connectionUni << QStringLiteral("not found.");
|
||||
co_return;
|
||||
}
|
||||
|
||||
// activate connection manually
|
||||
// despite the documentation saying otherwise, activateConnection seems to need the DBus path, not uuid of the connection
|
||||
QDBusReply<QDBusObjectPath> reply = co_await NetworkManager::activateConnection(con->path(), m_nmModem->uni(), "");
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error activating connection:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error activating connection: %1", reply.error().message()));
|
||||
co_return;
|
||||
}
|
||||
|
||||
// set roaming settings separately (since it changes the uni)
|
||||
co_await setIsRoaming(roaming);
|
||||
}
|
||||
|
||||
QCoro::Task<void> Modem::addProfile(QString name, QString apn, QString username, QString password, QString networkType)
|
||||
{
|
||||
if (!m_nmModem) {
|
||||
qWarning() << "Cannot add profile since there is no NetworkManager modem";
|
||||
co_return;
|
||||
}
|
||||
|
||||
NetworkManager::ConnectionSettings::Ptr settings{new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Gsm)};
|
||||
settings->setId(name);
|
||||
settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid());
|
||||
settings->setAutoconnect(true);
|
||||
settings->addToPermissions(KUser().loginName(), QString());
|
||||
|
||||
NetworkManager::GsmSetting::Ptr gsmSetting = settings->setting(NetworkManager::Setting::Gsm).dynamicCast<NetworkManager::GsmSetting>();
|
||||
gsmSetting->setApn(apn);
|
||||
gsmSetting->setUsername(username);
|
||||
gsmSetting->setPassword(password);
|
||||
gsmSetting->setPasswordFlags(password.isEmpty() ? NetworkManager::Setting::NotRequired : NetworkManager::Setting::AgentOwned);
|
||||
gsmSetting->setNetworkType(ProfileSettings::networkTypeFlag(networkType));
|
||||
gsmSetting->setHomeOnly(!isRoaming());
|
||||
|
||||
gsmSetting->setInitialized(true);
|
||||
|
||||
NetworkManager::Ipv6Setting::Ptr ipv6Setting = settings->setting(NetworkManager::Setting::Ipv6).dynamicCast<NetworkManager::Ipv6Setting>();
|
||||
ipv6Setting->setMethod(NetworkManager::Ipv6Setting::ConfigMethod::Automatic);
|
||||
ipv6Setting->setInitialized(true);
|
||||
|
||||
QDBusReply<QDBusObjectPath> reply = co_await NetworkManager::addAndActivateConnection(settings->toMap(), m_nmModem->uni(), "");
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error adding connection:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error adding connection: %1", reply.error().message()));
|
||||
} else {
|
||||
qDebug() << QStringLiteral("Successfully added a new connection") << name << QStringLiteral("with APN") << apn << ".";
|
||||
}
|
||||
}
|
||||
|
||||
QCoro::Task<void> Modem::removeProfile(const QString &connectionUni)
|
||||
{
|
||||
NetworkManager::Connection::Ptr con = NetworkManager::findConnectionByUuid(connectionUni);
|
||||
if (!con) {
|
||||
qWarning() << QStringLiteral("Could not find connection") << connectionUni << QStringLiteral("to update!");
|
||||
co_return;
|
||||
}
|
||||
|
||||
QDBusReply<void> reply = co_await con->remove();
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error removing connection") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error removing connection: %1", reply.error().message()));
|
||||
}
|
||||
}
|
||||
|
||||
QCoro::Task<void> Modem::updateProfile(QString connectionUni, QString name, QString apn, QString username, QString password, QString networkType)
|
||||
{
|
||||
NetworkManager::Connection::Ptr con = NetworkManager::findConnectionByUuid(connectionUni);
|
||||
if (!con) {
|
||||
qWarning() << QStringLiteral("Could not find connection") << connectionUni << QStringLiteral("to update!");
|
||||
co_return;
|
||||
}
|
||||
|
||||
NetworkManager::ConnectionSettings::Ptr conSettings = con->settings();
|
||||
if (!conSettings) {
|
||||
qWarning() << QStringLiteral("Could not find connection settings for") << connectionUni << QStringLiteral("to update!");
|
||||
co_return;
|
||||
}
|
||||
|
||||
conSettings->setId(name);
|
||||
|
||||
NetworkManager::GsmSetting::Ptr gsmSetting = conSettings->setting(NetworkManager::Setting::Gsm).dynamicCast<NetworkManager::GsmSetting>();
|
||||
gsmSetting->setApn(apn);
|
||||
gsmSetting->setUsername(username);
|
||||
gsmSetting->setPassword(password);
|
||||
gsmSetting->setPasswordFlags(password == "" ? NetworkManager::Setting::NotRequired : NetworkManager::Setting::AgentOwned);
|
||||
gsmSetting->setNetworkType(ProfileSettings::networkTypeFlag(networkType));
|
||||
gsmSetting->setHomeOnly(!isRoaming());
|
||||
|
||||
gsmSetting->setInitialized(true);
|
||||
|
||||
NetworkManager::Ipv6Setting::Ptr ipv6Setting = conSettings->setting(NetworkManager::Setting::Ipv6).dynamicCast<NetworkManager::Ipv6Setting>();
|
||||
ipv6Setting->setMethod(NetworkManager::Ipv6Setting::ConfigMethod::Automatic);
|
||||
ipv6Setting->setInitialized(true);
|
||||
|
||||
QDBusReply<void> reply = con->update(conSettings->toMap());
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error updating connection settings for") << connectionUni << QStringLiteral(":") << reply.error().message()
|
||||
<< QStringLiteral(".");
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error,
|
||||
i18n("Error updating connection settings for %1: %2.", connectionUni, reply.error().message()));
|
||||
} else {
|
||||
qDebug() << QStringLiteral("Successfully updated connection settings") << connectionUni << QStringLiteral(".");
|
||||
}
|
||||
}
|
||||
|
||||
void Modem::addDetectedProfileSettings()
|
||||
{
|
||||
if (!m_mmModem) {
|
||||
qWarning() << "ModemManager device missing, cannot detect profile settings";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasSim() || !m_mmModem->sim()) {
|
||||
qWarning() << "No SIM found, cannot detect profile settings";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_mm3gppDevice) {
|
||||
qWarning() << "3gpp object not found, cannot detect profile settings";
|
||||
return;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
static MobileProviders mobileProviders{};
|
||||
|
||||
QString operatorCode = m_mmModem->sim()->operatorIdentifier();
|
||||
qWarning() << QStringLiteral("Detecting profile settings. Using MCCMNC:") << operatorCode;
|
||||
|
||||
// lookup apns with mccmnc codes
|
||||
for (QString &provider : mobileProviders.getProvidersFromMCCMNC(operatorCode)) {
|
||||
qWarning() << QStringLiteral("Provider:") << provider;
|
||||
|
||||
for (auto apn : mobileProviders.getApns(provider)) {
|
||||
QVariantMap apnInfo = mobileProviders.getApnInfo(apn);
|
||||
qWarning() << QStringLiteral("Found gsm profile settings. Type:") << apnInfo[QStringLiteral("usageType")];
|
||||
|
||||
// only add mobile data apns (not mms)
|
||||
if (apnInfo[QStringLiteral("usageType")].toString() == QStringLiteral("internet")) {
|
||||
found = true;
|
||||
|
||||
QString name = provider;
|
||||
if (!apnInfo[QStringLiteral("name")].isNull()) {
|
||||
name += " - " + apnInfo[QStringLiteral("name")].toString();
|
||||
}
|
||||
|
||||
addProfile(name,
|
||||
apn,
|
||||
apnInfo[QStringLiteral("username")].toString(),
|
||||
apnInfo[QStringLiteral("password")].toString(),
|
||||
QStringLiteral("4G/3G/2G"));
|
||||
}
|
||||
|
||||
// TODO in the future for MMS settings, add else if here for == "mms"
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
qDebug() << QStringLiteral("No profiles were found.");
|
||||
Q_EMIT couldNotAutodetectSettings();
|
||||
}
|
||||
}
|
||||
|
||||
QList<Sim *> Modem::sims()
|
||||
{
|
||||
return m_sims;
|
||||
}
|
||||
|
||||
ModemManager::ModemDevice::Ptr Modem::mmModemDevice()
|
||||
{
|
||||
return m_mmModem;
|
||||
}
|
||||
|
||||
NetworkManager::ModemDevice::Ptr Modem::nmModemDevice()
|
||||
{
|
||||
return m_nmModem;
|
||||
}
|
||||
|
||||
ModemManager::Modem::Ptr Modem::mmModemInterface()
|
||||
{
|
||||
return m_mmInterface;
|
||||
}
|
||||
|
||||
QString Modem::nmDeviceStateStr(NetworkManager::Device::State state)
|
||||
{
|
||||
if (state == NetworkManager::Device::State::UnknownState)
|
||||
return i18n("Unknown");
|
||||
else if (state == NetworkManager::Device::State::Unmanaged)
|
||||
return i18n("Unmanaged");
|
||||
else if (state == NetworkManager::Device::State::Unavailable)
|
||||
return i18n("Unavailable");
|
||||
else if (state == NetworkManager::Device::State::Disconnected)
|
||||
return i18n("Disconnected");
|
||||
else if (state == NetworkManager::Device::State::Preparing)
|
||||
return i18n("Preparing");
|
||||
else if (state == NetworkManager::Device::State::ConfiguringHardware)
|
||||
return i18n("ConfiguringHardware");
|
||||
else if (state == NetworkManager::Device::State::NeedAuth)
|
||||
return i18n("NeedAuth");
|
||||
else if (state == NetworkManager::Device::State::ConfiguringIp)
|
||||
return i18n("ConfiguringIp");
|
||||
else if (state == NetworkManager::Device::State::CheckingIp)
|
||||
return i18n("CheckingIp");
|
||||
else if (state == NetworkManager::Device::State::WaitingForSecondaries)
|
||||
return i18n("WaitingForSecondaries");
|
||||
else if (state == NetworkManager::Device::State::Activated)
|
||||
return i18n("Activated");
|
||||
else if (state == NetworkManager::Device::State::Deactivating)
|
||||
return i18n("Deactivating");
|
||||
else if (state == NetworkManager::Device::State::Failed)
|
||||
return i18n("Failed");
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021-2022 Devin Lin <espidev@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cellularnetworksettings.h"
|
||||
#include "modemdetails.h"
|
||||
#include "profilesettings.h"
|
||||
#include "sim.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include <NetworkManagerQt/CdmaSetting>
|
||||
#include <NetworkManagerQt/ConnectionSettings>
|
||||
#include <NetworkManagerQt/GsmSetting>
|
||||
#include <NetworkManagerQt/Ipv6Setting>
|
||||
#include <NetworkManagerQt/Manager>
|
||||
#include <NetworkManagerQt/ModemDevice>
|
||||
#include <NetworkManagerQt/Settings>
|
||||
|
||||
#include <ModemManagerQt/GenericTypes>
|
||||
#include <ModemManagerQt/Manager>
|
||||
#include <ModemManagerQt/Modem3Gpp>
|
||||
#include <ModemManagerQt/ModemDevice>
|
||||
|
||||
#include <QCoroDBusPendingReply>
|
||||
|
||||
class ProfileSettings;
|
||||
class Sim;
|
||||
class AvailableNetwork;
|
||||
class ModemDetails;
|
||||
class MobileProviders;
|
||||
|
||||
// only supports GSM/UMTS/LTE
|
||||
class Modem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(ModemDetails *details READ modemDetails NOTIFY modemDetailsChanged)
|
||||
Q_PROPERTY(QString uni READ uni NOTIFY uniChanged)
|
||||
Q_PROPERTY(QString displayId READ displayId NOTIFY displayIdChanged)
|
||||
|
||||
Q_PROPERTY(bool isRoaming READ isRoaming WRITE setIsRoaming NOTIFY isRoamingChanged)
|
||||
Q_PROPERTY(bool hasSim READ hasSim NOTIFY hasSimChanged)
|
||||
Q_PROPERTY(QList<ProfileSettings *> profiles READ profileList NOTIFY profileListChanged)
|
||||
Q_PROPERTY(QString activeConnectionUni READ activeConnectionUni NOTIFY activeConnectionUniChanged)
|
||||
|
||||
Q_PROPERTY(bool mobileDataEnabled READ mobileDataEnabled WRITE setMobileDataEnabled NOTIFY mobileDataEnabledChanged)
|
||||
Q_PROPERTY(bool mobileDataSupported READ mobileDataSupported NOTIFY mobileDataSupportedChanged)
|
||||
Q_PROPERTY(bool needsAPNAdded READ needsAPNAdded NOTIFY mobileDataEnabledChanged)
|
||||
|
||||
public:
|
||||
Modem(QObject *parent = nullptr);
|
||||
Modem(QObject *parent, ModemManager::ModemDevice::Ptr mmModem, ModemManager::Modem::Ptr m_mmInterface);
|
||||
|
||||
ModemDetails *modemDetails() const;
|
||||
QString displayId() const; // splits uni and obtains the number suffix
|
||||
QString uni() const;
|
||||
QString activeConnectionUni() const;
|
||||
|
||||
Q_INVOKABLE QCoro::Task<void> reset();
|
||||
|
||||
bool mobileDataEnabled() const;
|
||||
void setMobileDataEnabled(bool enabled);
|
||||
bool mobileDataSupported() const;
|
||||
bool needsAPNAdded() const;
|
||||
|
||||
bool isRoaming() const;
|
||||
QCoro::Task<void> setIsRoaming(bool roaming);
|
||||
bool hasSim() const;
|
||||
|
||||
// connection profiles
|
||||
QList<ProfileSettings *> &profileList();
|
||||
void refreshProfiles();
|
||||
Q_INVOKABLE QCoro::Task<void> activateProfile(const QString &connectionUni);
|
||||
Q_INVOKABLE QCoro::Task<void> addProfile(QString name, QString apn, QString username, QString password, QString networkType);
|
||||
Q_INVOKABLE QCoro::Task<void> removeProfile(const QString &connectionUni);
|
||||
Q_INVOKABLE QCoro::Task<void> updateProfile(QString connectionUni, QString name, QString apn, QString username, QString password, QString networkType);
|
||||
Q_INVOKABLE void addDetectedProfileSettings(); // detect modem connection settings (ex. apn) and add a new connection
|
||||
|
||||
QList<Sim *> sims();
|
||||
|
||||
ModemManager::ModemDevice::Ptr mmModemDevice();
|
||||
NetworkManager::ModemDevice::Ptr nmModemDevice();
|
||||
ModemManager::Modem::Ptr mmModemInterface();
|
||||
|
||||
Q_SIGNALS:
|
||||
void modemDetailsChanged();
|
||||
void uniChanged();
|
||||
void displayIdChanged();
|
||||
void activeConnectionUniChanged();
|
||||
|
||||
void nmModemChanged();
|
||||
|
||||
void mobileDataEnabledChanged();
|
||||
void mobileDataSupportedChanged();
|
||||
void isRoamingChanged();
|
||||
void simsChanged();
|
||||
void hasSimChanged();
|
||||
void profileListChanged();
|
||||
|
||||
void couldNotAutodetectSettings();
|
||||
|
||||
private:
|
||||
void findNetworkManagerDevice();
|
||||
|
||||
QString nmDeviceStateStr(NetworkManager::Device::State state);
|
||||
|
||||
ModemDetails *m_details;
|
||||
|
||||
ModemManager::ModemDevice::Ptr m_mmModem;
|
||||
NetworkManager::ModemDevice::Ptr m_nmModem; // may be a nullptr if the nm modem hasn't been found yet
|
||||
ModemManager::Modem::Ptr m_mmInterface = nullptr;
|
||||
ModemManager::Modem3gpp::Ptr m_mm3gppDevice = nullptr; // this may be a nullptr if no sim is inserted
|
||||
|
||||
QList<Sim *> m_sims;
|
||||
QList<ProfileSettings *> m_profileList;
|
||||
|
||||
friend class ModemDetails;
|
||||
};
|
||||
|
|
@ -1,554 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "modemdetails.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QDBusPendingCallWatcher>
|
||||
|
||||
ModemDetails::ModemDetails(QObject *parent, Modem *modem)
|
||||
: QObject{parent}
|
||||
, m_modem{modem}
|
||||
, m_scanNetworkWatcher{nullptr}
|
||||
, m_isScanningNetworks{false}
|
||||
, m_cachedScannedNetworks{}
|
||||
{
|
||||
auto mmInterfacePointer = m_modem->m_mmInterface.data();
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::accessTechnologiesChanged, this, [this]() -> void {
|
||||
Q_EMIT accessTechnologiesChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::deviceChanged, this, [this]() -> void {
|
||||
Q_EMIT deviceChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::deviceIdentifierChanged, this, [this]() -> void {
|
||||
Q_EMIT deviceIdentifierChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::driversChanged, this, [this]() -> void {
|
||||
Q_EMIT driversChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::equipmentIdentifierChanged, this, [this]() -> void {
|
||||
Q_EMIT equipmentIdentifierChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::manufacturerChanged, this, [this]() -> void {
|
||||
Q_EMIT manufacturerChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::modelChanged, this, [this]() -> void {
|
||||
Q_EMIT modelChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::ownNumbersChanged, this, [this]() -> void {
|
||||
Q_EMIT ownNumbersChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::pluginChanged, this, [this]() -> void {
|
||||
Q_EMIT pluginChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::powerStateChanged, this, [this]() -> void {
|
||||
Q_EMIT powerStateChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::revisionChanged, this, [this]() -> void {
|
||||
Q_EMIT revisionChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::signalQualityChanged, this, [this]() -> void {
|
||||
Q_EMIT signalQualityChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::simPathChanged, this, [this]() -> void {
|
||||
Q_EMIT simPathChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::stateChanged, this, [this]() -> void {
|
||||
Q_EMIT stateChanged();
|
||||
});
|
||||
connect(mmInterfacePointer, &ModemManager::Modem::stateFailedReasonChanged, this, [this]() -> void {
|
||||
Q_EMIT stateFailedReasonChanged();
|
||||
});
|
||||
|
||||
if (m_modem->m_mm3gppDevice) {
|
||||
connect(m_modem->m_mm3gppDevice.data(), &ModemManager::Modem3gpp::operatorCodeChanged, this, [this]() -> void {
|
||||
Q_EMIT operatorCodeChanged();
|
||||
});
|
||||
connect(m_modem->m_mm3gppDevice.data(), &ModemManager::Modem3gpp::operatorNameChanged, this, [this]() -> void {
|
||||
Q_EMIT operatorNameChanged();
|
||||
});
|
||||
connect(m_modem->m_mm3gppDevice.data(), &ModemManager::Modem3gpp::registrationStateChanged, this, [this]() -> void {
|
||||
Q_EMIT registrationStateChanged();
|
||||
Q_EMIT m_modem->isRoamingChanged();
|
||||
});
|
||||
} else {
|
||||
qWarning() << QStringLiteral("3gpp device not found!");
|
||||
}
|
||||
|
||||
// m_modem->m_nmModem may be nullptr, listen for updates
|
||||
connect(m_modem, &Modem::nmModemChanged, this, &ModemDetails::updateNMSignals);
|
||||
updateNMSignals();
|
||||
}
|
||||
|
||||
void ModemDetails::updateNMSignals()
|
||||
{
|
||||
if (m_modem->m_nmModem) {
|
||||
connect(m_modem->m_nmModem.data(), &NetworkManager::ModemDevice::firmwareVersionChanged, this, [this]() -> void {
|
||||
Q_EMIT firmwareVersionChanged();
|
||||
});
|
||||
connect(m_modem->m_nmModem.data(), &NetworkManager::ModemDevice::interfaceNameChanged, this, [this]() -> void {
|
||||
Q_EMIT interfaceNameChanged();
|
||||
});
|
||||
connect(m_modem->m_nmModem.data(), &NetworkManager::ModemDevice::meteredChanged, this, [this]() -> void {
|
||||
Q_EMIT meteredChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ModemDetails &ModemDetails::operator=(ModemDetails &&other)
|
||||
{
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ModemDetails::swap(ModemDetails &other)
|
||||
{
|
||||
std::swap(m_modem, other.m_modem);
|
||||
std::swap(m_cachedScannedNetworks, other.m_cachedScannedNetworks);
|
||||
std::swap(m_isScanningNetworks, other.m_isScanningNetworks);
|
||||
std::swap(m_scanNetworkWatcher, other.m_scanNetworkWatcher);
|
||||
}
|
||||
|
||||
QStringList ModemDetails::accessTechnologies()
|
||||
{
|
||||
QStringList list;
|
||||
auto flags = m_modem->m_mmInterface->accessTechnologies();
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN) {
|
||||
list.push_back(i18n("Unknown"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_POTS) {
|
||||
list.push_back(i18n("POTS"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_GSM) {
|
||||
list.push_back(i18n("GSM"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT) {
|
||||
list.push_back(i18n("GSM Compact"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_GPRS) {
|
||||
list.push_back(i18n("GPRS"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_EDGE) {
|
||||
list.push_back(i18n("EDGE"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_UMTS) {
|
||||
list.push_back(i18n("UMTS"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_HSDPA) {
|
||||
list.push_back(i18n("HSDPA"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_HSUPA) {
|
||||
list.push_back(i18n("HSUPA"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_HSPA) {
|
||||
list.push_back(i18n("HSPA"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS) {
|
||||
list.push_back(i18n("HSPA+"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_1XRTT) {
|
||||
list.push_back(i18n("CDMA2000 1xRTT"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_EVDO0) {
|
||||
list.push_back(i18n("CDMA2000 EVDO-0"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_EVDOA) {
|
||||
list.push_back(i18n("CDMA2000 EVDO-A"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_EVDOB) {
|
||||
list.push_back(i18n("CDMA2000 EVDO-B"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
|
||||
list.push_back(i18n("LTE"));
|
||||
}
|
||||
if (flags & MM_MODEM_ACCESS_TECHNOLOGY_5GNR) {
|
||||
list.push_back(i18n("5GNR"));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
QString ModemDetails::device()
|
||||
{
|
||||
return m_modem->m_mmInterface->device();
|
||||
}
|
||||
|
||||
QString ModemDetails::deviceIdentifier()
|
||||
{
|
||||
return m_modem->m_mmInterface->deviceIdentifier();
|
||||
}
|
||||
|
||||
QStringList ModemDetails::drivers()
|
||||
{
|
||||
return m_modem->m_mmInterface->drivers();
|
||||
}
|
||||
|
||||
QString ModemDetails::equipmentIdentifier()
|
||||
{
|
||||
return m_modem->m_mmInterface->equipmentIdentifier();
|
||||
}
|
||||
|
||||
bool ModemDetails::isEnabled()
|
||||
{
|
||||
return m_modem->m_mmInterface->isEnabled();
|
||||
}
|
||||
|
||||
QString ModemDetails::manufacturer()
|
||||
{
|
||||
return m_modem->m_mmInterface->manufacturer();
|
||||
}
|
||||
|
||||
QString ModemDetails::model()
|
||||
{
|
||||
return m_modem->m_mmInterface->model();
|
||||
}
|
||||
|
||||
QStringList ModemDetails::ownNumbers()
|
||||
{
|
||||
return m_modem->m_mmInterface->ownNumbers();
|
||||
}
|
||||
|
||||
QString ModemDetails::plugin()
|
||||
{
|
||||
return m_modem->m_mmInterface->plugin();
|
||||
}
|
||||
|
||||
QString ModemDetails::powerState()
|
||||
{
|
||||
switch (m_modem->m_mmInterface->powerState()) {
|
||||
case MM_MODEM_POWER_STATE_UNKNOWN:
|
||||
return i18n("Unknown");
|
||||
case MM_MODEM_POWER_STATE_OFF:
|
||||
return i18n("Off");
|
||||
case MM_MODEM_POWER_STATE_LOW:
|
||||
return i18n("Low-power mode");
|
||||
case MM_MODEM_POWER_STATE_ON:
|
||||
return i18n("Full power mode");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ModemDetails::revision()
|
||||
{
|
||||
return m_modem->m_mmInterface->revision();
|
||||
}
|
||||
|
||||
uint ModemDetails::signalQuality()
|
||||
{
|
||||
return m_modem->m_mmInterface->signalQuality().signal;
|
||||
}
|
||||
|
||||
QString ModemDetails::simPath()
|
||||
{
|
||||
return m_modem->m_mmInterface->simPath();
|
||||
}
|
||||
|
||||
QString ModemDetails::state()
|
||||
{
|
||||
switch (m_modem->m_mmInterface->state()) {
|
||||
case MM_MODEM_STATE_FAILED:
|
||||
return i18n("Failed");
|
||||
case MM_MODEM_STATE_UNKNOWN:
|
||||
return i18n("Unknown");
|
||||
case MM_MODEM_STATE_INITIALIZING:
|
||||
return i18n("Initializing");
|
||||
case MM_MODEM_STATE_LOCKED:
|
||||
return i18n("Locked");
|
||||
case MM_MODEM_STATE_DISABLED:
|
||||
return i18n("Disabled");
|
||||
case MM_MODEM_STATE_DISABLING:
|
||||
return i18n("Disabling");
|
||||
case MM_MODEM_STATE_ENABLING:
|
||||
return i18n("Enabling");
|
||||
case MM_MODEM_STATE_ENABLED:
|
||||
return i18n("Enabled");
|
||||
case MM_MODEM_STATE_SEARCHING:
|
||||
return i18n("Searching for network provider");
|
||||
case MM_MODEM_STATE_REGISTERED:
|
||||
return i18n("Registered with network provider");
|
||||
case MM_MODEM_STATE_DISCONNECTING:
|
||||
return i18n("Disconnecting");
|
||||
case MM_MODEM_STATE_CONNECTING:
|
||||
return i18n("Connecting");
|
||||
case MM_MODEM_STATE_CONNECTED:
|
||||
return i18n("Connected");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ModemDetails::stateFailedReason()
|
||||
{
|
||||
switch (m_modem->m_mmInterface->stateFailedReason()) {
|
||||
case MM_MODEM_STATE_FAILED_REASON_NONE:
|
||||
return i18n("No error.");
|
||||
case MM_MODEM_STATE_FAILED_REASON_UNKNOWN:
|
||||
return i18n("Unknown error.");
|
||||
case MM_MODEM_STATE_FAILED_REASON_SIM_MISSING:
|
||||
return i18n("SIM is required but missing.");
|
||||
case MM_MODEM_STATE_FAILED_REASON_SIM_ERROR:
|
||||
return i18n("SIM is available but unusable.");
|
||||
case MM_MODEM_STATE_FAILED_REASON_UNKNOWN_CAPABILITIES:
|
||||
return i18n("Unknown modem capabilities.");
|
||||
case MM_MODEM_STATE_FAILED_REASON_ESIM_WITHOUT_PROFILES:
|
||||
return i18n("eSIM is not initialized.");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ModemDetails::operatorCode()
|
||||
{
|
||||
return m_modem->m_mm3gppDevice ? m_modem->m_mm3gppDevice->operatorCode() : QString{};
|
||||
}
|
||||
|
||||
QString ModemDetails::operatorName()
|
||||
{
|
||||
return m_modem->m_mm3gppDevice ? m_modem->m_mm3gppDevice->operatorName() : QString{};
|
||||
}
|
||||
|
||||
QString ModemDetails::registrationState()
|
||||
{
|
||||
if (!m_modem->m_mm3gppDevice) {
|
||||
return QString{};
|
||||
}
|
||||
|
||||
switch (m_modem->m_mm3gppDevice->registrationState()) {
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_IDLE:
|
||||
return i18n("Not registered, not searching for new operator to register.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_HOME:
|
||||
return i18n("Registered on home network.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING:
|
||||
return i18n("Not registered, searching for new operator to register with.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_DENIED:
|
||||
return i18n("Registration denied.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN:
|
||||
return i18n("Unknown registration status.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
|
||||
return i18n("Registered on a roaming network.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY:
|
||||
return i18n("Registered for \"SMS only\", on home network.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_SMS_ONLY:
|
||||
return i18n("Registered for \"SMS only\", roaming network.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY:
|
||||
return i18n("Emergency services only.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED:
|
||||
return i18n("Registered for \"CSFB not preferred\", home network.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED:
|
||||
return i18n("Registered for \"CSFB not preferred\", roaming network.");
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS:
|
||||
return i18n("Attached for access to Restricted Local Operator Services.");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(MMModem3gppNetworkAvailability)
|
||||
Q_DECLARE_METATYPE(MMModemAccessTechnology)
|
||||
|
||||
QList<AvailableNetwork *> ModemDetails::networks()
|
||||
{
|
||||
return m_cachedScannedNetworks;
|
||||
}
|
||||
|
||||
Q_INVOKABLE void ModemDetails::scanNetworks()
|
||||
{
|
||||
for (auto p : m_cachedScannedNetworks) {
|
||||
p->deleteLater();
|
||||
}
|
||||
m_cachedScannedNetworks.clear();
|
||||
|
||||
if (m_modem->m_mm3gppDevice) {
|
||||
qDebug() << QStringLiteral("Scanning for available networks...");
|
||||
|
||||
QDBusPendingReply<ModemManager::QVariantMapList> reply = m_modem->m_mm3gppDevice->scan();
|
||||
|
||||
m_isScanningNetworks = true;
|
||||
Q_EMIT isScanningNetworksChanged();
|
||||
m_scanNetworkWatcher = new QDBusPendingCallWatcher(reply, this);
|
||||
connect(m_scanNetworkWatcher, &QDBusPendingCallWatcher::finished, this, &ModemDetails::scanNetworksFinished);
|
||||
}
|
||||
|
||||
Q_EMIT networksChanged();
|
||||
}
|
||||
|
||||
void ModemDetails::scanNetworksFinished(QDBusPendingCallWatcher *call)
|
||||
{
|
||||
QDBusPendingReply<ModemManager::QVariantMapList> reply = *call;
|
||||
if (reply.isError()) {
|
||||
qDebug() << QStringLiteral("Scanning failed:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Scanning networks failed: %1", reply.error().message()));
|
||||
} else {
|
||||
ModemManager::QVariantMapList list = reply.value();
|
||||
|
||||
for (auto &var : list) {
|
||||
auto status = var[QStringLiteral("status")].value<MMModem3gppNetworkAvailability>();
|
||||
|
||||
if (status == MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT || status == MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE) {
|
||||
auto network = new AvailableNetwork{this,
|
||||
m_modem->m_mm3gppDevice,
|
||||
status == MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT,
|
||||
var[QStringLiteral("operator-long")].toString(),
|
||||
var[QStringLiteral("operator-short")].toString(),
|
||||
var[QStringLiteral("operator-code")].toString(),
|
||||
var[QStringLiteral("access-technology")].value<MMModemAccessTechnology>()};
|
||||
m_cachedScannedNetworks.push_back(network);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_isScanningNetworks = false;
|
||||
Q_EMIT networksChanged();
|
||||
Q_EMIT isScanningNetworksChanged();
|
||||
|
||||
call->deleteLater();
|
||||
}
|
||||
|
||||
bool ModemDetails::isScanningNetworks()
|
||||
{
|
||||
return m_isScanningNetworks;
|
||||
}
|
||||
|
||||
QString ModemDetails::firmwareVersion()
|
||||
{
|
||||
if (!m_modem->m_nmModem) {
|
||||
return QString{};
|
||||
}
|
||||
return m_modem->m_nmModem->firmwareVersion();
|
||||
}
|
||||
|
||||
QString ModemDetails::interfaceName()
|
||||
{
|
||||
if (!m_modem->m_nmModem) {
|
||||
return QString{};
|
||||
}
|
||||
return m_modem->m_nmModem->interfaceName();
|
||||
}
|
||||
|
||||
QString ModemDetails::metered()
|
||||
{
|
||||
if (!m_modem->m_nmModem) {
|
||||
return QString{};
|
||||
}
|
||||
|
||||
switch (m_modem->m_nmModem->metered()) {
|
||||
case NetworkManager::Device::MeteredStatus::UnknownStatus:
|
||||
return i18n("Unknown");
|
||||
case NetworkManager::Device::MeteredStatus::Yes:
|
||||
return i18n("Yes");
|
||||
case NetworkManager::Device::MeteredStatus::No:
|
||||
return i18n("No");
|
||||
case NetworkManager::Device::MeteredStatus::GuessYes:
|
||||
return i18n("GuessYes");
|
||||
case NetworkManager::Device::MeteredStatus::GuessNo:
|
||||
return i18n("GuessNo");
|
||||
}
|
||||
return QString{};
|
||||
}
|
||||
|
||||
AvailableNetwork::AvailableNetwork(QObject *parent,
|
||||
ModemManager::Modem3gpp::Ptr mm3gppDevice,
|
||||
bool isCurrentlyUsed,
|
||||
QString operatorLong,
|
||||
QString operatorShort,
|
||||
QString operatorCode,
|
||||
MMModemAccessTechnology accessTechnology)
|
||||
: QObject{parent}
|
||||
, m_isCurrentlyUsed{isCurrentlyUsed}
|
||||
, m_operatorLong{operatorLong}
|
||||
, m_operatorShort{operatorShort}
|
||||
, m_operatorCode{operatorCode}
|
||||
, m_accessTechnology{}
|
||||
, m_mm3gppDevice{mm3gppDevice}
|
||||
{
|
||||
switch (accessTechnology) {
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN:
|
||||
m_accessTechnology = i18n("Unknown");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_POTS:
|
||||
m_accessTechnology = i18n("POTS");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_GSM:
|
||||
m_accessTechnology = i18n("2G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT:
|
||||
m_accessTechnology = i18n("2G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_GPRS:
|
||||
m_accessTechnology = i18n("2G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_EDGE:
|
||||
m_accessTechnology = i18n("2G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_UMTS:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_HSDPA:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_HSUPA:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_HSPA:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_1XRTT:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_EVDO0:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_EVDOA:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_EVDOB:
|
||||
m_accessTechnology = i18n("3G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_LTE:
|
||||
m_accessTechnology = i18n("4G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_5GNR:
|
||||
m_accessTechnology = i18n("5G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_ANY:
|
||||
m_accessTechnology = i18n("Any");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_LTE_CAT_M:
|
||||
m_accessTechnology = i18n("4G");
|
||||
break;
|
||||
case MM_MODEM_ACCESS_TECHNOLOGY_LTE_NB_IOT:
|
||||
m_accessTechnology = i18n("4G");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool AvailableNetwork::isCurrentlyUsed()
|
||||
{
|
||||
return m_isCurrentlyUsed;
|
||||
}
|
||||
|
||||
QString AvailableNetwork::operatorLong()
|
||||
{
|
||||
return m_operatorLong;
|
||||
}
|
||||
|
||||
QString AvailableNetwork::operatorShort()
|
||||
{
|
||||
return m_operatorShort;
|
||||
}
|
||||
|
||||
QString AvailableNetwork::operatorCode()
|
||||
{
|
||||
return m_operatorCode;
|
||||
}
|
||||
|
||||
QString AvailableNetwork::accessTechnology()
|
||||
{
|
||||
return m_accessTechnology;
|
||||
}
|
||||
|
||||
void AvailableNetwork::registerToNetwork()
|
||||
{
|
||||
if (!m_isCurrentlyUsed && m_mm3gppDevice) {
|
||||
m_mm3gppDevice->registerToNetwork(m_operatorCode);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "modem.h"
|
||||
#include "sim.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include <NetworkManagerQt/CdmaSetting>
|
||||
#include <NetworkManagerQt/ConnectionSettings>
|
||||
#include <NetworkManagerQt/GsmSetting>
|
||||
#include <NetworkManagerQt/Manager>
|
||||
#include <NetworkManagerQt/ModemDevice>
|
||||
#include <NetworkManagerQt/Settings>
|
||||
|
||||
#include <ModemManagerQt/GenericTypes>
|
||||
#include <ModemManagerQt/Manager>
|
||||
#include <ModemManagerQt/Modem3Gpp>
|
||||
#include <ModemManagerQt/ModemDevice>
|
||||
|
||||
class Modem;
|
||||
class AvailableNetwork;
|
||||
|
||||
class ModemDetails : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
// modemmanager device
|
||||
Q_PROPERTY(QStringList accessTechnologies READ accessTechnologies NOTIFY accessTechnologiesChanged) // currently used tech
|
||||
Q_PROPERTY(QString device READ device NOTIFY deviceChanged)
|
||||
Q_PROPERTY(QString deviceIdentifier READ deviceIdentifier NOTIFY deviceIdentifierChanged)
|
||||
Q_PROPERTY(QStringList drivers READ drivers NOTIFY driversChanged)
|
||||
Q_PROPERTY(QString equipmentIdentifier READ equipmentIdentifier NOTIFY equipmentIdentifierChanged)
|
||||
// TODO add bands
|
||||
Q_PROPERTY(bool isEnabled READ isEnabled NOTIFY isEnabledChanged)
|
||||
Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged)
|
||||
Q_PROPERTY(QString model READ model NOTIFY modelChanged)
|
||||
Q_PROPERTY(QStringList ownNumbers READ ownNumbers NOTIFY ownNumbersChanged)
|
||||
Q_PROPERTY(QString plugin READ plugin NOTIFY pluginChanged)
|
||||
Q_PROPERTY(QString powerState READ powerState NOTIFY powerStateChanged)
|
||||
Q_PROPERTY(QString revision READ revision NOTIFY revisionChanged)
|
||||
Q_PROPERTY(uint signalQuality READ signalQuality NOTIFY signalQualityChanged)
|
||||
Q_PROPERTY(QString simPath READ simPath NOTIFY simPathChanged)
|
||||
Q_PROPERTY(QString state READ state NOTIFY stateChanged)
|
||||
Q_PROPERTY(QString stateFailedReason READ stateFailedReason NOTIFY stateFailedReasonChanged)
|
||||
|
||||
// modemmanager 3gpp device
|
||||
Q_PROPERTY(QString operatorCode READ operatorCode NOTIFY operatorCodeChanged)
|
||||
Q_PROPERTY(QString operatorName READ operatorName NOTIFY operatorNameChanged)
|
||||
Q_PROPERTY(QString registrationState READ registrationState NOTIFY registrationStateChanged)
|
||||
Q_PROPERTY(QList<AvailableNetwork *> networks READ networks NOTIFY networksChanged)
|
||||
Q_PROPERTY(bool isScanningNetworks READ isScanningNetworks NOTIFY isScanningNetworksChanged)
|
||||
|
||||
// networkmanager device
|
||||
Q_PROPERTY(QString firmwareVersion READ firmwareVersion NOTIFY firmwareVersionChanged)
|
||||
Q_PROPERTY(QString interfaceName READ interfaceName NOTIFY interfaceNameChanged)
|
||||
Q_PROPERTY(QString metered READ metered NOTIFY meteredChanged)
|
||||
|
||||
public:
|
||||
ModemDetails(QObject *parent = nullptr, Modem *modem = nullptr);
|
||||
ModemDetails &operator=(ModemDetails &&other);
|
||||
void swap(ModemDetails &other);
|
||||
|
||||
QStringList accessTechnologies();
|
||||
QString device();
|
||||
QString deviceIdentifier();
|
||||
QStringList drivers();
|
||||
QString equipmentIdentifier();
|
||||
bool isEnabled();
|
||||
QString manufacturer();
|
||||
uint maxActiveBearers();
|
||||
uint maxBearers();
|
||||
QString model();
|
||||
QStringList ownNumbers();
|
||||
QString plugin();
|
||||
QString powerState();
|
||||
QString revision();
|
||||
uint signalQuality();
|
||||
QString simPath();
|
||||
QString state();
|
||||
QString stateFailedReason();
|
||||
|
||||
QString operatorCode();
|
||||
QString operatorName();
|
||||
QString registrationState();
|
||||
|
||||
Q_INVOKABLE void scanNetworks();
|
||||
QList<AvailableNetwork *> networks();
|
||||
bool isScanningNetworks();
|
||||
void scanNetworksFinished(QDBusPendingCallWatcher *call);
|
||||
|
||||
QString firmwareVersion();
|
||||
QString interfaceName();
|
||||
QString metered();
|
||||
|
||||
Q_SIGNALS:
|
||||
void accessTechnologiesChanged();
|
||||
void deviceChanged();
|
||||
void deviceIdentifierChanged();
|
||||
void driversChanged();
|
||||
void equipmentIdentifierChanged();
|
||||
void isEnabledChanged();
|
||||
void manufacturerChanged();
|
||||
void modelChanged();
|
||||
void ownNumbersChanged();
|
||||
void pluginChanged();
|
||||
void powerStateChanged();
|
||||
void revisionChanged();
|
||||
void signalQualityChanged();
|
||||
void simPathChanged();
|
||||
void stateChanged();
|
||||
void stateFailedReasonChanged();
|
||||
void supportedCapabilitiesChanged();
|
||||
|
||||
void operatorCodeChanged();
|
||||
void operatorNameChanged();
|
||||
void registrationStateChanged();
|
||||
void networksChanged();
|
||||
void isScanningNetworksChanged();
|
||||
|
||||
void firmwareVersionChanged();
|
||||
void interfaceNameChanged();
|
||||
void meteredChanged();
|
||||
|
||||
private:
|
||||
void updateNMSignals();
|
||||
|
||||
Modem *m_modem;
|
||||
|
||||
QDBusPendingCallWatcher *m_scanNetworkWatcher;
|
||||
bool m_isScanningNetworks;
|
||||
QList<AvailableNetwork *> m_cachedScannedNetworks;
|
||||
};
|
||||
|
||||
class AvailableNetwork : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool isCurrentlyUsed READ isCurrentlyUsed NOTIFY isCurrentlyUsedChanged)
|
||||
Q_PROPERTY(QString operatorLong READ operatorLong NOTIFY operatorLongChanged)
|
||||
Q_PROPERTY(QString operatorShort READ operatorShort NOTIFY operatorShortChanged)
|
||||
Q_PROPERTY(QString operatorCode READ operatorCode NOTIFY operatorCodeChanged)
|
||||
Q_PROPERTY(QString accessTechnology READ accessTechnology NOTIFY accessTechnologyChanged)
|
||||
|
||||
public:
|
||||
AvailableNetwork(QObject *parent = nullptr,
|
||||
ModemManager::Modem3gpp::Ptr mm3gppDevice = nullptr,
|
||||
bool isCurrentlyUsed = false,
|
||||
QString operatorLong = "",
|
||||
QString operatorShort = "",
|
||||
QString operatorCode = "",
|
||||
MMModemAccessTechnology accessTechnology = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
|
||||
bool isCurrentlyUsed();
|
||||
QString operatorLong();
|
||||
QString operatorShort();
|
||||
QString operatorCode();
|
||||
QString accessTechnology();
|
||||
|
||||
Q_INVOKABLE void registerToNetwork();
|
||||
|
||||
Q_SIGNALS:
|
||||
void isCurrentlyUsedChanged();
|
||||
void operatorLongChanged();
|
||||
void operatorShortChanged();
|
||||
void operatorCodeChanged();
|
||||
void accessTechnologyChanged();
|
||||
|
||||
private:
|
||||
bool m_isCurrentlyUsed;
|
||||
QString m_operatorLong;
|
||||
QString m_operatorShort;
|
||||
QString m_operatorCode;
|
||||
QString m_accessTechnology;
|
||||
|
||||
ModemManager::Modem3gpp::Ptr m_mm3gppDevice; // this may be a nullptr if no sim is inserted
|
||||
};
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "profilesettings.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
ProfileSettings::ProfileSettings(QObject *parent,
|
||||
QString name,
|
||||
QString apn,
|
||||
QString user,
|
||||
QString password,
|
||||
NetworkManager::GsmSetting::NetworkType networkType,
|
||||
QString connectionUni)
|
||||
: QObject{parent}
|
||||
, m_name(name)
|
||||
, m_apn(apn)
|
||||
, m_user(user)
|
||||
, m_password(password)
|
||||
, m_networkType(networkTypeStr(networkType))
|
||||
, m_connectionUni(connectionUni)
|
||||
{
|
||||
setParent(parent);
|
||||
}
|
||||
|
||||
ProfileSettings::ProfileSettings(QObject *parent, NetworkManager::Setting::Ptr setting, NetworkManager::Connection::Ptr connection)
|
||||
: QObject{parent}
|
||||
, m_connectionUni(connection->uuid())
|
||||
{
|
||||
setParent(parent);
|
||||
|
||||
NetworkManager::GsmSetting::Ptr gsmSetting = setting.staticCast<NetworkManager::GsmSetting>();
|
||||
|
||||
m_name = connection->name();
|
||||
m_apn = gsmSetting->apn();
|
||||
m_user = gsmSetting->username();
|
||||
m_password = gsmSetting->password();
|
||||
m_networkType = networkTypeStr(gsmSetting->networkType());
|
||||
}
|
||||
|
||||
QString ProfileSettings::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
QString ProfileSettings::apn()
|
||||
{
|
||||
return m_apn;
|
||||
}
|
||||
|
||||
void ProfileSettings::setApn(QString apn)
|
||||
{
|
||||
if (apn != m_apn) {
|
||||
m_apn = apn;
|
||||
Q_EMIT apnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString ProfileSettings::user()
|
||||
{
|
||||
return m_user;
|
||||
}
|
||||
|
||||
void ProfileSettings::setUser(QString user)
|
||||
{
|
||||
if (user != m_user) {
|
||||
m_user = user;
|
||||
Q_EMIT userChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString ProfileSettings::password()
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
|
||||
void ProfileSettings::setPassword(QString password)
|
||||
{
|
||||
if (password != m_password) {
|
||||
m_password = password;
|
||||
Q_EMIT passwordChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString ProfileSettings::networkType()
|
||||
{
|
||||
return m_networkType;
|
||||
}
|
||||
|
||||
void ProfileSettings::setNetworkType(QString networkType)
|
||||
{
|
||||
if (networkType != m_networkType) {
|
||||
m_networkType = networkType;
|
||||
Q_EMIT networkTypeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString ProfileSettings::connectionUni()
|
||||
{
|
||||
return m_connectionUni;
|
||||
}
|
||||
|
||||
QString ProfileSettings::networkTypeStr(NetworkManager::GsmSetting::NetworkType networkType)
|
||||
{
|
||||
if (networkType == NetworkManager::GsmSetting::NetworkType::Any) {
|
||||
return QStringLiteral("Any");
|
||||
} else if (networkType == NetworkManager::GsmSetting::NetworkType::GprsEdgeOnly) {
|
||||
return QStringLiteral("Only 2G");
|
||||
} else if (networkType == NetworkManager::GsmSetting::NetworkType::Only3G) {
|
||||
return QStringLiteral("Only 3G");
|
||||
} else if (networkType == NetworkManager::GsmSetting::NetworkType::Only4GLte) {
|
||||
return QStringLiteral("Only 4G");
|
||||
} else if (networkType == NetworkManager::GsmSetting::NetworkType::Prefer2G) {
|
||||
return QStringLiteral("2G");
|
||||
} else if (networkType == NetworkManager::GsmSetting::NetworkType::Prefer3G) {
|
||||
return QStringLiteral("3G/2G");
|
||||
} else if (networkType == NetworkManager::GsmSetting::NetworkType::Prefer4GLte) {
|
||||
return QStringLiteral("4G/3G/2G");
|
||||
}
|
||||
return QStringLiteral("Any");
|
||||
}
|
||||
|
||||
NetworkManager::GsmSetting::NetworkType ProfileSettings::networkTypeFlag(const QString &networkType)
|
||||
{
|
||||
if (networkType == QStringLiteral("Any")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::Any;
|
||||
} else if (networkType == QStringLiteral("Only 2G")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::GprsEdgeOnly;
|
||||
} else if (networkType == QStringLiteral("Only 3G")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::Only3G;
|
||||
} else if (networkType == QStringLiteral("Only 4G")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::Only4GLte;
|
||||
} else if (networkType == QStringLiteral("2G")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::Prefer2G;
|
||||
} else if (networkType == QStringLiteral("3G/2G")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::Prefer3G;
|
||||
} else if (networkType == QStringLiteral("4G/3G/2G")) {
|
||||
return NetworkManager::GsmSetting::NetworkType::Prefer4GLte;
|
||||
}
|
||||
return NetworkManager::GsmSetting::NetworkType::Any;
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021-2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cellularnetworksettings.h"
|
||||
#include "modemdetails.h"
|
||||
#include "sim.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include <NetworkManagerQt/CdmaSetting>
|
||||
#include <NetworkManagerQt/ConnectionSettings>
|
||||
#include <NetworkManagerQt/GsmSetting>
|
||||
#include <NetworkManagerQt/Manager>
|
||||
#include <NetworkManagerQt/ModemDevice>
|
||||
#include <NetworkManagerQt/Settings>
|
||||
|
||||
#include <ModemManagerQt/GenericTypes>
|
||||
#include <ModemManagerQt/Manager>
|
||||
#include <ModemManagerQt/Modem3Gpp>
|
||||
#include <ModemManagerQt/ModemDevice>
|
||||
|
||||
class ProfileSettings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString apn READ apn WRITE setApn NOTIFY apnChanged)
|
||||
Q_PROPERTY(QString user READ user WRITE setUser NOTIFY userChanged)
|
||||
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
|
||||
Q_PROPERTY(QString networkType READ networkType WRITE setNetworkType NOTIFY networkTypeChanged)
|
||||
Q_PROPERTY(QString connectionUni READ connectionUni NOTIFY connectionUniChanged)
|
||||
|
||||
public:
|
||||
ProfileSettings(QObject *parent = nullptr)
|
||||
: QObject{parent}
|
||||
{
|
||||
}
|
||||
ProfileSettings(QObject *parent,
|
||||
QString name,
|
||||
QString apn,
|
||||
QString user,
|
||||
QString password,
|
||||
NetworkManager::GsmSetting::NetworkType networkType,
|
||||
QString connectionUni);
|
||||
ProfileSettings(QObject *parent, NetworkManager::Setting::Ptr settings, NetworkManager::Connection::Ptr connection);
|
||||
|
||||
QString name();
|
||||
QString apn();
|
||||
void setApn(QString apn);
|
||||
QString user();
|
||||
void setUser(QString user);
|
||||
QString password();
|
||||
void setPassword(QString password);
|
||||
QString networkType();
|
||||
void setNetworkType(QString ipType);
|
||||
QString connectionUni();
|
||||
|
||||
// utilities
|
||||
static QString networkTypeStr(NetworkManager::GsmSetting::NetworkType networkType);
|
||||
static NetworkManager::GsmSetting::NetworkType networkTypeFlag(const QString &networkType);
|
||||
|
||||
Q_SIGNALS:
|
||||
void nameChanged();
|
||||
void apnChanged();
|
||||
void userChanged();
|
||||
void passwordChanged();
|
||||
void networkTypeChanged();
|
||||
void connectionUniChanged();
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_apn;
|
||||
QString m_user;
|
||||
QString m_password;
|
||||
QString m_networkType;
|
||||
QString m_connectionUni;
|
||||
};
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "sim.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QDBusReply>
|
||||
|
||||
Sim::Sim(QObject *parent, Modem *modem, ModemManager::Sim::Ptr mmSim, ModemManager::Modem::Ptr mmModem, ModemManager::Modem3gpp::Ptr mmModem3gpp)
|
||||
: QObject{parent}
|
||||
, m_modem{modem}
|
||||
, m_mmSim{mmSim}
|
||||
, m_mmModem{mmModem}
|
||||
, m_mmModem3gpp{mmModem3gpp}
|
||||
{
|
||||
if (m_mmSim) {
|
||||
connect(m_mmSim.data(), &ModemManager::Sim::imsiChanged, this, [this]() -> void {
|
||||
Q_EMIT imsiChanged();
|
||||
});
|
||||
connect(m_mmSim.data(), &ModemManager::Sim::operatorIdentifierChanged, this, [this]() -> void {
|
||||
Q_EMIT operatorIdentifierChanged();
|
||||
});
|
||||
connect(m_mmSim.data(), &ModemManager::Sim::operatorNameChanged, this, [this]() -> void {
|
||||
Q_EMIT operatorNameChanged();
|
||||
});
|
||||
connect(m_mmSim.data(), &ModemManager::Sim::simIdentifierChanged, this, [this]() -> void {
|
||||
Q_EMIT simIdentifierChanged();
|
||||
});
|
||||
}
|
||||
|
||||
if (m_mmModem) {
|
||||
connect(m_mmModem.data(), &ModemManager::Modem::unlockRequiredChanged, this, [this]() -> void {
|
||||
Q_EMIT lockedChanged();
|
||||
Q_EMIT lockedReasonChanged();
|
||||
});
|
||||
}
|
||||
|
||||
if (m_mmModem3gpp) {
|
||||
connect(m_mmModem3gpp.data(), &ModemManager::Modem3gpp::enabledFacilityLocksChanged, this, [this]() -> void {
|
||||
Q_EMIT pinEnabledChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool Sim::enabled()
|
||||
{
|
||||
return uni() != QStringLiteral("/");
|
||||
}
|
||||
|
||||
bool Sim::pinEnabled()
|
||||
{
|
||||
return m_mmModem3gpp && (m_mmModem3gpp->enabledFacilityLocks() & MM_MODEM_3GPP_FACILITY_SIM);
|
||||
}
|
||||
|
||||
int Sim::unlockRetriesLeft()
|
||||
{
|
||||
return m_mmModem && m_mmModem->unlockRetries()[MM_MODEM_LOCK_SIM_PIN];
|
||||
}
|
||||
|
||||
bool Sim::locked()
|
||||
{
|
||||
return m_mmModem && m_mmModem->unlockRequired() == MM_MODEM_LOCK_SIM_PIN;
|
||||
}
|
||||
|
||||
QString Sim::lockedReason()
|
||||
{
|
||||
if (!m_mmModem) {
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (m_mmModem->unlockRequired()) {
|
||||
case MM_MODEM_LOCK_UNKNOWN:
|
||||
return i18n("Lock reason unknown.");
|
||||
case MM_MODEM_LOCK_NONE:
|
||||
return i18n("Modem is unlocked.");
|
||||
case MM_MODEM_LOCK_SIM_PIN:
|
||||
return i18n("SIM requires the PIN code.");
|
||||
case MM_MODEM_LOCK_SIM_PIN2:
|
||||
return i18n("SIM requires the PIN2 code.");
|
||||
case MM_MODEM_LOCK_SIM_PUK:
|
||||
return i18n("SIM requires the PUK code.");
|
||||
case MM_MODEM_LOCK_SIM_PUK2:
|
||||
return i18n("SIM requires the PUK2 code.");
|
||||
case MM_MODEM_LOCK_PH_SP_PIN:
|
||||
return i18n("Modem requires the service provider PIN code.");
|
||||
case MM_MODEM_LOCK_PH_SP_PUK:
|
||||
return i18n("Modem requires the service provider PUK code.");
|
||||
case MM_MODEM_LOCK_PH_NET_PIN:
|
||||
return i18n("Modem requires the network PIN code.");
|
||||
case MM_MODEM_LOCK_PH_NET_PUK:
|
||||
return i18n("Modem requires the network PUK code.");
|
||||
case MM_MODEM_LOCK_PH_SIM_PIN:
|
||||
return i18n("Modem requires the PIN code.");
|
||||
case MM_MODEM_LOCK_PH_CORP_PIN:
|
||||
return i18n("Modem requires the corporate PIN code.");
|
||||
case MM_MODEM_LOCK_PH_CORP_PUK:
|
||||
return i18n("Modem requires the corporate PUK code.");
|
||||
case MM_MODEM_LOCK_PH_FSIM_PIN:
|
||||
return i18n("Modem requires the PH-FSIM PIN code.");
|
||||
case MM_MODEM_LOCK_PH_FSIM_PUK:
|
||||
return i18n("Modem requires the PH-FSIM PUK code.");
|
||||
case MM_MODEM_LOCK_PH_NETSUB_PIN:
|
||||
return i18n("Modem requires the network subset PIN code.");
|
||||
case MM_MODEM_LOCK_PH_NETSUB_PUK:
|
||||
return i18n("Modem requires the network subset PUK code.");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString Sim::imsi()
|
||||
{
|
||||
return m_mmSim ? m_mmSim->imsi() : QString{};
|
||||
}
|
||||
|
||||
QString Sim::eid()
|
||||
{
|
||||
return {}; // TODO add in mm-qt
|
||||
}
|
||||
|
||||
QString Sim::operatorIdentifier()
|
||||
{
|
||||
return m_mmSim ? m_mmSim->operatorIdentifier() : QString{};
|
||||
}
|
||||
|
||||
QString Sim::operatorName()
|
||||
{
|
||||
return m_mmSim ? m_mmSim->operatorName() : QString{};
|
||||
}
|
||||
|
||||
QString Sim::simIdentifier()
|
||||
{
|
||||
return m_mmSim ? m_mmSim->simIdentifier() : QString{};
|
||||
}
|
||||
|
||||
QStringList Sim::emergencyNumbers()
|
||||
{
|
||||
return {}; // TODO add in mm-qt
|
||||
}
|
||||
|
||||
QString Sim::uni()
|
||||
{
|
||||
return m_mmSim ? m_mmSim->uni() : QString{};
|
||||
}
|
||||
|
||||
QString Sim::displayId()
|
||||
{
|
||||
// in the form /org/freedesktop/ModemManager1/Sim/0
|
||||
QStringList uniSplit = uni().split(QStringLiteral("/"));
|
||||
return (uniSplit.count() == 0 || uni() == "/") ? i18n("(empty)") : QString(uniSplit[uniSplit.size() - 1]);
|
||||
}
|
||||
|
||||
Modem *Sim::modem()
|
||||
{
|
||||
return m_modem;
|
||||
}
|
||||
|
||||
QCoro::Task<void> Sim::togglePinEnabled(const QString &pin)
|
||||
{
|
||||
bool isPinEnabled = pinEnabled();
|
||||
QDBusReply<void> reply = co_await m_mmSim->enablePin(pin, !isPinEnabled);
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error toggling SIM lock to") << isPinEnabled << QStringLiteral(":") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error toggling SIM lock: %1", reply.error().message()));
|
||||
}
|
||||
}
|
||||
|
||||
QCoro::Task<void> Sim::changePin(const QString &oldPin, const QString &newPin)
|
||||
{
|
||||
QDBusReply<void> reply = co_await m_mmSim->changePin(oldPin, newPin);
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error changing the PIN:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error changing the PIN: %1", reply.error().message()));
|
||||
}
|
||||
}
|
||||
|
||||
QCoro::Task<void> Sim::sendPin(const QString &pin)
|
||||
{
|
||||
if (!m_mmModem || !m_mmSim || m_mmModem->unlockRequired() == MM_MODEM_LOCK_NONE) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
QDBusReply<void> reply = co_await m_mmSim->sendPin(pin);
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error sending the PIN:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error sending the PIN: %1", reply.error().message()));
|
||||
}
|
||||
}
|
||||
|
||||
QCoro::Task<void> Sim::sendPuk(const QString &pin, const QString &puk)
|
||||
{
|
||||
if (!m_mmModem || !m_mmSim || m_mmModem->unlockRequired() != MM_MODEM_LOCK_NONE) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
QDBusReply<void> reply = co_await m_mmSim->sendPuk(pin, puk);
|
||||
if (!reply.isValid()) {
|
||||
qWarning() << QStringLiteral("Error sending the PUK:") << reply.error().message();
|
||||
CellularNetworkSettings::instance()->addMessage(InlineMessage::Error, i18n("Error sending the PUK: %1", reply.error().message()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "modem.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include <NetworkManagerQt/CdmaSetting>
|
||||
#include <NetworkManagerQt/ConnectionSettings>
|
||||
#include <NetworkManagerQt/GsmSetting>
|
||||
#include <NetworkManagerQt/Manager>
|
||||
#include <NetworkManagerQt/ModemDevice>
|
||||
#include <NetworkManagerQt/Settings>
|
||||
|
||||
#include <ModemManagerQt/GenericTypes>
|
||||
#include <ModemManagerQt/Manager>
|
||||
#include <ModemManagerQt/Modem3Gpp>
|
||||
#include <ModemManagerQt/ModemDevice>
|
||||
|
||||
#include <QCoroDBusPendingReply>
|
||||
|
||||
class Modem;
|
||||
|
||||
class Sim : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(bool pinEnabled READ pinEnabled NOTIFY pinEnabledChanged) // if there is a PIN set on the SIM
|
||||
Q_PROPERTY(int unlockRetriesLeft READ unlockRetriesLeft NOTIFY unlockRetriesLeftChanged)
|
||||
Q_PROPERTY(bool locked READ locked NOTIFY lockedChanged) // if the SIM is currently locked (requires entering PIN)
|
||||
Q_PROPERTY(QString lockedReason READ lockedReason NOTIFY lockedReasonChanged)
|
||||
Q_PROPERTY(QString imsi READ imsi NOTIFY imsiChanged)
|
||||
Q_PROPERTY(QString eid READ eid NOTIFY eidChanged) // TODO (not in mm-qt)
|
||||
Q_PROPERTY(QString operatorIdentifier READ operatorIdentifier NOTIFY operatorIdentifierChanged)
|
||||
Q_PROPERTY(QString operatorName READ operatorName NOTIFY operatorNameChanged)
|
||||
Q_PROPERTY(QString simIdentifier READ simIdentifier NOTIFY simIdentifierChanged)
|
||||
Q_PROPERTY(QStringList emergencyNumbers READ emergencyNumbers NOTIFY emergencyNumbersChanged)
|
||||
Q_PROPERTY(QString uni READ uni NOTIFY uniChanged)
|
||||
Q_PROPERTY(QString displayId READ displayId NOTIFY displayIdChanged)
|
||||
Q_PROPERTY(Modem *modem READ modem NOTIFY modemChanged)
|
||||
|
||||
public:
|
||||
Sim(QObject *parent = nullptr,
|
||||
Modem *modem = nullptr,
|
||||
ModemManager::Sim::Ptr mmSim = ModemManager::Sim::Ptr{nullptr},
|
||||
ModemManager::Modem::Ptr mmModem = ModemManager::Modem::Ptr{nullptr},
|
||||
ModemManager::Modem3gpp::Ptr mmModem3gpp = ModemManager::Modem3gpp::Ptr{nullptr});
|
||||
|
||||
bool enabled();
|
||||
bool pinEnabled();
|
||||
int unlockRetriesLeft();
|
||||
bool locked();
|
||||
QString lockedReason();
|
||||
QString imsi();
|
||||
QString eid(); // TODO add in mm-qt
|
||||
QString operatorIdentifier();
|
||||
QString operatorName();
|
||||
QString simIdentifier();
|
||||
QStringList emergencyNumbers(); // TODO add in mm-qt
|
||||
QString uni();
|
||||
QString displayId();
|
||||
Modem *modem();
|
||||
|
||||
Q_INVOKABLE QCoro::Task<void> togglePinEnabled(const QString &pin);
|
||||
Q_INVOKABLE QCoro::Task<void> changePin(const QString &oldPin, const QString &newPin);
|
||||
Q_INVOKABLE QCoro::Task<void> sendPin(const QString &pin);
|
||||
Q_INVOKABLE QCoro::Task<void> sendPuk(const QString &pin, const QString &puk);
|
||||
|
||||
Q_SIGNALS:
|
||||
void enabledChanged();
|
||||
void pinEnabledChanged();
|
||||
void unlockRetriesLeftChanged();
|
||||
void lockedChanged();
|
||||
void lockedReasonChanged();
|
||||
void imsiChanged();
|
||||
void eidChanged();
|
||||
void operatorIdentifierChanged();
|
||||
void operatorNameChanged();
|
||||
void simIdentifierChanged();
|
||||
void emergencyNumbersChanged();
|
||||
void uniChanged();
|
||||
void displayIdChanged();
|
||||
void modemChanged();
|
||||
|
||||
private:
|
||||
Modem *m_modem;
|
||||
ModemManager::Sim::Ptr m_mmSim;
|
||||
ModemManager::Modem::Ptr m_mmModem;
|
||||
ModemManager::Modem3gpp::Ptr m_mmModem3gpp; // this may be a nullptr if no sim is inserted
|
||||
};
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Controls
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kcmutils
|
||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
||||
|
||||
import cellularnetworkkcm 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: root
|
||||
title: i18n("Available Networks")
|
||||
|
||||
property Modem modem
|
||||
property Sim sim
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
header: ColumnLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 0
|
||||
|
||||
MessagesList {
|
||||
visible: count != 0
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.largeSpacing
|
||||
model: kcm.messages
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
anchors.centerIn: parent
|
||||
visible: !modem.details.isScanningNetworks && listView.count == 0
|
||||
icon.name: "network-mobile-100"
|
||||
text: i18n("Current operator: %1", modem.details.operatorName ? modem.details.operatorName : i18n("none"))
|
||||
helpfulAction: Kirigami.Action {
|
||||
icon.name: "view-refresh"
|
||||
text: i18n("Scan For Networks")
|
||||
enabled: !modem.details.isScanningNetworks
|
||||
onTriggered: modem.details.scanNetworks()
|
||||
}
|
||||
}
|
||||
|
||||
Controls.BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
visible: modem.details.isScanningNetworks
|
||||
implicitWidth: Kirigami.Units.iconSizes.large
|
||||
implicitHeight: implicitWidth
|
||||
}
|
||||
|
||||
model: modem.details.networks
|
||||
|
||||
delegate: FormCard.FormRadioDelegate {
|
||||
width: listView.width
|
||||
checked: modelData.isCurrentlyUsed
|
||||
|
||||
onClicked: {
|
||||
if (!modelData.isCurrentlyUsed) {
|
||||
modelData.registerToNetwork();
|
||||
modem.details.scanNetworks();
|
||||
}
|
||||
}
|
||||
|
||||
text: modelData.operatorLong + " | " + modelData.operatorShort + "(" + modelData.operatorCode + ")"
|
||||
description: modelData.accessTechnology
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2020-2022 Devin Lin <espidev@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
||||
|
||||
import cellularnetworkkcm 1.0
|
||||
|
||||
FormCard.FormCardPage {
|
||||
id: editProfile
|
||||
title: profile != null ? i18n("Edit APN") : i18n("New APN")
|
||||
|
||||
topPadding: Kirigami.Units.gridUnit
|
||||
bottomPadding: Kirigami.Units.gridUnit
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
|
||||
property Modem modem
|
||||
property ProfileSettings profile
|
||||
|
||||
FormCard.FormCard {
|
||||
Layout.topMargin: Kirigami.Units.gridUnit
|
||||
|
||||
FormCard.FormTextFieldDelegate {
|
||||
id: profileName
|
||||
label: i18n("Name")
|
||||
text: profile != null ? profile.name : ""
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: profileName; below: profileApn }
|
||||
|
||||
FormCard.FormTextFieldDelegate {
|
||||
id: profileApn
|
||||
label: i18n("APN")
|
||||
text: profile != null ? profile.apn : ""
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: profileApn; below: profileUsername }
|
||||
|
||||
FormCard.FormTextFieldDelegate {
|
||||
id: profileUsername
|
||||
label: i18n("Username")
|
||||
text: profile != null ? profile.user : ""
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: profileUsername; below: profilePassword }
|
||||
|
||||
FormCard.FormTextFieldDelegate {
|
||||
id: profilePassword
|
||||
label: i18n("Password")
|
||||
text: profile != null ? profile.password : ""
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: profilePassword; below: profileNetworkType }
|
||||
|
||||
FormCard.FormComboBoxDelegate {
|
||||
id: profileNetworkType
|
||||
text: i18n("Network type")
|
||||
model: [i18n("4G/3G/2G"), i18n("3G/2G"), i18n("2G"), i18n("Only 4G"), i18n("Only 3G"), i18n("Only 2G"), i18n("Any")]
|
||||
Component.onCompleted: {
|
||||
if (profile != null) {
|
||||
currentIndex = indexOfValue(profile.networkType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: profileNetworkType; below: profileSave }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: profileSave
|
||||
text: i18n("Save profile")
|
||||
icon.name: "document-save"
|
||||
onClicked: {
|
||||
if (profile == null) { // create new profile
|
||||
modem.addProfile(profileName.text, profileApn.text, profileUsername.text, profilePassword.text, profileNetworkType.currentText);
|
||||
} else { // edit existing profile
|
||||
modem.updateProfile(profile.connectionUni, profileName.text, profileApn.text, profileUsername.text, profilePassword.text, profileNetworkType.currentText);
|
||||
}
|
||||
kcm.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
import cellularnetworkkcm 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var model
|
||||
property alias count: repeater.count
|
||||
|
||||
spacing: 0
|
||||
visible: count > 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: root.model
|
||||
|
||||
delegate: Kirigami.InlineMessage {
|
||||
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||
Layout.fillWidth: true
|
||||
visible: true
|
||||
text: modelData.message
|
||||
type: {
|
||||
switch (modelData.type) {
|
||||
case InlineMessage.Information: return Kirigami.MessageType.Information;
|
||||
case InlineMessage.Positive: return Kirigami.MessageType.Positive;
|
||||
case InlineMessage.Warning: return Kirigami.MessageType.Warning;
|
||||
case InlineMessage.Error: return Kirigami.MessageType.Error;
|
||||
}
|
||||
return Kirigami.MessageType.Error;
|
||||
}
|
||||
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
icon.name: "dialog-close"
|
||||
onTriggered: kcm.removeMessage(model.index)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,279 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021-2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Controls
|
||||
|
||||
import org.kde.kirigami 2 as Kirigami
|
||||
import org.kde.kcmutils
|
||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
||||
|
||||
import cellularnetworkkcm
|
||||
|
||||
FormCard.FormCardPage {
|
||||
id: modemPage
|
||||
|
||||
property Modem modem
|
||||
property bool showExtra: false
|
||||
|
||||
title: i18n("Modem %1", modem.displayId)
|
||||
|
||||
MessagesList {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.smallSpacing
|
||||
visible: count != 0
|
||||
model: kcm.messages
|
||||
}
|
||||
|
||||
FormCard.FormHeader {
|
||||
title: i18n("Modem Control")
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
FormCard.FormButtonDelegate {
|
||||
id: modemRestartButton
|
||||
text: i18n("Force Modem Restart")
|
||||
onClicked: modem.reset()
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormHeader {
|
||||
title: i18n("Modem Details")
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
FormCard.AbstractFormDelegate {
|
||||
id: accessTechnologiesText
|
||||
|
||||
background: null
|
||||
contentItem: ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Access Technologies")
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Repeater {
|
||||
model: modem.details.accessTechnologies
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: modelData
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: imeiText
|
||||
text: i18n("IMEI")
|
||||
description: modem.details.equipmentIdentifier
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: enabledText
|
||||
text: i18n("Enabled")
|
||||
description: modem.details.isEnabled
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: manufacturerText
|
||||
text: i18n("Manufacturer")
|
||||
description: modem.details.manufacturer
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: modelText
|
||||
text: i18n("Model")
|
||||
description: modem.details.model
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.AbstractFormDelegate {
|
||||
id: ownedNumbersText
|
||||
|
||||
background: null
|
||||
contentItem: ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Owned Numbers:")
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: modem.details.ownNumbers
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: modelData
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: revisionText
|
||||
text: i18n("Revision")
|
||||
description: modem.details.revision
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: signalQualityText
|
||||
text: i18n("Signal Quality")
|
||||
description: modem.details.signalQuality
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: stateText
|
||||
text: i18n("State")
|
||||
description: modem.details.state
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: failureReasonText
|
||||
text: i18n("Failure Reason")
|
||||
description: modem.details.stateFailedReason
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: registrationStateText
|
||||
text: i18n("Registration State")
|
||||
description: modem.details.registrationState
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: roamingText
|
||||
text: i18n("Roaming")
|
||||
description: modem.isRoaming ? i18n("Yes") : i18n("No")
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: firmwareVersionText
|
||||
text: i18n("Firmware Version")
|
||||
description: modem.details.firmwareVersion
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: interfaceNameText
|
||||
text: i18n("Interface Name")
|
||||
description: modem.details.interfaceName
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: meteredText
|
||||
text: i18n("Metered")
|
||||
description: modem.details.metered
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: activeNMConnectionText
|
||||
text: i18n("Active NetworkManager Connection")
|
||||
description: modem.activeConnectionUni
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: deviceText
|
||||
text: i18n("Device")
|
||||
description: modem.details.device
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: deviceIdText
|
||||
text: i18n("Device ID")
|
||||
description: modem.details.deviceIdentifier
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.AbstractFormDelegate {
|
||||
id: driversText
|
||||
|
||||
background: null
|
||||
contentItem: ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Drivers:")
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Repeater {
|
||||
model: modem.details.drivers
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: modelData
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: pluginText
|
||||
text: i18n("Plugin")
|
||||
description: modem.details.plugin
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: powerStateText
|
||||
text: i18n("Power State")
|
||||
description: modem.details.powerState
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: simPathText
|
||||
text: i18n("SIM Path")
|
||||
description: modem.details.simPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Controls
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import cellularnetworkkcm
|
||||
|
||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: root
|
||||
topPadding: Kirigami.Units.gridUnit
|
||||
bottomPadding: Kirigami.Units.gridUnit
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
|
||||
property Modem modem
|
||||
property bool editMode: false
|
||||
|
||||
title: i18n("APNs")
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
text: i18n("Edit")
|
||||
icon.name: 'entry-edit'
|
||||
checkable: true
|
||||
onCheckedChanged: root.editMode = checked
|
||||
}
|
||||
]
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
MessagesList {
|
||||
id: messagesList
|
||||
visible: count != 0
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.largeSpacing
|
||||
model: kcm.messages
|
||||
}
|
||||
|
||||
Kirigami.InlineMessage {
|
||||
id: cannotFindWarning
|
||||
Layout.margins: visible ? Kirigami.Units.largeSpacing : 0
|
||||
Layout.topMargin: visible && !messagesList.visible ? Kirigami.Units.largeSpacing : 0
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: false
|
||||
type: Kirigami.MessageType.Warning
|
||||
showCloseButton: true
|
||||
text: i18n("Unable to autodetect connection settings for your carrier. Please find your carrier's APN settings by either contacting support or searching online.")
|
||||
|
||||
Connections {
|
||||
target: modem
|
||||
function onCouldNotAutodetectSettings() {
|
||||
cannotFindWarning.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormHeader {
|
||||
title: i18n("APN List")
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
Repeater {
|
||||
id: profilesRepeater
|
||||
model: modem.profiles
|
||||
|
||||
delegate: FormCard.FormRadioDelegate {
|
||||
text: modelData.name
|
||||
description: modelData.apn
|
||||
|
||||
checked: modem.activeConnectionUni == modelData.connectionUni
|
||||
onClicked: {
|
||||
modem.activateProfile(modelData.connectionUni);
|
||||
|
||||
// reapply binding
|
||||
checked = Qt.binding(() => { return modem.activeConnectionUni == modelData.connectionUni });
|
||||
}
|
||||
|
||||
trailing: RowLayout {
|
||||
Controls.ToolButton {
|
||||
visible: root.editMode
|
||||
icon.name: "entry-edit"
|
||||
text: i18n("Edit")
|
||||
display: Controls.ToolButton.IconOnly
|
||||
onClicked: {
|
||||
kcm.push("EditProfilePage.qml", { "profile": modelData, "modem": modem });
|
||||
}
|
||||
}
|
||||
|
||||
Controls.ToolButton {
|
||||
visible: root.editMode
|
||||
icon.name: "delete"
|
||||
text: i18n("Delete")
|
||||
display: Controls.ToolButton.IconOnly
|
||||
onClicked: modem.removeProfile(modelData.connectionUni)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
text: i18n("Add APN")
|
||||
icon.name: 'list-add'
|
||||
onClicked: {
|
||||
kcm.push("EditProfilePage.qml", { "profile": null, "modem": modem });
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
text: i18n("Automatically detect APN")
|
||||
icon.name: 'list-add'
|
||||
onClicked: {
|
||||
modem.addDetectedProfileSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.kcmutils
|
||||
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||
|
||||
import cellularnetworkkcm 1.0
|
||||
|
||||
FormCard.FormCardPage {
|
||||
id: root
|
||||
|
||||
property Sim sim
|
||||
|
||||
title: i18n("SIM Lock")
|
||||
|
||||
MessagesList {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.gridUnit
|
||||
model: kcm.messages
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: unlockSimPlaceholder
|
||||
visible: sim.locked
|
||||
|
||||
// HACK: prevent infinite binding loop?
|
||||
Component.onCompleted: unlockSimPlaceholder.Layout.preferredHeight = root.height
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
Layout.margins: Kirigami.Units.gridUnit * 2
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: i18n("SIM is locked")
|
||||
explanation: i18n("In order to use this SIM, you must first unlock it.")
|
||||
icon.name: "lock"
|
||||
helpfulAction: Kirigami.Action {
|
||||
icon.name: "unlock"
|
||||
text: "Unlock SIM"
|
||||
onTriggered: unlockPinDialog.open() // TODO replace custom unlock pin dialog with just opening the system unlock PIN dialog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: notLockedSimPlaceholder
|
||||
visible: !sim.pinEnabled && !unlockSimPlaceholder.visible
|
||||
Layout.fillWidth: true
|
||||
|
||||
// HACK: prevent infinite binding loop?
|
||||
Component.onCompleted: notLockedSimPlaceholder.Layout.preferredHeight = root.height
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
Layout.margins: Kirigami.Units.gridUnit * 2
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: i18n("SIM is not locked")
|
||||
explanation: i18n("You can lock your SIM to require a set PIN code for phone calls and mobile data.")
|
||||
icon.name: "unlock"
|
||||
helpfulAction: Kirigami.Action {
|
||||
icon.name: "lock"
|
||||
text: i18n("Lock SIM")
|
||||
onTriggered: createPinDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
visible: !notLockedSimPlaceholder.visible && !unlockSimPlaceholder.visible
|
||||
Layout.fillWidth: true
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: disableSimLockButton
|
||||
text: i18n("Disable SIM Lock")
|
||||
description: i18n("Disable the SIM lock feature and remove the passcode on the SIM.")
|
||||
onClicked: removePinDialog.open();
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
opacity: (!disableSimLockButton.controlHovered && !changePinButton.controlHovered) ? 0.5 : 0
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: changePinButton
|
||||
text: i18n("Change PIN")
|
||||
description: i18n("Change the passcode set on the SIM.")
|
||||
onClicked: changePinDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
data: [
|
||||
RegularExpressionValidator {
|
||||
id: pinValidator
|
||||
regularExpression: /[0-9]+/
|
||||
},
|
||||
// dialogs
|
||||
|
||||
Kirigami.Dialog {
|
||||
id: unlockPinDialog
|
||||
title: i18n("Unlock SIM")
|
||||
standardButtons: Controls.Dialog.Ok | Controls.Dialog.Cancel
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
onAccepted: sim.sendPin(unlockPinCurPin.text)
|
||||
|
||||
ColumnLayout {
|
||||
Controls.Label {
|
||||
text: i18n("Attempts left: %1", sim.unlockRetriesLeft)
|
||||
}
|
||||
Kirigami.PasswordField {
|
||||
id: unlockPinCurPin
|
||||
placeholderText: i18n("Enter PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Kirigami.Dialog {
|
||||
id: changePinDialog
|
||||
title: i18n("Change SIM PIN")
|
||||
standardButtons: isValid ? Controls.Dialog.Ok | Controls.Dialog.Cancel : Controls.Dialog.Cancel
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
property bool isValid: changePinNewPin.text == changePinConfirmPin.text &&
|
||||
changePinNewPin.text.length >= 4 && changePinNewPin.text.length <= 8 // SIM PINs are between 4-8 digits
|
||||
|
||||
onAccepted: {
|
||||
if (isValid) {
|
||||
sim.changePin(changePinCurPin.text, changePinNewPin.text);
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Kirigami.InlineMessage {
|
||||
id: changePinMatch
|
||||
Layout.fillWidth: true
|
||||
visible: changePinNewPin.text != changePinConfirmPin.text
|
||||
text: i18n("PINs don't match!")
|
||||
type: Kirigami.MessageType.Error
|
||||
}
|
||||
Kirigami.InlineMessage {
|
||||
Layout.fillWidth: true
|
||||
visible: !changePinMatch.visible && changePinNewPin.text.length != 0 && (changePinNewPin.text.length < 4 || changePinNewPin.text.length > 8)
|
||||
text: i18n("PINs must be between 4 and 8 digits!")
|
||||
type: Kirigami.MessageType.Error
|
||||
}
|
||||
Kirigami.PasswordField {
|
||||
id: changePinCurPin
|
||||
placeholderText: i18n("Current PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
Kirigami.PasswordField {
|
||||
id: changePinNewPin
|
||||
placeholderText: i18n("New PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
Kirigami.PasswordField {
|
||||
id: changePinConfirmPin
|
||||
placeholderText: i18n("Confirm PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Kirigami.Dialog {
|
||||
id: removePinDialog
|
||||
title: i18n("Remove SIM PIN")
|
||||
standardButtons: Controls.Dialog.Ok | Controls.Dialog.Cancel
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
onAccepted: sim.togglePinEnabled(removePinCurPin.text);
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.PasswordField {
|
||||
id: removePinCurPin
|
||||
placeholderText: i18n("Current PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Kirigami.Dialog {
|
||||
id: createPinDialog
|
||||
title: i18n("Add SIM PIN")
|
||||
standardButtons: isValid ? Controls.Dialog.Ok | Controls.Dialog.Cancel : Controls.Dialog.Cancel
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
property bool isValid: createPinNewPin.text == createPinConfirmPin.text &&
|
||||
createPinNewPin.text.length >= 4 && createPinNewPin.text.length <= 8 // SIM PINs are between 4-8 digits
|
||||
|
||||
onAccepted: {
|
||||
if (isValid) {
|
||||
sim.togglePinEnabled(createPinNewPin.text);
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Kirigami.InlineMessage {
|
||||
id: createPinMatch
|
||||
Layout.fillWidth: true
|
||||
visible: createPinNewPin.text != createPinConfirmPin.text
|
||||
text: i18n("PINs don't match!")
|
||||
type: Kirigami.MessageType.Error
|
||||
}
|
||||
Kirigami.InlineMessage {
|
||||
Layout.fillWidth: true
|
||||
visible: !createPinMatch.visible && createPinNewPin.text.length != 0 && (createPinNewPin.text.length < 4 || createPinNewPin.text.length > 8)
|
||||
text: i18n("PINs must be between 4 and 8 digits!")
|
||||
type: Kirigami.MessageType.Error
|
||||
}
|
||||
Kirigami.PasswordField {
|
||||
id: createPinNewPin
|
||||
placeholderText: i18n("New PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
Kirigami.PasswordField {
|
||||
id: createPinConfirmPin
|
||||
placeholderText: i18n("Confirm PIN")
|
||||
validator: pinValidator
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Controls
|
||||
|
||||
import org.kde.plasma.networkmanagement as PlasmaNM
|
||||
import org.kde.kcmutils
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
||||
import org.kde.kirigamiaddons.components 1 as Components
|
||||
|
||||
import cellularnetworkkcm 1.0
|
||||
|
||||
FormCard.FormCardPage {
|
||||
id: simPage
|
||||
|
||||
property Sim sim: null
|
||||
|
||||
property string displayId: sim ? sim.displayId : ""
|
||||
property bool simEnabled: sim ? sim.enabled : false
|
||||
property bool isRoaming: sim ? (sim.modem ? sim.modem.isRoaming : false) : false
|
||||
|
||||
property bool simLocked: sim ? sim.locked : false
|
||||
property string simImsi: sim ? sim.imsi : ""
|
||||
property string simEid: sim ? sim.eid : ""
|
||||
property string operatorCode: sim ? (sim.modem ? sim.modem.details.operatorCode : "") : ""
|
||||
property string operatorName: sim ? (sim.modem ? sim.modem.details.operatorName : "") : ""
|
||||
property string simOperatorIdentifier: sim ? sim.operatorIdentifier : ""
|
||||
property string simOperatorName: sim ? sim.operatorName : ""
|
||||
property string simIdentifier: sim ? sim.simIdentifier : ""
|
||||
property var simEmergencyNumbers: sim ? sim.emergencyNumbers : []
|
||||
|
||||
title: i18n("SIM") + " " + displayId
|
||||
|
||||
data: PlasmaNM.EnabledConnections {
|
||||
id: enabledConnections
|
||||
}
|
||||
|
||||
header: Components.Banner {
|
||||
width: parent.width
|
||||
visible: !simEnabled
|
||||
type: Kirigami.MessageType.Error
|
||||
text: i18n("This SIM slot is empty, a SIM card needs to be inserted in order for it to be used.")
|
||||
}
|
||||
|
||||
MessagesList {
|
||||
id: messagesList
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.gridUnit
|
||||
model: kcm.messages
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
Layout.topMargin: Kirigami.Units.gridUnit
|
||||
|
||||
FormCard.FormSwitchDelegate {
|
||||
id: dataRoamingCheckBox
|
||||
text: i18n("Data Roaming")
|
||||
description: i18n("Allow your device to use networks other than your carrier.")
|
||||
enabled: simEnabled
|
||||
checked: isRoaming
|
||||
onCheckedChanged: sim.modem.isRoaming = checked
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: dataRoamingCheckBox; below: apnButton }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: apnButton
|
||||
icon.name: "globe"
|
||||
text: i18n("Modify APNs")
|
||||
description: i18n("Configure access point names for your carrier.")
|
||||
enabled: simEnabled
|
||||
onClicked: kcm.push("ProfileList.qml", { "modem": sim.modem });
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: apnButton; below: networksButton }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: networksButton
|
||||
icon.name: "network-mobile-available"
|
||||
text: i18n("Networks")
|
||||
description: i18n("Select a network operator.")
|
||||
enabled: simEnabled
|
||||
onClicked: kcm.push("AvailableNetworks.qml", { "modem": sim.modem, "sim": sim });
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: networksButton; below: simLockButton }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: simLockButton
|
||||
icon.name: "unlock"
|
||||
text: i18n("SIM Lock")
|
||||
description: i18n("Modify SIM lock settings.")
|
||||
enabled: simEnabled
|
||||
onClicked: kcm.push("SimLockPage.qml", { "sim": sim });
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: simLockButton; below: modemDetailsButton }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: modemDetailsButton
|
||||
icon.name: "network-modem"
|
||||
text: i18n("Modem Details")
|
||||
description: i18n("View the details of the modem this SIM is connected to.")
|
||||
onClicked: kcm.push("ModemPage.qml", { "modem": sim.modem })
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormHeader {
|
||||
title: i18n("SIM Details")
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
FormCard.FormTextDelegate {
|
||||
id: lockedText
|
||||
text: i18n("Locked")
|
||||
description: simLocked ? i18n("Yes") : i18n("No")
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: imsiText
|
||||
text: i18n("IMSI")
|
||||
description: simImsi
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: eidText
|
||||
text: i18n("EID")
|
||||
description: simEid
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: opCodeModemText
|
||||
text: i18n("Operator Code (modem)")
|
||||
description: operatorCode
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: opNameModemText
|
||||
text: i18n("Operator Name (modem)")
|
||||
description: operatorName
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: opCodeSimText
|
||||
text: i18n("Operator Code (provided by SIM)")
|
||||
description: simOperatorIdentifier
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: opNameSimText
|
||||
text: i18n("Operator Name (provided by SIM)")
|
||||
description: simOperatorName
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.FormTextDelegate {
|
||||
id: simIdText
|
||||
text: i18n("SIM ID")
|
||||
description: simIdentifier
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator {}
|
||||
|
||||
FormCard.AbstractFormDelegate {
|
||||
id: emergencyNumbersText
|
||||
|
||||
background: null
|
||||
contentItem: ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Emergency Numbers")
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: simEmergencyNumbers
|
||||
|
||||
Controls.Label {
|
||||
Layout.fillWidth: true
|
||||
text: modelData
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
font: Kirigami.Theme.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
||||
// SPDX-FileCopyrightText: 2020 Dimitris Kardarakos <dimkard@posteo.net>
|
||||
// SPDX-FileCopyrightText: 2021-2022 Devin Lin <espidev@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2023 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
|
||||
import org.kde.plasma.networkmanagement as PlasmaNM
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kcmutils as KCM
|
||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
||||
|
||||
import cellularnetworkkcm 1.0
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: root
|
||||
|
||||
objectName: "mobileDataMain"
|
||||
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
PlasmaNM.Handler {
|
||||
id: nmHandler
|
||||
}
|
||||
|
||||
PlasmaNM.AvailableDevices {
|
||||
id: availableDevices
|
||||
}
|
||||
|
||||
PlasmaNM.EnabledConnections {
|
||||
id: enabledConnections
|
||||
}
|
||||
|
||||
SimPage {
|
||||
id: simPage
|
||||
visible: false
|
||||
}
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
id: noModem
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Kirigami.Units.gridUnit * 4
|
||||
|
||||
visible: !enabledConnections.wwanHwEnabled || !availableDevices.modemDeviceAvailable || !kcm.modemFound
|
||||
icon.name: "auth-sim-missing"
|
||||
text: i18n("Modem not available")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
width: root.width
|
||||
visible: !noModem.visible
|
||||
|
||||
MessagesList {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.largeSpacing
|
||||
model: kcm.messages
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
Layout.topMargin: Kirigami.Units.gridUnit
|
||||
|
||||
FormCard.FormSwitchDelegate {
|
||||
id: mobileDataSwitch
|
||||
text: i18n("Mobile data")
|
||||
description: {
|
||||
if (!kcm.modemFound) {
|
||||
return "";
|
||||
} else if (!kcm.selectedModem.hasSim) {
|
||||
return i18n("No SIM is inserted.")
|
||||
} if (!kcm.selectedModem.mobileDataSupported) {
|
||||
return i18n("Mobile data is not available with this modem.")
|
||||
} else if (kcm.selectedModem.needsAPNAdded) {
|
||||
return i18n("An APN needs to be configured to have mobile data.");
|
||||
} else {
|
||||
return i18n("Whether mobile data is enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
property bool manuallySet: false
|
||||
property bool shouldBeChecked: kcm.selectedModem && kcm.selectedModem.mobileDataEnabled
|
||||
onShouldBeCheckedChanged: {
|
||||
checked = shouldBeChecked;
|
||||
}
|
||||
|
||||
enabled: kcm.selectedModem && kcm.selectedModem.mobileDataSupported && !kcm.selectedModem.needsAPNAdded
|
||||
checked: shouldBeChecked
|
||||
|
||||
onCheckedChanged: {
|
||||
// prevent binding loops
|
||||
if (manuallySet) {
|
||||
manuallySet = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (kcm.selectedModem.mobileDataEnabled != checked) {
|
||||
manuallySet = true;
|
||||
kcm.selectedModem.mobileDataEnabled = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: mobileDataSwitch; below: dataUsageButton }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: dataUsageButton
|
||||
text: i18n("Data Usage")
|
||||
description: i18n("View data usage.")
|
||||
icon.name: "office-chart-bar"
|
||||
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormHeader {
|
||||
title: i18np("SIM", "SIMs", kcm.sims.count)
|
||||
visible: repeater.count > 0
|
||||
}
|
||||
|
||||
FormCard.FormCard {
|
||||
visible: repeater.count > 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: kcm.sims
|
||||
|
||||
delegate: ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
FormCard.FormDelegateSeparator {
|
||||
visible: model.index !== 0
|
||||
opacity: (!(model.index && repeater.itemAt(model.index - 1).controlHovered) && !simDelegate.controlHovered) ? 0.5 : 0
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: simDelegate
|
||||
text: i18n("SIM %1", modelData.displayId)
|
||||
description: i18n("View SIM %1 details.", modelData.displayId)
|
||||
icon.name: "auth-sim-symbolic"
|
||||
onClicked: {
|
||||
simPage.sim = modelData;
|
||||
simPage.visible = true;
|
||||
kcm.push(simPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue